Merge from Chromium at DEPS revision 257591

This commit was generated by merge_to_master.py.

Change-Id: I834f3ca85c1ef7ec2c1061847a3d92aa461da043
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();