Merge from Chromium at DEPS revision 232015

This commit was generated by merge_to_master.py.

Change-Id: I9f9356b47400040c33b19d1ff3837161628089e0
diff --git a/Source/core/dom/ActiveDOMObject.cpp b/Source/core/dom/ActiveDOMObject.cpp
index 15ac7be..be52d0f 100644
--- a/Source/core/dom/ActiveDOMObject.cpp
+++ b/Source/core/dom/ActiveDOMObject.cpp
@@ -63,7 +63,7 @@
     m_suspendIfNeededCalled = true;
 #endif
     if (ExecutionContext* context = executionContext())
-        executionContext()->suspendActiveDOMObjectIfNeeded(this);
+        context->suspendActiveDOMObjectIfNeeded(this);
 }
 
 bool ActiveDOMObject::hasPendingActivity() const
diff --git a/Source/core/dom/Attr.cpp b/Source/core/dom/Attr.cpp
index e962c77..6b0e04e 100644
--- a/Source/core/dom/Attr.cpp
+++ b/Source/core/dom/Attr.cpp
@@ -85,7 +85,7 @@
         // This does everything appendChild() would do in this situation (assuming m_ignoreChildrenChanged was set),
         // but much more efficiently.
         textNode->setParentOrShadowHostNode(this);
-        treeScope().adoptIfNeeded(textNode.get());
+        treeScope().adoptIfNeeded(*textNode);
         setFirstChild(textNode.get());
         setLastChild(textNode.get());
     }
diff --git a/Source/core/dom/CSSSelectorWatch.cpp b/Source/core/dom/CSSSelectorWatch.cpp
index d746adb..4f8b781 100644
--- a/Source/core/dom/CSSSelectorWatch.cpp
+++ b/Source/core/dom/CSSSelectorWatch.cpp
@@ -77,7 +77,7 @@
         Vector<String> removedSelectors;
         copyToVector(m_addedSelectors, addedSelectors);
         copyToVector(m_removedSelectors, removedSelectors);
-        m_document.frame()->loader()->client()->selectorMatchChanged(addedSelectors, removedSelectors);
+        m_document.frame()->loader().client()->selectorMatchChanged(addedSelectors, removedSelectors);
     }
     m_addedSelectors.clear();
     m_removedSelectors.clear();
diff --git a/Source/core/dom/CharacterData.cpp b/Source/core/dom/CharacterData.cpp
index 4df25c9..305cad6 100644
--- a/Source/core/dom/CharacterData.cpp
+++ b/Source/core/dom/CharacterData.cpp
@@ -188,7 +188,7 @@
 
 void CharacterData::didModifyData(const String& oldData)
 {
-    if (OwnPtr<MutationObserverInterestGroup> mutationRecipients = MutationObserverInterestGroup::createForCharacterDataMutation(this))
+    if (OwnPtr<MutationObserverInterestGroup> mutationRecipients = MutationObserverInterestGroup::createForCharacterDataMutation(*this))
         mutationRecipients->enqueueMutationRecord(MutationRecord::createCharacterData(this, oldData));
 
     if (parentNode())
diff --git a/Source/core/dom/ChildListMutationScope.cpp b/Source/core/dom/ChildListMutationScope.cpp
index 6acb5b1..47e296e 100644
--- a/Source/core/dom/ChildListMutationScope.cpp
+++ b/Source/core/dom/ChildListMutationScope.cpp
@@ -62,14 +62,14 @@
     accumulatorMap().remove(m_target.get());
 }
 
-PassRefPtr<ChildListMutationAccumulator> ChildListMutationAccumulator::getOrCreate(Node* target)
+PassRefPtr<ChildListMutationAccumulator> ChildListMutationAccumulator::getOrCreate(Node& target)
 {
-    AccumulatorMap::AddResult result = accumulatorMap().add(target, 0);
+    AccumulatorMap::AddResult result = accumulatorMap().add(&target, 0);
     RefPtr<ChildListMutationAccumulator> accumulator;
     if (!result.isNewEntry)
         accumulator = result.iterator->value;
     else {
-        accumulator = adoptRef(new ChildListMutationAccumulator(target, MutationObserverInterestGroup::createForChildListMutation(target)));
+        accumulator = adoptRef(new ChildListMutationAccumulator(PassRefPtr<Node>(target), MutationObserverInterestGroup::createForChildListMutation(target)));
         result.iterator->value = accumulator.get();
     }
     return accumulator.release();
diff --git a/Source/core/dom/ChildListMutationScope.h b/Source/core/dom/ChildListMutationScope.h
index 442df97..d847d82 100644
--- a/Source/core/dom/ChildListMutationScope.h
+++ b/Source/core/dom/ChildListMutationScope.h
@@ -45,7 +45,7 @@
 // ChildListMutationAccumulator is not meant to be used directly; ChildListMutationScope is the public interface.
 class ChildListMutationAccumulator : public RefCounted<ChildListMutationAccumulator> {
 public:
-    static PassRefPtr<ChildListMutationAccumulator> getOrCreate(Node*);
+    static PassRefPtr<ChildListMutationAccumulator> getOrCreate(Node&);
     ~ChildListMutationAccumulator();
 
     void childAdded(PassRefPtr<Node>);
@@ -75,22 +75,22 @@
 class ChildListMutationScope {
     WTF_MAKE_NONCOPYABLE(ChildListMutationScope);
 public:
-    explicit ChildListMutationScope(Node* target)
+    explicit ChildListMutationScope(Node& target)
     {
-        if (target->document().hasMutationObserversOfType(MutationObserver::ChildList))
+        if (target.document().hasMutationObserversOfType(MutationObserver::ChildList))
             m_accumulator = ChildListMutationAccumulator::getOrCreate(target);
     }
 
-    void childAdded(Node* child)
+    void childAdded(Node& child)
     {
         if (m_accumulator && m_accumulator->hasObservers())
-            m_accumulator->childAdded(child);
+            m_accumulator->childAdded(PassRefPtr<Node>(child));
     }
 
-    void willRemoveChild(Node* child)
+    void willRemoveChild(Node& child)
     {
         if (m_accumulator && m_accumulator->hasObservers())
-            m_accumulator->willRemoveChild(child);
+            m_accumulator->willRemoveChild(PassRefPtr<Node>(child));
     }
 
 private:
diff --git a/Source/core/dom/ContainerNode.cpp b/Source/core/dom/ContainerNode.cpp
index 13140b6..676aac1 100644
--- a/Source/core/dom/ContainerNode.cpp
+++ b/Source/core/dom/ContainerNode.cpp
@@ -49,9 +49,9 @@
 
 namespace WebCore {
 
-static void dispatchChildInsertionEvents(Node*);
-static void dispatchChildRemovalEvents(Node*);
-static void updateTreeAfterInsertion(ContainerNode*, Node*);
+static void dispatchChildInsertionEvents(Node&);
+static void dispatchChildRemovalEvents(Node&);
+static void updateTreeAfterInsertion(ContainerNode&, Node&);
 
 ChildNodesLazySnapshot* ChildNodesLazySnapshot::latestSnapshot = 0;
 
@@ -82,22 +82,21 @@
             child->updateAncestorConnectedSubframeCountForRemoval();
     }
     // FIXME: We should be able to ASSERT(!confusingAndOftenMisusedAttached()) here: https://bugs.webkit.org/show_bug.cgi?id=107801
-    removeDetachedChildrenInContainer<Node, ContainerNode>(this);
+    removeDetachedChildrenInContainer<Node, ContainerNode>(*this);
 }
 
 void ContainerNode::parserTakeAllChildrenFrom(ContainerNode* oldParent)
 {
     while (RefPtr<Node> child = oldParent->firstChild()) {
-        oldParent->parserRemoveChild(child.get());
-        treeScope().adoptIfNeeded(child.get());
+        oldParent->parserRemoveChild(*child);
+        treeScope().adoptIfNeeded(*child);
         parserAppendChild(child.get());
     }
 }
 
 ContainerNode::~ContainerNode()
 {
-    if (Document* document = documentInternal())
-        willBeDeletedFrom(document);
+    willBeDeletedFromDocument();
     removeDetachedChildren();
 }
 
@@ -235,9 +234,10 @@
 
     InspectorInstrumentation::willInsertDOMNode(this);
 
-    ChildListMutationScope mutation(this);
+    ChildListMutationScope mutation(*this);
     for (NodeVector::const_iterator it = targets.begin(); it != targets.end(); ++it) {
-        Node* child = it->get();
+        ASSERT(*it);
+        Node& child = **it;
 
         // Due to arbitrary code running in response to a DOM mutation event it's
         // possible that "next" is no longer a child of "this".
@@ -245,43 +245,42 @@
         // In either of those cases, we'll just stop.
         if (next->parentNode() != this)
             break;
-        if (child->parentNode())
+        if (child.parentNode())
             break;
 
         treeScope().adoptIfNeeded(child);
 
-        insertBeforeCommon(next.get(), child);
+        insertBeforeCommon(*next, child);
 
-        updateTreeAfterInsertion(this, child);
+        updateTreeAfterInsertion(*this, child);
     }
 
     dispatchSubtreeModifiedEvent();
 }
 
-void ContainerNode::insertBeforeCommon(Node* nextChild, Node* newChild)
+void ContainerNode::insertBeforeCommon(Node& nextChild, Node& newChild)
 {
     NoEventDispatchAssertion assertNoEventDispatch;
 
-    ASSERT(newChild);
-    ASSERT(!newChild->parentNode()); // Use insertBefore if you need to handle reparenting (and want DOM mutation events).
-    ASSERT(!newChild->nextSibling());
-    ASSERT(!newChild->previousSibling());
-    ASSERT(!newChild->isShadowRoot());
+    ASSERT(!newChild.parentNode()); // Use insertBefore if you need to handle reparenting (and want DOM mutation events).
+    ASSERT(!newChild.nextSibling());
+    ASSERT(!newChild.previousSibling());
+    ASSERT(!newChild.isShadowRoot());
 
-    Node* prev = nextChild->previousSibling();
+    Node* prev = nextChild.previousSibling();
     ASSERT(m_lastChild != prev);
-    nextChild->setPreviousSibling(newChild);
+    nextChild.setPreviousSibling(&newChild);
     if (prev) {
         ASSERT(m_firstChild != nextChild);
         ASSERT(prev->nextSibling() == nextChild);
-        prev->setNextSibling(newChild);
+        prev->setNextSibling(&newChild);
     } else {
         ASSERT(m_firstChild == nextChild);
-        m_firstChild = newChild;
+        m_firstChild = &newChild;
     }
-    newChild->setParentOrShadowHostNode(this);
-    newChild->setPreviousSibling(prev);
-    newChild->setNextSibling(nextChild);
+    newChild.setParentOrShadowHostNode(this);
+    newChild.setPreviousSibling(prev);
+    newChild.setNextSibling(&nextChild);
 }
 
 void ContainerNode::parserInsertBefore(PassRefPtr<Node> newChild, Node* nextChild)
@@ -298,15 +297,15 @@
     if (document() != newChild->document())
         document().adoptNode(newChild.get(), ASSERT_NO_EXCEPTION);
 
-    insertBeforeCommon(nextChild, newChild.get());
+    insertBeforeCommon(*nextChild, *newChild);
 
     newChild->updateAncestorConnectedSubframeCountForInsertion();
 
-    ChildListMutationScope(this).childAdded(newChild.get());
+    ChildListMutationScope(*this).childAdded(*newChild);
 
     childrenChanged(true, newChild->previousSibling(), nextChild, 1);
 
-    ChildNodeInsertionNotifier(this).notify(newChild.get());
+    ChildNodeInsertionNotifier(*this).notify(*newChild);
 }
 
 void ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionState& es)
@@ -335,7 +334,7 @@
         return;
     }
 
-    ChildListMutationScope mutation(this);
+    ChildListMutationScope mutation(*this);
 
     RefPtr<Node> next = oldChild->nextSibling();
 
@@ -365,7 +364,8 @@
 
     // Add the new child(ren)
     for (NodeVector::const_iterator it = targets.begin(); it != targets.end(); ++it) {
-        Node* child = it->get();
+        ASSERT(*it);
+        Node& child = **it;
 
         // Due to arbitrary code running in response to a DOM mutation event it's
         // possible that "next" is no longer a child of "this".
@@ -373,7 +373,7 @@
         // In either of those cases, we'll just stop.
         if (next && next->parentNode() != this)
             break;
-        if (child->parentNode())
+        if (child.parentNode())
             break;
 
         treeScope().adoptIfNeeded(child);
@@ -382,37 +382,38 @@
         {
             NoEventDispatchAssertion assertNoEventDispatch;
             if (next)
-                insertBeforeCommon(next.get(), child);
+                insertBeforeCommon(*next, child);
             else
-                appendChildToContainer(child, this);
+                appendChildToContainer(child, *this);
         }
 
-        updateTreeAfterInsertion(this, child);
+        updateTreeAfterInsertion(*this, child);
     }
 
     dispatchSubtreeModifiedEvent();
 }
 
-static void willRemoveChild(Node* child)
+static void willRemoveChild(Node& child)
 {
-    ASSERT(child->parentNode());
-    ChildListMutationScope(child->parentNode()).willRemoveChild(child);
-    child->notifyMutationObserversNodeWillDetach();
+    ASSERT(child.parentNode());
+    ChildListMutationScope(*child.parentNode()).willRemoveChild(child);
+    child.notifyMutationObserversNodeWillDetach();
     dispatchChildRemovalEvents(child);
-    child->document().nodeWillBeRemoved(child); // e.g. mutation event listener can create a new range.
+    child.document().nodeWillBeRemoved(&child); // e.g. mutation event listener can create a new range.
     ChildFrameDisconnector(child).disconnect();
 }
 
-static void willRemoveChildren(ContainerNode* container)
+static void willRemoveChildren(ContainerNode& container)
 {
     NodeVector children;
-    getChildNodes(container, children);
+    getChildNodes(&container, children);
 
     ChildListMutationScope mutation(container);
     for (NodeVector::const_iterator it = children.begin(); it != children.end(); it++) {
-        Node* child = it->get();
+        ASSERT(*it);
+        Node& child = **it;
         mutation.willRemoveChild(child);
-        child->notifyMutationObserversNodeWillDetach();
+        child.notifyMutationObserversNodeWillDetach();
 
         // fire removed from document mutation events.
         dispatchChildRemovalEvents(child);
@@ -423,7 +424,7 @@
 
 void ContainerNode::disconnectDescendantFrames()
 {
-    ChildFrameDisconnector(this).disconnect();
+    ChildFrameDisconnector(*this).disconnect();
 }
 
 void ContainerNode::removeChild(Node* oldChild, ExceptionState& es)
@@ -454,7 +455,7 @@
         return;
     }
 
-    willRemoveChild(child.get());
+    willRemoveChild(*child);
 
     // Mutation events might have moved this child into a different parent.
     if (child->parentNode() != this) {
@@ -467,23 +468,22 @@
 
         Node* prev = child->previousSibling();
         Node* next = child->nextSibling();
-        removeBetween(prev, next, child.get());
+        removeBetween(prev, next, *child);
         childrenChanged(false, prev, next, -1);
-        ChildNodeRemovalNotifier(this).notify(child.get());
+        ChildNodeRemovalNotifier(*this).notify(*child);
     }
     dispatchSubtreeModifiedEvent();
 }
 
-void ContainerNode::removeBetween(Node* previousChild, Node* nextChild, Node* oldChild)
+void ContainerNode::removeBetween(Node* previousChild, Node* nextChild, Node& oldChild)
 {
     NoEventDispatchAssertion assertNoEventDispatch;
 
-    ASSERT(oldChild);
-    ASSERT(oldChild->parentNode() == this);
+    ASSERT(oldChild.parentNode() == this);
 
     // Remove from rendering tree
-    if (oldChild->confusingAndOftenMisusedAttached())
-        oldChild->detach();
+    if (oldChild.confusingAndOftenMisusedAttached())
+        oldChild.detach();
 
     if (nextChild)
         nextChild->setPreviousSibling(previousChild);
@@ -494,31 +494,30 @@
     if (m_lastChild == oldChild)
         m_lastChild = previousChild;
 
-    oldChild->setPreviousSibling(0);
-    oldChild->setNextSibling(0);
-    oldChild->setParentOrShadowHostNode(0);
+    oldChild.setPreviousSibling(0);
+    oldChild.setNextSibling(0);
+    oldChild.setParentOrShadowHostNode(0);
 
     document().adoptIfNeeded(oldChild);
 }
 
-void ContainerNode::parserRemoveChild(Node* oldChild)
+void ContainerNode::parserRemoveChild(Node& oldChild)
 {
-    ASSERT(oldChild);
-    ASSERT(oldChild->parentNode() == this);
-    ASSERT(!oldChild->isDocumentFragment());
+    ASSERT(oldChild.parentNode() == this);
+    ASSERT(!oldChild.isDocumentFragment());
 
-    Node* prev = oldChild->previousSibling();
-    Node* next = oldChild->nextSibling();
+    Node* prev = oldChild.previousSibling();
+    Node* next = oldChild.nextSibling();
 
-    oldChild->updateAncestorConnectedSubframeCountForRemoval();
+    oldChild.updateAncestorConnectedSubframeCountForRemoval();
 
-    ChildListMutationScope(this).willRemoveChild(oldChild);
-    oldChild->notifyMutationObserversNodeWillDetach();
+    ChildListMutationScope(*this).willRemoveChild(oldChild);
+    oldChild.notifyMutationObserversNodeWillDetach();
 
     removeBetween(prev, next, oldChild);
 
     childrenChanged(true, prev, next, -1);
-    ChildNodeRemovalNotifier(this).notify(oldChild);
+    ChildNodeRemovalNotifier(*this).notify(oldChild);
 }
 
 // this differs from other remove functions because it forcibly removes all the children,
@@ -536,7 +535,7 @@
 
     // Do any prep work needed before actually starting to detach
     // and remove... e.g. stop loading frames, fire unload events.
-    willRemoveChildren(protect.get());
+    willRemoveChildren(*this);
 
     {
         // Removing focus can cause frames to load, either via events (focusout, blur)
@@ -548,9 +547,11 @@
         // This must be later than willRemoveChildren, which might change focus
         // state of a child.
         document().removeFocusedElementOfSubtree(this, true);
+
+        // Removing a node from a selection can cause widget updates.
+        document().nodeChildrenWillBeRemoved(this);
     }
 
-    document().nodeChildrenWillBeRemoved(this);
 
     NodeVector removedChildren;
     {
@@ -560,14 +561,14 @@
             removedChildren.reserveInitialCapacity(childNodeCount());
             while (m_firstChild) {
                 removedChildren.append(m_firstChild);
-                removeBetween(0, m_firstChild->nextSibling(), m_firstChild);
+                removeBetween(0, m_firstChild->nextSibling(), *m_firstChild);
             }
         }
 
         childrenChanged(false, 0, 0, -static_cast<int>(removedChildren.size()));
 
         for (size_t i = 0; i < removedChildren.size(); ++i)
-            ChildNodeRemovalNotifier(this).notify(removedChildren[i].get());
+            ChildNodeRemovalNotifier(*this).notify(*removedChildren[i]);
     }
 
     dispatchSubtreeModifiedEvent();
@@ -603,14 +604,15 @@
     InspectorInstrumentation::willInsertDOMNode(this);
 
     // Now actually add the child(ren)
-    ChildListMutationScope mutation(this);
+    ChildListMutationScope mutation(*this);
     for (NodeVector::const_iterator it = targets.begin(); it != targets.end(); ++it) {
-        Node* child = it->get();
+        ASSERT(*it);
+        Node& child = **it;
 
         // If the child has a parent again, just stop what we're doing, because
         // that means someone is doing something with DOM mutation -- can't re-parent
         // a child that already has a parent.
-        if (child->parentNode())
+        if (child.parentNode())
             break;
 
         treeScope().adoptIfNeeded(child);
@@ -618,10 +620,10 @@
         // Append child to the end of the list
         {
             NoEventDispatchAssertion assertNoEventDispatch;
-            appendChildToContainer(child, this);
+            appendChildToContainer(child, *this);
         }
 
-        updateTreeAfterInsertion(this, child);
+        updateTreeAfterInsertion(*this, child);
     }
 
     dispatchSubtreeModifiedEvent();
@@ -641,16 +643,16 @@
     {
         NoEventDispatchAssertion assertNoEventDispatch;
         // FIXME: This method should take a PassRefPtr.
-        appendChildToContainer(newChild.get(), this);
-        treeScope().adoptIfNeeded(newChild.get());
+        appendChildToContainer(*newChild, *this);
+        treeScope().adoptIfNeeded(*newChild);
     }
 
     newChild->updateAncestorConnectedSubframeCountForInsertion();
 
-    ChildListMutationScope(this).childAdded(newChild.get());
+    ChildListMutationScope(*this).childAdded(*newChild);
 
     childrenChanged(true, last, 0, 1);
-    ChildNodeInsertionNotifier(this).notify(newChild.get());
+    ChildNodeInsertionNotifier(*this).notify(*newChild);
 }
 
 void ContainerNode::attach(const AttachContext& context)
@@ -872,7 +874,7 @@
 
 PassRefPtr<HTMLCollection> ContainerNode::children()
 {
-    return ensureRareData().ensureNodeLists()->addCacheWithAtomicName<HTMLCollection>(this, NodeChildren);
+    return ensureRareData().ensureNodeLists().addCacheWithAtomicName<HTMLCollection>(this, NodeChildren);
 }
 
 Element* ContainerNode::firstElementChild() const
@@ -917,62 +919,62 @@
     return n;
 }
 
-static void dispatchChildInsertionEvents(Node* child)
+static void dispatchChildInsertionEvents(Node& child)
 {
-    if (child->isInShadowTree())
+    if (child.isInShadowTree())
         return;
 
     ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
 
-    RefPtr<Node> c = child;
-    RefPtr<Document> document(child->document());
+    RefPtr<Node> c(child);
+    RefPtr<Document> document(child.document());
 
     if (c->parentNode() && document->hasListenerType(Document::DOMNODEINSERTED_LISTENER))
         c->dispatchScopedEvent(MutationEvent::create(EventTypeNames::DOMNodeInserted, true, c->parentNode()));
 
     // dispatch the DOMNodeInsertedIntoDocument event to all descendants
     if (c->inDocument() && document->hasListenerType(Document::DOMNODEINSERTEDINTODOCUMENT_LISTENER)) {
-        for (; c; c = NodeTraversal::next(c.get(), child))
+        for (; c; c = NodeTraversal::next(c.get(), &child))
             c->dispatchScopedEvent(MutationEvent::create(EventTypeNames::DOMNodeInsertedIntoDocument, false));
     }
 }
 
-static void dispatchChildRemovalEvents(Node* child)
+static void dispatchChildRemovalEvents(Node& child)
 {
-    if (child->isInShadowTree()) {
-        InspectorInstrumentation::willRemoveDOMNode(child);
+    if (child.isInShadowTree()) {
+        InspectorInstrumentation::willRemoveDOMNode(&child);
         return;
     }
 
     ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
 
-    InspectorInstrumentation::willRemoveDOMNode(child);
+    InspectorInstrumentation::willRemoveDOMNode(&child);
 
-    RefPtr<Node> c = child;
-    RefPtr<Document> document(child->document());
+    RefPtr<Node> c(child);
+    RefPtr<Document> document(child.document());
 
     // dispatch pre-removal mutation events
     if (c->parentNode() && document->hasListenerType(Document::DOMNODEREMOVED_LISTENER)) {
-        NodeChildRemovalTracker scope(child);
+        NodeChildRemovalTracker scope(&child);
         c->dispatchScopedEvent(MutationEvent::create(EventTypeNames::DOMNodeRemoved, true, c->parentNode()));
     }
 
     // dispatch the DOMNodeRemovedFromDocument event to all descendants
     if (c->inDocument() && document->hasListenerType(Document::DOMNODEREMOVEDFROMDOCUMENT_LISTENER)) {
-        NodeChildRemovalTracker scope(child);
-        for (; c; c = NodeTraversal::next(c.get(), child))
+        NodeChildRemovalTracker scope(&child);
+        for (; c; c = NodeTraversal::next(c.get(), &child))
             c->dispatchScopedEvent(MutationEvent::create(EventTypeNames::DOMNodeRemovedFromDocument, false));
     }
 }
 
-static void updateTreeAfterInsertion(ContainerNode* parent, Node* child)
+static void updateTreeAfterInsertion(ContainerNode& parent, Node& child)
 {
-    ASSERT(parent->refCount());
-    ASSERT(child->refCount());
+    ASSERT(parent.refCount());
+    ASSERT(child.refCount());
 
     ChildListMutationScope(parent).childAdded(child);
 
-    parent->childrenChanged(false, child->previousSibling(), child->nextSibling(), 1);
+    parent.childrenChanged(false, child.previousSibling(), child.nextSibling(), 1);
 
     ChildNodeInsertionNotifier(parent).notify(child);
 
diff --git a/Source/core/dom/ContainerNode.h b/Source/core/dom/ContainerNode.h
index 61034cb..16d0942 100644
--- a/Source/core/dom/ContainerNode.h
+++ b/Source/core/dom/ContainerNode.h
@@ -37,8 +37,8 @@
 
 namespace Private {
     template<class GenericNode, class GenericNodeContainer>
-    void addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, GenericNodeContainer*);
-};
+    void addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, GenericNodeContainer&);
+}
 
 class NoEventDispatchAssertion {
 public:
@@ -105,7 +105,7 @@
     // They don't send DOM mutation events or handle reparenting.
     // However, arbitrary code may be run by beforeload handlers.
     void parserAppendChild(PassRefPtr<Node>);
-    void parserRemoveChild(Node*);
+    void parserRemoveChild(Node&);
     void parserInsertBefore(PassRefPtr<Node> newChild, Node* refChild);
     void parserTakeAllChildrenFrom(ContainerNode*);
 
@@ -135,18 +135,18 @@
     ContainerNode(TreeScope*, ConstructionType = CreateContainer);
 
     template<class GenericNode, class GenericNodeContainer>
-    friend void appendChildToContainer(GenericNode* child, GenericNodeContainer*);
+    friend void appendChildToContainer(GenericNode& child, GenericNodeContainer&);
 
     template<class GenericNode, class GenericNodeContainer>
-    friend void Private::addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, GenericNodeContainer*);
+    friend void Private::addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, GenericNodeContainer&);
 
     void removeDetachedChildren();
     void setFirstChild(Node* child) { m_firstChild = child; }
     void setLastChild(Node* child) { m_lastChild = child; }
 
 private:
-    void removeBetween(Node* previousChild, Node* nextChild, Node* oldChild);
-    void insertBeforeCommon(Node* nextChild, Node* oldChild);
+    void removeBetween(Node* previousChild, Node* nextChild, Node& oldChild);
+    void insertBeforeCommon(Node& nextChild, Node& oldChild);
 
     void attachChildren(const AttachContext& = AttachContext());
     void detachChildren(const AttachContext& = AttachContext());
@@ -246,8 +246,8 @@
     WTF_MAKE_NONCOPYABLE(ChildNodesLazySnapshot);
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    explicit ChildNodesLazySnapshot(Node* parentNode)
-        : m_currentNode(parentNode->firstChild())
+    explicit ChildNodesLazySnapshot(Node& parentNode)
+        : m_currentNode(parentNode.firstChild())
         , m_currentIndex(0)
     {
         m_nextSnapshot = latestSnapshot;
diff --git a/Source/core/dom/ContainerNodeAlgorithms.cpp b/Source/core/dom/ContainerNodeAlgorithms.cpp
index ab67eef..1caa683 100644
--- a/Source/core/dom/ContainerNodeAlgorithms.cpp
+++ b/Source/core/dom/ContainerNodeAlgorithms.cpp
@@ -42,115 +42,115 @@
     }
 };
 
-void ChildNodeInsertionNotifier::notifyDescendantInsertedIntoDocument(ContainerNode* node)
+void ChildNodeInsertionNotifier::notifyDescendantInsertedIntoDocument(ContainerNode& node)
 {
     ChildNodesLazySnapshot snapshot(node);
     while (RefPtr<Node> child = snapshot.nextNode()) {
         // If we have been removed from the document during this loop, then
         // we don't want to tell the rest of our children that they've been
         // inserted into the document because they haven't.
-        if (node->inDocument() && child->parentNode() == node)
-            notifyNodeInsertedIntoDocument(child.get());
+        if (node.inDocument() && child->parentNode() == node)
+            notifyNodeInsertedIntoDocument(*child);
     }
 
-    if (!node->isElementNode())
+    if (!node.isElementNode())
         return;
 
-    if (ElementShadow* shadow = toElement(node)->shadow()) {
+    if (ElementShadow* shadow = toElement(node).shadow()) {
         ShadowRootVector roots(shadow);
         for (size_t i = 0; i < roots.size(); ++i) {
-            if (node->inDocument() && roots[i]->host() == node)
-                notifyNodeInsertedIntoDocument(roots[i].get());
+            if (node.inDocument() && roots[i]->host() == node)
+                notifyNodeInsertedIntoDocument(*roots[i]);
         }
     }
 }
 
-void ChildNodeInsertionNotifier::notifyDescendantInsertedIntoTree(ContainerNode* node)
+void ChildNodeInsertionNotifier::notifyDescendantInsertedIntoTree(ContainerNode& node)
 {
-    for (Node* child = node->firstChild(); child; child = child->nextSibling()) {
+    for (Node* child = node.firstChild(); child; child = child->nextSibling()) {
         if (child->isContainerNode())
-            notifyNodeInsertedIntoTree(toContainerNode(child));
+            notifyNodeInsertedIntoTree(toContainerNode(*child));
     }
 
-    for (ShadowRoot* root = node->youngestShadowRoot(); root; root = root->olderShadowRoot())
-        notifyNodeInsertedIntoTree(root);
+    for (ShadowRoot* root = node.youngestShadowRoot(); root; root = root->olderShadowRoot())
+        notifyNodeInsertedIntoTree(*root);
 }
 
-void ChildNodeRemovalNotifier::notifyDescendantRemovedFromDocument(ContainerNode* node)
+void ChildNodeRemovalNotifier::notifyDescendantRemovedFromDocument(ContainerNode& node)
 {
     ChildNodesLazySnapshot snapshot(node);
     while (RefPtr<Node> child = snapshot.nextNode()) {
         // If we have been added to the document during this loop, then we
         // don't want to tell the rest of our children that they've been
         // removed from the document because they haven't.
-        if (!node->inDocument() && child->parentNode() == node)
-            notifyNodeRemovedFromDocument(child.get());
+        if (!node.inDocument() && child->parentNode() == node)
+            notifyNodeRemovedFromDocument(*child);
     }
 
-    if (!node->isElementNode())
+    if (!node.isElementNode())
         return;
 
-    if (node->document().cssTarget() == node)
-        node->document().setCSSTarget(0);
+    if (node.document().cssTarget() == node)
+        node.document().setCSSTarget(0);
 
-    if (ElementShadow* shadow = toElement(node)->shadow()) {
+    if (ElementShadow* shadow = toElement(node).shadow()) {
         ShadowRootVector roots(shadow);
         for (size_t i = 0; i < roots.size(); ++i) {
-            if (!node->inDocument() && roots[i]->host() == node)
-                notifyNodeRemovedFromDocument(roots[i].get());
+            if (!node.inDocument() && roots[i]->host() == node)
+                notifyNodeRemovedFromDocument(*roots[i]);
         }
     }
 }
 
-void ChildNodeRemovalNotifier::notifyDescendantRemovedFromTree(ContainerNode* node)
+void ChildNodeRemovalNotifier::notifyDescendantRemovedFromTree(ContainerNode& node)
 {
-    for (Node* child = node->firstChild(); child; child = child->nextSibling()) {
+    for (Node* child = node.firstChild(); child; child = child->nextSibling()) {
         if (child->isContainerNode())
-            notifyNodeRemovedFromTree(toContainerNode(child));
+            notifyNodeRemovedFromTree(toContainerNode(*child));
     }
 
-    if (!node->isElementNode())
+    if (!node.isElementNode())
         return;
 
-    if (ElementShadow* shadow = toElement(node)->shadow()) {
+    if (ElementShadow* shadow = toElement(node).shadow()) {
         ShadowRootVector roots(shadow);
         for (size_t i = 0; i < roots.size(); ++i)
-            notifyNodeRemovedFromTree(roots[i].get());
+            notifyNodeRemovedFromTree(*roots[i]);
     }
 }
 
-void ChildFrameDisconnector::collectFrameOwners(ElementShadow* shadow)
+void ChildFrameDisconnector::collectFrameOwners(ElementShadow& shadow)
 {
-    for (ShadowRoot* root = shadow->youngestShadowRoot(); root; root = root->olderShadowRoot())
-        collectFrameOwners(root);
+    for (ShadowRoot* root = shadow.youngestShadowRoot(); root; root = root->olderShadowRoot())
+        collectFrameOwners(*root);
 }
 
 #ifndef NDEBUG
-unsigned assertConnectedSubrameCountIsConsistent(Node* node)
+unsigned assertConnectedSubrameCountIsConsistent(Node& node)
 {
     unsigned count = 0;
 
-    if (node->isElementNode()) {
-        if (node->isFrameOwnerElement() && toHTMLFrameOwnerElement(node)->contentFrame())
+    if (node.isElementNode()) {
+        if (node.isFrameOwnerElement() && toHTMLFrameOwnerElement(node).contentFrame())
             count++;
 
-        if (ElementShadow* shadow = toElement(node)->shadow()) {
+        if (ElementShadow* shadow = toElement(node).shadow()) {
             for (ShadowRoot* root = shadow->youngestShadowRoot(); root; root = root->olderShadowRoot())
-                count += assertConnectedSubrameCountIsConsistent(root);
+                count += assertConnectedSubrameCountIsConsistent(*root);
         }
     }
 
-    for (Node* child = node->firstChild(); child; child = child->nextSibling())
-        count += assertConnectedSubrameCountIsConsistent(child);
+    for (Node* child = node.firstChild(); child; child = child->nextSibling())
+        count += assertConnectedSubrameCountIsConsistent(*child);
 
     // If we undercount there's possibly a security bug since we'd leave frames
     // in subtrees outside the document.
-    ASSERT(node->connectedSubframeCount() >= count);
+    ASSERT(node.connectedSubframeCount() >= count);
 
     // If we overcount it's safe, but not optimal because it means we'll traverse
     // through the document in ChildFrameDisconnector looking for frames that have
     // already been disconnected.
-    ASSERT(node->connectedSubframeCount() == count);
+    ASSERT(node.connectedSubframeCount() == count);
 
     return count;
 }
diff --git a/Source/core/dom/ContainerNodeAlgorithms.h b/Source/core/dom/ContainerNodeAlgorithms.h
index a6683fd..a0b7dbe 100644
--- a/Source/core/dom/ContainerNodeAlgorithms.h
+++ b/Source/core/dom/ContainerNodeAlgorithms.h
@@ -31,52 +31,52 @@
 
 class ChildNodeInsertionNotifier {
 public:
-    explicit ChildNodeInsertionNotifier(ContainerNode* insertionPoint)
+    explicit ChildNodeInsertionNotifier(ContainerNode& insertionPoint)
         : m_insertionPoint(insertionPoint)
     {
     }
 
-    void notify(Node*);
+    void notify(Node&);
 
 private:
-    void notifyDescendantInsertedIntoDocument(ContainerNode*);
-    void notifyDescendantInsertedIntoTree(ContainerNode*);
-    void notifyNodeInsertedIntoDocument(Node*);
-    void notifyNodeInsertedIntoTree(ContainerNode*);
+    void notifyDescendantInsertedIntoDocument(ContainerNode&);
+    void notifyDescendantInsertedIntoTree(ContainerNode&);
+    void notifyNodeInsertedIntoDocument(Node&);
+    void notifyNodeInsertedIntoTree(ContainerNode&);
 
-    ContainerNode* m_insertionPoint;
+    ContainerNode& m_insertionPoint;
     Vector< RefPtr<Node> > m_postInsertionNotificationTargets;
 };
 
 class ChildNodeRemovalNotifier {
 public:
-    explicit ChildNodeRemovalNotifier(ContainerNode* insertionPoint)
+    explicit ChildNodeRemovalNotifier(ContainerNode& insertionPoint)
         : m_insertionPoint(insertionPoint)
     {
     }
 
-    void notify(Node*);
+    void notify(Node&);
 
 private:
-    void notifyDescendantRemovedFromDocument(ContainerNode*);
-    void notifyDescendantRemovedFromTree(ContainerNode*);
-    void notifyNodeRemovedFromDocument(Node*);
-    void notifyNodeRemovedFromTree(ContainerNode*);
+    void notifyDescendantRemovedFromDocument(ContainerNode&);
+    void notifyDescendantRemovedFromTree(ContainerNode&);
+    void notifyNodeRemovedFromDocument(Node&);
+    void notifyNodeRemovedFromTree(ContainerNode&);
 
-    ContainerNode* m_insertionPoint;
+    ContainerNode& m_insertionPoint;
 };
 
 namespace Private {
 
     template<class GenericNode, class GenericNodeContainer>
-    void addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, GenericNodeContainer*);
+    void addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, GenericNodeContainer&);
 
 }
 
 // Helper functions for TreeShared-derived classes, which have a 'Node' style interface
 // This applies to 'ContainerNode' and 'SVGElementInstance'
 template<class GenericNode, class GenericNodeContainer>
-inline void removeDetachedChildrenInContainer(GenericNodeContainer* container)
+inline void removeDetachedChildrenInContainer(GenericNodeContainer& container)
 {
     // List of nodes to be deleted.
     GenericNode* head = 0;
@@ -97,25 +97,26 @@
             tail = 0;
 
         if (n->hasChildNodes())
-            Private::addChildNodesToDeletionQueue<GenericNode, GenericNodeContainer>(head, tail, static_cast<GenericNodeContainer*>(n));
+            Private::addChildNodesToDeletionQueue<GenericNode, GenericNodeContainer>(head, tail, static_cast<GenericNodeContainer&>(*n));
 
         delete n;
     }
 }
 
 template<class GenericNode, class GenericNodeContainer>
-inline void appendChildToContainer(GenericNode* child, GenericNodeContainer* container)
+inline void appendChildToContainer(GenericNode& child, GenericNodeContainer& container)
 {
-    child->setParentOrShadowHostNode(container);
+    child.setParentOrShadowHostNode(&container);
 
-    GenericNode* lastChild = container->lastChild();
+    GenericNode* lastChild = container.lastChild();
     if (lastChild) {
-        child->setPreviousSibling(lastChild);
-        lastChild->setNextSibling(child);
-    } else
-        container->setFirstChild(child);
+        child.setPreviousSibling(lastChild);
+        lastChild->setNextSibling(&child);
+    } else {
+        container.setFirstChild(&child);
+    }
 
-    container->setLastChild(child);
+    container.setLastChild(&child);
 }
 
 // Helper methods for removeDetachedChildrenInContainer, hidden from WebCore namespace
@@ -123,7 +124,7 @@
 
     template<class GenericNode, class GenericNodeContainer, bool dispatchRemovalNotification>
     struct NodeRemovalDispatcher {
-        static void dispatch(GenericNode*, GenericNodeContainer*)
+        static void dispatch(GenericNode&, GenericNodeContainer&)
         {
             // no-op, by default
         }
@@ -131,12 +132,12 @@
 
     template<class GenericNode, class GenericNodeContainer>
     struct NodeRemovalDispatcher<GenericNode, GenericNodeContainer, true> {
-        static void dispatch(GenericNode* node, GenericNodeContainer* container)
+        static void dispatch(GenericNode& node, GenericNodeContainer& container)
         {
             // Clean up any TreeScope to a removed tree.
-            if (Document* containerDocument = container->ownerDocument())
+            if (Document* containerDocument = container.ownerDocument())
                 containerDocument->adoptIfNeeded(node);
-            if (node->inDocument())
+            if (node.inDocument())
                 ChildNodeRemovalNotifier(container).notify(node);
         }
     };
@@ -152,17 +153,17 @@
     };
 
     template<class GenericNode, class GenericNodeContainer>
-    void addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, GenericNodeContainer* container)
+    void addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, GenericNodeContainer& container)
     {
         // We have to tell all children that their parent has died.
         GenericNode* next = 0;
-        for (GenericNode* n = container->firstChild(); n != 0; n = next) {
+        for (GenericNode* n = container.firstChild(); n; n = next) {
             ASSERT_WITH_SECURITY_IMPLICATION(!n->m_deletionHasBegun);
 
             next = n->nextSibling();
             n->setNextSibling(0);
             n->setParentOrShadowHostNode(0);
-            container->setFirstChild(next);
+            container.setFirstChild(next);
             if (next)
                 next->setPreviousSibling(0);
 
@@ -180,47 +181,47 @@
                 tail = n;
             } else {
                 RefPtr<GenericNode> protect(n); // removedFromDocument may remove remove all references to this node.
-                NodeRemovalDispatcher<GenericNode, GenericNodeContainer, ShouldDispatchRemovalNotification<GenericNode>::value>::dispatch(n, container);
+                NodeRemovalDispatcher<GenericNode, GenericNodeContainer, ShouldDispatchRemovalNotification<GenericNode>::value>::dispatch(*n, container);
             }
         }
 
-        container->setLastChild(0);
+        container.setLastChild(0);
     }
 
 } // namespace Private
 
-inline void ChildNodeInsertionNotifier::notifyNodeInsertedIntoDocument(Node* node)
+inline void ChildNodeInsertionNotifier::notifyNodeInsertedIntoDocument(Node& node)
 {
-    ASSERT(m_insertionPoint->inDocument());
+    ASSERT(m_insertionPoint.inDocument());
     RefPtr<Node> protect(node);
-    if (Node::InsertionShouldCallDidNotifySubtreeInsertions == node->insertedInto(m_insertionPoint))
-        m_postInsertionNotificationTargets.append(node);
-    if (node->isContainerNode())
+    if (Node::InsertionShouldCallDidNotifySubtreeInsertions == node.insertedInto(&m_insertionPoint))
+        m_postInsertionNotificationTargets.append(&node);
+    if (node.isContainerNode())
         notifyDescendantInsertedIntoDocument(toContainerNode(node));
 }
 
-inline void ChildNodeInsertionNotifier::notifyNodeInsertedIntoTree(ContainerNode* node)
+inline void ChildNodeInsertionNotifier::notifyNodeInsertedIntoTree(ContainerNode& node)
 {
     NoEventDispatchAssertion assertNoEventDispatch;
-    ASSERT(!m_insertionPoint->inDocument());
+    ASSERT(!m_insertionPoint.inDocument());
 
-    if (Node::InsertionShouldCallDidNotifySubtreeInsertions == node->insertedInto(m_insertionPoint))
-        m_postInsertionNotificationTargets.append(node);
+    if (Node::InsertionShouldCallDidNotifySubtreeInsertions == node.insertedInto(&m_insertionPoint))
+        m_postInsertionNotificationTargets.append(&node);
     notifyDescendantInsertedIntoTree(node);
 }
 
-inline void ChildNodeInsertionNotifier::notify(Node* node)
+inline void ChildNodeInsertionNotifier::notify(Node& node)
 {
     ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
 
-    InspectorInstrumentation::didInsertDOMNode(node);
+    InspectorInstrumentation::didInsertDOMNode(&node);
 
-    RefPtr<Document> protectDocument(node->document());
+    RefPtr<Document> protectDocument(node.document());
     RefPtr<Node> protectNode(node);
 
-    if (m_insertionPoint->inDocument())
+    if (m_insertionPoint.inDocument())
         notifyNodeInsertedIntoDocument(node);
-    else if (node->isContainerNode())
+    else if (node.isContainerNode())
         notifyNodeInsertedIntoTree(toContainerNode(node));
 
     // Script runs in didNotifySubtreeInsertions so we should lazy attach before
@@ -228,40 +229,40 @@
     // were inserted.
     // FIXME: We should merge the lazy attach logic into the tree traversal in
     // notifyNodeInsertedIntoDocument.
-    if (!node->confusingAndOftenMisusedAttached() && node->parentNode() && node->parentNode()->confusingAndOftenMisusedAttached())
-        node->lazyAttach();
+    if (!node.confusingAndOftenMisusedAttached() && node.parentNode() && node.parentNode()->confusingAndOftenMisusedAttached())
+        node.lazyAttach();
 
     for (size_t i = 0; i < m_postInsertionNotificationTargets.size(); ++i) {
-        Node* node = m_postInsertionNotificationTargets[i].get();
-        if (node->inDocument())
-            node->didNotifySubtreeInsertionsToDocument();
+        Node* targetNode = m_postInsertionNotificationTargets[i].get();
+        if (targetNode->inDocument())
+            targetNode->didNotifySubtreeInsertionsToDocument();
     }
 }
 
-inline void ChildNodeRemovalNotifier::notifyNodeRemovedFromDocument(Node* node)
+inline void ChildNodeRemovalNotifier::notifyNodeRemovedFromDocument(Node& node)
 {
-    ASSERT(m_insertionPoint->inDocument());
-    node->removedFrom(m_insertionPoint);
+    ASSERT(m_insertionPoint.inDocument());
+    node.removedFrom(&m_insertionPoint);
 
-    if (node->isContainerNode())
+    if (node.isContainerNode())
         notifyDescendantRemovedFromDocument(toContainerNode(node));
 }
 
-inline void ChildNodeRemovalNotifier::notifyNodeRemovedFromTree(ContainerNode* node)
+inline void ChildNodeRemovalNotifier::notifyNodeRemovedFromTree(ContainerNode& node)
 {
     NoEventDispatchAssertion assertNoEventDispatch;
-    ASSERT(!m_insertionPoint->inDocument());
+    ASSERT(!m_insertionPoint.inDocument());
 
-    node->removedFrom(m_insertionPoint);
+    node.removedFrom(&m_insertionPoint);
     notifyDescendantRemovedFromTree(node);
 }
 
-inline void ChildNodeRemovalNotifier::notify(Node* node)
+inline void ChildNodeRemovalNotifier::notify(Node& node)
 {
-    if (node->inDocument()) {
+    if (node.inDocument()) {
         notifyNodeRemovedFromDocument(node);
-        node->document().notifyRemovePendingSheetIfNeeded();
-    } else if (node->isContainerNode())
+        node.document().notifyRemovePendingSheetIfNeeded();
+    } else if (node.isContainerNode())
         notifyNodeRemovedFromTree(toContainerNode(node));
 }
 
@@ -272,7 +273,7 @@
         DescendantsOnly
     };
 
-    explicit ChildFrameDisconnector(Node* root)
+    explicit ChildFrameDisconnector(Node& root)
         : m_root(root)
     {
     }
@@ -280,45 +281,45 @@
     void disconnect(DisconnectPolicy = RootAndDescendants);
 
 private:
-    void collectFrameOwners(Node* root);
-    void collectFrameOwners(ElementShadow*);
+    void collectFrameOwners(Node& root);
+    void collectFrameOwners(ElementShadow&);
     void disconnectCollectedFrameOwners();
 
     Vector<RefPtr<HTMLFrameOwnerElement>, 10> m_frameOwners;
-    Node* m_root;
+    Node& m_root;
 };
 
 #ifndef NDEBUG
-unsigned assertConnectedSubrameCountIsConsistent(Node*);
+unsigned assertConnectedSubrameCountIsConsistent(Node&);
 #endif
 
-inline void ChildFrameDisconnector::collectFrameOwners(Node* root)
+inline void ChildFrameDisconnector::collectFrameOwners(Node& root)
 {
-    if (!root->connectedSubframeCount())
+    if (!root.connectedSubframeCount())
         return;
 
-    if (root->isHTMLElement() && root->isFrameOwnerElement())
-        m_frameOwners.append(toHTMLFrameOwnerElement(root));
+    if (root.isHTMLElement() && root.isFrameOwnerElement())
+        m_frameOwners.append(&toHTMLFrameOwnerElement(root));
 
-    for (Node* child = root->firstChild(); child; child = child->nextSibling())
-        collectFrameOwners(child);
+    for (Node* child = root.firstChild(); child; child = child->nextSibling())
+        collectFrameOwners(*child);
 
-    ElementShadow* shadow = root->isElementNode() ? toElement(root)->shadow() : 0;
+    ElementShadow* shadow = root.isElementNode() ? toElement(root).shadow() : 0;
     if (shadow)
-        collectFrameOwners(shadow);
+        collectFrameOwners(*shadow);
 }
 
 inline void ChildFrameDisconnector::disconnectCollectedFrameOwners()
 {
     // Must disable frame loading in the subtree so an unload handler cannot
     // insert more frames and create loaded frames in detached subtrees.
-    SubframeLoadingDisabler disabler(m_root);
+    SubframeLoadingDisabler disabler(&m_root);
 
     for (unsigned i = 0; i < m_frameOwners.size(); ++i) {
         HTMLFrameOwnerElement* owner = m_frameOwners[i].get();
         // Don't need to traverse up the tree for the first owner since no
         // script could have moved it.
-        if (!i || m_root->containsIncludingShadowDOM(owner))
+        if (!i || m_root.containsIncludingShadowDOM(owner))
             owner->disconnectContentFrame();
     }
 }
@@ -329,14 +330,14 @@
     assertConnectedSubrameCountIsConsistent(m_root);
 #endif
 
-    if (!m_root->connectedSubframeCount())
+    if (!m_root.connectedSubframeCount())
         return;
 
     if (policy == RootAndDescendants)
         collectFrameOwners(m_root);
     else {
-        for (Node* child = m_root->firstChild(); child; child = child->nextSibling())
-            collectFrameOwners(child);
+        for (Node* child = m_root.firstChild(); child; child = child->nextSibling())
+            collectFrameOwners(*child);
     }
 
     disconnectCollectedFrameOwners();
diff --git a/Source/core/dom/ContextLifecycleNotifier.cpp b/Source/core/dom/ContextLifecycleNotifier.cpp
index bf319bd..7b96fbe 100644
--- a/Source/core/dom/ContextLifecycleNotifier.cpp
+++ b/Source/core/dom/ContextLifecycleNotifier.cpp
@@ -34,7 +34,7 @@
 namespace WebCore {
 
 ContextLifecycleNotifier::ContextLifecycleNotifier(ExecutionContext* context)
-    : LifecycleNotifier(context)
+    : LifecycleNotifier<ExecutionContext>(context)
 {
 }
 
@@ -42,23 +42,23 @@
 {
 }
 
-void ContextLifecycleNotifier::addObserver(LifecycleObserver* observer)
+void ContextLifecycleNotifier::addObserver(ContextLifecycleNotifier::Observer* observer)
 {
     LifecycleNotifier::addObserver(observer);
 
     RELEASE_ASSERT(m_iterating != IteratingOverContextObservers);
-    if (observer->observerType() == LifecycleObserver::ActiveDOMObjectType) {
+    if (observer->observerType() == Observer::ActiveDOMObjectType) {
         RELEASE_ASSERT(m_iterating != IteratingOverActiveDOMObjects);
         m_activeDOMObjects.add(static_cast<ActiveDOMObject*>(observer));
     }
 }
 
-void ContextLifecycleNotifier::removeObserver(LifecycleObserver* observer)
+void ContextLifecycleNotifier::removeObserver(ContextLifecycleNotifier::Observer* observer)
 {
     LifecycleNotifier::removeObserver(observer);
 
     RELEASE_ASSERT(m_iterating != IteratingOverContextObservers);
-    if (observer->observerType() == LifecycleObserver::ActiveDOMObjectType) {
+    if (observer->observerType() == Observer::ActiveDOMObjectType) {
         RELEASE_ASSERT(m_iterating != IteratingOverActiveDOMObjects);
         m_activeDOMObjects.remove(static_cast<ActiveDOMObject*>(observer));
     }
diff --git a/Source/core/dom/ContextLifecycleNotifier.h b/Source/core/dom/ContextLifecycleNotifier.h
index 342b57f..93d8540 100644
--- a/Source/core/dom/ContextLifecycleNotifier.h
+++ b/Source/core/dom/ContextLifecycleNotifier.h
@@ -28,7 +28,7 @@
 #define ContextLifecycleNotifier_h
 
 #include "core/dom/ActiveDOMObject.h"
-#include "core/platform/LifecycleNotifier.h"
+#include "platform/LifecycleNotifier.h"
 #include "wtf/HashSet.h"
 #include "wtf/PassOwnPtr.h"
 
@@ -38,7 +38,7 @@
 class ContextLifecycleObserver;
 class ExecutionContext;
 
-class ContextLifecycleNotifier : public LifecycleNotifier {
+class ContextLifecycleNotifier : public LifecycleNotifier<ExecutionContext> {
 public:
     static PassOwnPtr<ContextLifecycleNotifier> create(ExecutionContext*);
 
@@ -48,8 +48,8 @@
 
     const ActiveDOMObjectSet& activeDOMObjects() const { return m_activeDOMObjects; }
 
-    virtual void addObserver(LifecycleObserver*) OVERRIDE;
-    virtual void removeObserver(LifecycleObserver*) OVERRIDE;
+    virtual void addObserver(Observer*) OVERRIDE;
+    virtual void removeObserver(Observer*) OVERRIDE;
 
     void notifyResumingActiveDOMObjects();
     void notifySuspendingActiveDOMObjects();
diff --git a/Source/core/dom/ContextLifecycleObserver.cpp b/Source/core/dom/ContextLifecycleObserver.cpp
index f10c7ca..b534648 100644
--- a/Source/core/dom/ContextLifecycleObserver.cpp
+++ b/Source/core/dom/ContextLifecycleObserver.cpp
@@ -31,8 +31,18 @@
 
 namespace WebCore {
 
+template<> void observerContext(ExecutionContext* context, LifecycleObserver<ExecutionContext>* observer)
+{
+    context->wasObservedBy(observer);
+}
+
+template<> void unobserverContext(ExecutionContext* context, LifecycleObserver<ExecutionContext>* observer)
+{
+    context->wasUnobservedBy(observer);
+}
+
 ContextLifecycleObserver::ContextLifecycleObserver(ExecutionContext* executionContext, Type type)
-    : LifecycleObserver(executionContext, type)
+    : LifecycleObserver<ExecutionContext>(executionContext, type)
 {
 }
 
@@ -40,9 +50,4 @@
 {
 }
 
-ExecutionContext* ContextLifecycleObserver::executionContext() const
-{
-    return static_cast<ExecutionContext*>(m_lifecycleContext);
-}
-
 } // namespace WebCore
diff --git a/Source/core/dom/ContextLifecycleObserver.h b/Source/core/dom/ContextLifecycleObserver.h
index 932b021..adde88c 100644
--- a/Source/core/dom/ContextLifecycleObserver.h
+++ b/Source/core/dom/ContextLifecycleObserver.h
@@ -27,17 +27,19 @@
 #ifndef ContextLifecycleObserver_h
 #define ContextLifecycleObserver_h
 
-#include "core/platform/LifecycleObserver.h"
+#include "platform/LifecycleContext.h"
 
 namespace WebCore {
 
 class ExecutionContext;
 
-class ContextLifecycleObserver : public LifecycleObserver {
+template<> void observerContext(ExecutionContext*, LifecycleObserver<ExecutionContext>*);
+template<> void unobserverContext(ExecutionContext*, LifecycleObserver<ExecutionContext>*);
+
+class ContextLifecycleObserver : public LifecycleObserver<ExecutionContext> {
 public:
     explicit ContextLifecycleObserver(ExecutionContext*, Type = GenericType);
-    ExecutionContext* executionContext() const;
-
+    ExecutionContext* executionContext() const { return lifecycleContext(); }
 protected:
     virtual ~ContextLifecycleObserver();
 };
diff --git a/Source/core/dom/DOMException.cpp b/Source/core/dom/DOMException.cpp
index 348a94e..ebb5b20 100644
--- a/Source/core/dom/DOMException.cpp
+++ b/Source/core/dom/DOMException.cpp
@@ -33,7 +33,7 @@
 
 namespace WebCore {
 
-static struct CoreException {
+static const struct CoreException {
     const char* const name;
     const char* const message;
     const int code;
diff --git a/Source/core/dom/DOMImplementation.cpp b/Source/core/dom/DOMImplementation.cpp
index b4690e4..756cbb1 100644
--- a/Source/core/dom/DOMImplementation.cpp
+++ b/Source/core/dom/DOMImplementation.cpp
@@ -321,43 +321,48 @@
 
 PassRefPtr<Document> DOMImplementation::createDocument(const String& type, Frame* frame, const KURL& url, bool inViewSourceMode)
 {
+    return createDocument(type, DocumentInit(url, frame), inViewSourceMode);
+}
+
+PassRefPtr<Document> DOMImplementation::createDocument(const String& type, const DocumentInit& init, bool inViewSourceMode)
+{
     if (inViewSourceMode)
-        return HTMLViewSourceDocument::create(DocumentInit(url, frame), type);
+        return HTMLViewSourceDocument::create(init, type);
 
     // Plugins cannot take HTML and XHTML from us, and we don't even need to initialize the plugin database for those.
     if (type == "text/html")
-        return HTMLDocument::create(DocumentInit(url, frame));
+        return HTMLDocument::create(init);
     if (type == "application/xhtml+xml")
-        return Document::createXHTML(DocumentInit(url, frame));
+        return Document::createXHTML(init);
 
     PluginData* pluginData = 0;
-    if (frame && frame->page() && frame->loader()->allowPlugins(NotAboutToInstantiatePlugin))
-        pluginData = frame->page()->pluginData();
+    if (init.frame() && init.frame()->page() && init.frame()->loader().allowPlugins(NotAboutToInstantiatePlugin))
+        pluginData = init.frame()->page()->pluginData();
 
     // PDF is one image type for which a plugin can override built-in support.
     // We do not want QuickTime to take over all image types, obviously.
     if ((type == "application/pdf" || type == "text/pdf") && pluginData && pluginData->supportsMimeType(type))
-        return PluginDocument::create(DocumentInit(url, frame));
+        return PluginDocument::create(init);
     if (Image::supportsType(type))
-        return ImageDocument::create(DocumentInit(url, frame));
+        return ImageDocument::create(init);
 
     // Check to see if the type can be played by our MediaPlayer, if so create a MediaDocument
     if (HTMLMediaElement::supportsType(ContentType(type)))
-        return MediaDocument::create(DocumentInit(url, frame));
+        return MediaDocument::create(init);
 
     // Everything else except text/plain can be overridden by plugins. In particular, Adobe SVG Viewer should be used for SVG, if installed.
     // Disallowing plug-ins to use text/plain prevents plug-ins from hijacking a fundamental type that the browser is expected to handle,
     // and also serves as an optimization to prevent loading the plug-in database in the common case.
     if (type != "text/plain" && pluginData && pluginData->supportsMimeType(type))
-        return PluginDocument::create(DocumentInit(url, frame));
+        return PluginDocument::create(init);
     if (isTextMIMEType(type))
-        return TextDocument::create(DocumentInit(url, frame));
+        return TextDocument::create(init);
     if (type == "image/svg+xml")
-        return SVGDocument::create(DocumentInit(url, frame));
+        return SVGDocument::create(init);
     if (isXMLMIMEType(type))
-        return Document::create(DocumentInit(url, frame));
+        return Document::create(init);
 
-    return HTMLDocument::create(DocumentInit(url, frame));
+    return HTMLDocument::create(init);
 }
 
 }
diff --git a/Source/core/dom/DOMImplementation.h b/Source/core/dom/DOMImplementation.h
index 153f4c4..5fb1f51 100644
--- a/Source/core/dom/DOMImplementation.h
+++ b/Source/core/dom/DOMImplementation.h
@@ -32,6 +32,7 @@
 
 class CSSStyleSheet;
 class Document;
+class DocumentInit;
 class DocumentType;
 class ExceptionState;
 class Frame;
@@ -62,6 +63,7 @@
 
     // Other methods (not part of DOM)
     static PassRefPtr<Document> createDocument(const String& MIMEType, Frame*, const KURL&, bool inViewSourceMode);
+    static PassRefPtr<Document> createDocument(const String& type, const DocumentInit&, bool inViewSourceMode);
 
     static bool isXMLMIMEType(const String& MIMEType);
     static bool isTextMIMEType(const String& MIMEType);
diff --git a/Source/core/dom/DOMURL.h b/Source/core/dom/DOMURL.h
index f197a11..1736990 100644
--- a/Source/core/dom/DOMURL.h
+++ b/Source/core/dom/DOMURL.h
@@ -42,7 +42,7 @@
 class ExecutionContext;
 class URLRegistrable;
 
-class DOMURL : public ScriptWrappable, public DOMURLUtils, public RefCounted<DOMURL> {
+class DOMURL FINAL : public ScriptWrappable, public DOMURLUtils, public RefCounted<DOMURL> {
 
 public:
     static PassRefPtr<DOMURL> create(const String& url, ExceptionState& es)
diff --git a/Source/core/dom/DOMURLUtils.h b/Source/core/dom/DOMURLUtils.h
index b7b128e..1987ecd 100644
--- a/Source/core/dom/DOMURLUtils.h
+++ b/Source/core/dom/DOMURLUtils.h
@@ -39,6 +39,7 @@
 public:
     virtual void setURL(const KURL&) = 0;
     virtual void setInput(const String&) = 0;
+    virtual ~DOMURLUtils() { };
 
     static void setHref(DOMURLUtils*, const String&);
 
diff --git a/Source/core/dom/DOMURLUtilsReadOnly.h b/Source/core/dom/DOMURLUtilsReadOnly.h
index 74f1d1c..9ddfd40 100644
--- a/Source/core/dom/DOMURLUtilsReadOnly.h
+++ b/Source/core/dom/DOMURLUtilsReadOnly.h
@@ -37,6 +37,7 @@
 public:
     virtual KURL url() const = 0;
     virtual String input() const = 0;
+    virtual ~DOMURLUtilsReadOnly() { };
 
     static String href(DOMURLUtilsReadOnly*);
 
diff --git a/Source/core/dom/Document.cpp b/Source/core/dom/Document.cpp
index 38504b3..2f97a3f 100644
--- a/Source/core/dom/Document.cpp
+++ b/Source/core/dom/Document.cpp
@@ -44,11 +44,11 @@
 #include "core/accessibility/AXObjectCache.h"
 #include "core/animation/AnimationClock.h"
 #include "core/animation/DocumentTimeline.h"
+#include "core/animation/css/TransitionTimeline.h"
 #include "core/css/CSSDefaultStyleSheets.h"
 #include "core/css/CSSFontSelector.h"
 #include "core/css/CSSStyleDeclaration.h"
 #include "core/css/CSSStyleSheet.h"
-#include "core/css/FontFaceSet.h"
 #include "core/css/MediaQueryMatcher.h"
 #include "core/css/StylePropertySet.h"
 #include "core/css/StyleSheetContents.h"
@@ -100,13 +100,11 @@
 #include "core/editing/Editor.h"
 #include "core/editing/FrameSelection.h"
 #include "core/events/BeforeUnloadEvent.h"
-#include "core/events/DocumentEventQueue.h"
 #include "core/events/Event.h"
 #include "core/events/EventFactory.h"
 #include "core/events/EventListener.h"
 #include "core/events/HashChangeEvent.h"
 #include "core/events/PageTransitionEvent.h"
-#include "core/events/PopStateEvent.h"
 #include "core/events/ScopedEventQueue.h"
 #include "core/events/ThreadLocalEventNames.h"
 #include "core/fetch/ResourceFetcher.h"
@@ -167,7 +165,6 @@
 #include "core/rendering/TextAutosizer.h"
 #include "core/svg/SVGDocumentExtensions.h"
 #include "core/svg/SVGStyleElement.h"
-#include "core/workers/SharedWorkerRepository.h"
 #include "core/xml/XSLTProcessor.h"
 #include "core/xml/parser/XMLDocumentParser.h"
 #include "platform/DateComponents.h"
@@ -197,8 +194,6 @@
 
 using namespace HTMLNames;
 
-static const double cDefaultIncrementalRenderingSuppressionTimeoutInSeconds = 5;
-
 static const unsigned cMaxWriteRecursionDepth = 21;
 
 // This amount of time must have elapsed before we will even consider scheduling a layout without a delay.
@@ -292,40 +287,37 @@
     return url.isEmpty() || url.isBlankURL();
 }
 
-static Widget* widgetForElement(Element* focusedElement)
+static Widget* widgetForElement(const Element& focusedElement)
 {
-    if (!focusedElement)
-        return 0;
-    RenderObject* renderer = focusedElement->renderer();
+    RenderObject* renderer = focusedElement.renderer();
     if (!renderer || !renderer->isWidget())
         return 0;
     return toRenderWidget(renderer)->widget();
 }
 
-static bool acceptsEditingFocus(Element* element)
+static bool acceptsEditingFocus(const Element& element)
 {
-    ASSERT(element);
-    ASSERT(element->rendererIsEditable());
+    ASSERT(element.rendererIsEditable());
 
-    return element->document().frame() && element->rootEditableElement();
+    return element.document().frame() && element.rootEditableElement();
 }
 
-static bool canAccessAncestor(const SecurityOrigin* activeSecurityOrigin, Frame* targetFrame)
+static bool canAccessAncestor(const SecurityOrigin& activeSecurityOrigin, Frame* targetFrame)
 {
     // targetFrame can be 0 when we're trying to navigate a top-level frame
     // that has a 0 opener.
     if (!targetFrame)
         return false;
 
-    const bool isLocalActiveOrigin = activeSecurityOrigin->isLocal();
-    for (Frame* ancestorFrame = targetFrame; ancestorFrame; ancestorFrame = ancestorFrame->tree()->parent()) {
+    const bool isLocalActiveOrigin = activeSecurityOrigin.isLocal();
+    for (Frame* ancestorFrame = targetFrame; ancestorFrame; ancestorFrame = ancestorFrame->tree().parent()) {
         Document* ancestorDocument = ancestorFrame->document();
         // FIXME: Should be an ASSERT? Frames should alway have documents.
         if (!ancestorDocument)
             return true;
 
         const SecurityOrigin* ancestorSecurityOrigin = ancestorDocument->securityOrigin();
-        if (activeSecurityOrigin->canAccess(ancestorSecurityOrigin))
+        if (activeSecurityOrigin.canAccess(ancestorSecurityOrigin))
             return true;
 
         // Allow file URL descendant navigation even when allowFileAccessFromFileURLs is false.
@@ -338,12 +330,12 @@
     return false;
 }
 
-static void printNavigationErrorMessage(Frame* frame, const KURL& activeURL, const char* reason)
+static void printNavigationErrorMessage(const Frame& 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";
+    String message = "Unsafe JavaScript attempt to initiate navigation for frame with URL '" + frame.document()->url().string() + "' from frame with URL '" + activeURL.string() + "'. " + reason + "\n";
 
     // FIXME: should we print to the console of the document performing the navigation instead?
-    frame->domWindow()->printErrorMessage(message);
+    frame.domWindow()->printErrorMessage(message);
 }
 
 uint64_t Document::s_globalTreeVersion = 0;
@@ -385,13 +377,13 @@
     , m_styleResolverAccessCount(0)
     , m_lastStyleResolverAccessCount(0)
     , m_didCalculateStyleResolver(false)
+    , m_hasNodesWithPlaceholderStyle(false)
+    , m_needsNotifyRemoveAllPendingStylesheet(false)
     , m_ignorePendingStylesheets(false)
     , m_evaluateMediaQueriesOnStyleRecalc(false)
-    , m_needsNotifyRemoveAllPendingStylesheet(false)
-    , m_hasNodesWithPlaceholderStyle(false)
     , m_pendingSheetLayout(NoLayoutWithPendingSheets)
     , m_frame(initializer.frame())
-    , m_domWindow(0)
+    , m_domWindow(m_frame ? m_frame->domWindow() : 0)
     , m_import(initializer.import())
     , m_activeParserCount(0)
     , m_contextFeatures(ContextFeatures::defaultSwitch())
@@ -437,7 +429,6 @@
     , m_isMobileDocument(false)
     , m_mayDisplaySeamlesslyWithParent(false)
     , m_renderView(0)
-    , m_eventQueue(DocumentEventQueue::create(this))
     , m_weakFactory(this)
     , m_contextDocument(initializer.contextDocument())
     , m_idAttributeName(idAttr)
@@ -447,13 +438,12 @@
     , m_referrerPolicy(ReferrerPolicyDefault)
     , m_directionSetOnDocumentElement(false)
     , m_writingModeSetOnDocumentElement(false)
-    , m_didAllowNavigationViaBeforeUnloadConfirmationPanel(false)
     , m_writeRecursionIsTooDeep(false)
     , m_writeRecursionDepth(0)
     , m_lastHandledUserGestureTimestamp(0)
+    , m_pendingTasksTimer(this, &Document::pendingTasksTimerFired)
     , m_textAutosizer(TextAutosizer::create(this))
     , m_registrationContext(initializer.registrationContext(this))
-    , m_pendingTasksTimer(this, &Document::pendingTasksTimerFired)
     , m_scheduledTasksAreSuspended(false)
     , m_sharedObjectPoolClearTimer(this, &Document::sharedObjectPoolClearTimerFired)
 #ifndef NDEBUG
@@ -461,8 +451,8 @@
 #endif
     , m_animationClock(AnimationClock::create())
     , m_timeline(DocumentTimeline::create(this))
+    , m_transitionTimeline(TransitionTimeline::create(this))
     , m_templateDocumentHost(0)
-    , m_fonts(0)
     , m_didAssociateFormControlsTimer(this, &Document::didAssociateFormControlsTimerFired)
 {
     setClient(this);
@@ -471,7 +461,7 @@
     if (m_frame) {
         provideContextFeaturesToDocumentFrom(this, m_frame->page());
 
-        m_fetcher = m_frame->loader()->activeDocumentLoader()->fetcher();
+        m_fetcher = m_frame->loader().activeDocumentLoader()->fetcher();
     }
 
     if (!m_fetcher)
@@ -620,21 +610,21 @@
         accessSVGExtensions()->pauseAnimations();
 
     m_lifecyle.advanceTo(DocumentLifecycle::Disposed);
-    lifecycleNotifier()->notifyDocumentWasDisposed();
+    lifecycleNotifier().notifyDocumentWasDisposed();
 }
 
-SelectorQueryCache* Document::selectorQueryCache()
+SelectorQueryCache& Document::selectorQueryCache()
 {
     if (!m_selectorQueryCache)
         m_selectorQueryCache = adoptPtr(new SelectorQueryCache());
-    return m_selectorQueryCache.get();
+    return *m_selectorQueryCache;
 }
 
-MediaQueryMatcher* Document::mediaQueryMatcher()
+MediaQueryMatcher& Document::mediaQueryMatcher()
 {
     if (!m_mediaQueryMatcher)
         m_mediaQueryMatcher = MediaQueryMatcher::create(this);
-    return m_mediaQueryMatcher.get();
+    return *m_mediaQueryMatcher;
 }
 
 void Document::setCompatibilityMode(CompatibilityMode mode)
@@ -643,7 +633,7 @@
         return;
     bool wasInQuirksMode = inQuirksMode();
     m_compatibilityMode = mode;
-    selectorQueryCache()->invalidate();
+    selectorQueryCache().invalidate();
     if (inQuirksMode() != wasInQuirksMode) {
         // All user stylesheets have to reparse using the different mode.
         m_styleEngine->clearPageUserSheet();
@@ -662,7 +652,7 @@
     ASSERT(!m_docType || !docType);
     m_docType = docType;
     if (m_docType) {
-        this->adoptIfNeeded(m_docType.get());
+        this->adoptIfNeeded(*m_docType);
         if (m_docType->publicId().startsWith("-//wapforum//dtd xhtml mobile 1.", /* caseSensitive */ false))
             m_isMobileDocument = true;
     }
@@ -952,7 +942,7 @@
 
         if (source->isFrameOwnerElement()) {
             HTMLFrameOwnerElement* frameOwnerElement = toHTMLFrameOwnerElement(source.get());
-            if (frame() && frame()->tree()->isDescendantOf(frameOwnerElement->contentFrame())) {
+            if (frame() && frame()->tree().isDescendantOf(frameOwnerElement->contentFrame())) {
                 es.throwUninformativeAndGenericDOMException(HierarchyRequestError);
                 return 0;
             }
@@ -964,7 +954,7 @@
         }
     }
 
-    this->adoptIfNeeded(source.get());
+    this->adoptIfNeeded(*source);
 
     return source;
 }
@@ -1092,7 +1082,7 @@
         if (!m_documentTiming.domLoading) {
             m_documentTiming.domLoading = monotonicallyIncreasingTime();
             if (RuntimeEnabledFeatures::webAnimationsEnabled())
-                m_timeline->setZeroTimeAsPerfTime(m_documentTiming.domLoading);
+                m_timeline->setZeroTime(m_documentTiming.domLoading);
         }
         break;
     case Interactive:
@@ -1109,6 +1099,11 @@
     dispatchEvent(Event::create(EventTypeNames::readystatechange));
 }
 
+bool Document::isLoadCompleted()
+{
+    return m_readyState == Complete;
+}
+
 String Document::encodingName() const
 {
     // TextEncoding::name() returns a char*, no need to allocate a new
@@ -1306,7 +1301,7 @@
 
     if (!m_frame || oldTitle == m_title)
         return;
-    m_frame->loader()->client()->dispatchDidReceiveTitle(m_title);
+    m_frame->loader().client()->dispatchDidReceiveTitle(m_title);
 }
 
 void Document::setTitle(const String& title)
@@ -1325,7 +1320,7 @@
     updateTitle(title);
 
     if (m_titleElement && isHTMLTitleElement(m_titleElement.get()))
-        toHTMLTitleElement(m_titleElement.get())->setText(title);
+        toHTMLTitleElement(m_titleElement)->setText(title);
 }
 
 void Document::setTitleElement(const String& title, Element* titleElement)
@@ -1629,12 +1624,10 @@
     }
 
     WritingMode rootWritingMode = documentElementStyle->writingMode();
-    bool isHorizontalWritingMode = documentElementStyle->isHorizontalWritingMode();
     TextDirection rootDirection = documentElementStyle->direction();
 
     if (!writingModeSetOnDocumentElement() && body()) {
         rootWritingMode = bodyStyle->writingMode();
-        isHorizontalWritingMode = bodyStyle->isHorizontalWritingMode();
     }
 
     if (!directionSetOnDocumentElement() && body())
@@ -1667,8 +1660,8 @@
     // we should not enter style recalc while painting
     RELEASE_ASSERT(!view() || !view()->isPainting());
 
-    // FIXME: We should never enter here without a FrameView or a RenderView.
-    if (!renderer() || !view())
+    // FIXME: We should never enter here without a FrameView or with an inactive document.
+    if (!isActive() || !view())
         return;
 
     if (m_inStyleRecalc)
@@ -1734,8 +1727,8 @@
         if (m_styleEngine->needsUpdateActiveStylesheetsOnStyleRecalc())
             setNeedsStyleRecalc();
 
-        // Pseudo element removal and similar may only work with these flags still set. Reset them after the style recalc.
         if (m_styleResolver) {
+            // Pseudo element removal and similar may only work with these flags still set. Reset them after the style recalc.
             m_styleEngine->resetCSSFeatureFlags(m_styleResolver->ruleFeatureSet());
             m_styleResolver->clearStyleSharingList();
         }
@@ -1750,7 +1743,7 @@
     // detached (for example, by setting display:none in the :hover style), schedule another mouseMove event
     // to check if any other elements ended up under the mouse pointer due to re-layout.
     if (hoverNode() && !hoverNode()->renderer() && frame())
-        frame()->eventHandler()->dispatchFakeMouseMoveEventSoon();
+        frame()->eventHandler().dispatchFakeMouseMoveEventSoon();
 }
 
 void Document::updateStyleIfNeeded()
@@ -1994,7 +1987,6 @@
         clearAXObjectCache();
 
     stopActiveDOMObjects();
-    m_eventQueue->close();
 
     // FIXME: consider using ActiveDOMObject.
     if (m_scriptedAnimationController)
@@ -2008,8 +2000,6 @@
 
     documentWillBecomeInactive();
 
-    SharedWorkerRepository::documentDetached(this);
-
     if (m_frame) {
         FrameView* view = m_frame->view();
         if (view)
@@ -2048,7 +2038,7 @@
     if (m_mediaQueryMatcher)
         m_mediaQueryMatcher->documentDestroyed();
 
-    lifecycleNotifier()->notifyDocumentWasDetached();
+    lifecycleNotifier().notifyDocumentWasDetached();
     m_lifecyle.advanceTo(DocumentLifecycle::Stopped);
 }
 
@@ -2171,8 +2161,8 @@
             }
         }
 
-        if (m_frame->loader()->state() == FrameStateProvisional)
-            m_frame->loader()->stopAllLoaders();
+        if (m_frame->loader().state() == FrameStateProvisional)
+            m_frame->loader().stopAllLoaders();
     }
 
     removeAllEventListeners();
@@ -2181,7 +2171,7 @@
         parser->setWasCreatedByScript(true);
 
     if (m_frame)
-        m_frame->loader()->didExplicitOpen();
+        m_frame->loader().didExplicitOpen();
     if (m_loadEventProgress != LoadEventInProgress && m_loadEventProgress != UnloadEventInProgress)
         m_loadEventProgress = LoadEventNotRun;
 }
@@ -2303,14 +2293,14 @@
         return;
     }
 
-    m_frame->loader()->checkCompleted();
+    m_frame->loader().checkCompleted();
 }
 
 void Document::implicitClose()
 {
     ASSERT(!inStyleRecalc());
 
-    bool wasLocationChangePending = frame() && frame()->navigationScheduler()->locationChangePending();
+    bool wasLocationChangePending = frame() && frame()->navigationScheduler().locationChangePending();
     bool doload = !parsing() && m_parser && !processingLoadEvent() && !wasLocationChangePending;
 
     // If the load was blocked because of a pending location change and the location change triggers a same document
@@ -2322,7 +2312,7 @@
 
     // The call to dispatchWindowLoadEvent can detach the DOMWindow and cause it (and its
     // attached Document) to be destroyed.
-    RefPtr<DOMWindow> protect(this->domWindow());
+    RefPtr<DOMWindow> protectedWindow(this->domWindow());
 
     m_loadEventProgress = LoadEventInProgress;
 
@@ -2334,7 +2324,7 @@
     detachParser();
 
     Frame* f = frame();
-    if (f && f->script()->canExecuteScripts(NotAboutToExecuteScript)) {
+    if (f && f->script().canExecuteScripts(NotAboutToExecuteScript)) {
         ImageLoader::dispatchPendingBeforeLoadEvents();
         ImageLoader::dispatchPendingLoadEvents();
         ImageLoader::dispatchPendingErrorEvents();
@@ -2349,12 +2339,11 @@
     if (svgExtensions())
         accessSVGExtensions()->dispatchSVGLoadEventToOutermostSVGElements();
 
-    dispatchWindowLoadEvent();
-    enqueuePageshowEvent(PageshowEventNotPersisted);
-    enqueuePopstateEvent(m_pendingStateObject ? m_pendingStateObject.release() : SerializedScriptValue::nullValue());
+    if (protectedWindow)
+        protectedWindow->documentWasClosed();
 
     if (frame()) {
-        frame()->loader()->client()->dispatchDidHandleOnloadEvents();
+        frame()->loader().client()->dispatchDidHandleOnloadEvents();
         loader()->applicationCacheHost()->stopDeferringEvents();
     }
 
@@ -2368,7 +2357,7 @@
     // fires. This will improve onload scores, and other browsers do it.
     // If they wanna cheat, we can too. -dwh
 
-    if (frame()->navigationScheduler()->locationChangePending() && elapsedTime() < cLayoutScheduleThreshold) {
+    if (frame()->navigationScheduler().locationChangePending() && elapsedTime() < cLayoutScheduleThreshold) {
         // Just bail out. Before or during the onload we were shifted to another page.
         // The old i-Bench suite does this. When this happens don't bother painting or laying out.
         m_loadEventProgress = LoadEventCompleted;
@@ -2413,7 +2402,7 @@
         accessSVGExtensions()->startAnimations();
 }
 
-bool Document::dispatchBeforeUnloadEvent(Chrome& chrome, Document* navigatingDocument)
+bool Document::dispatchBeforeUnloadEvent(Chrome& chrome, bool& didAllowNavigation)
 {
     if (!m_domWindow)
         return true;
@@ -2425,21 +2414,21 @@
 
     RefPtr<BeforeUnloadEvent> beforeUnloadEvent = BeforeUnloadEvent::create();
     m_loadEventProgress = BeforeUnloadEventInProgress;
-    dispatchWindowEvent(beforeUnloadEvent.get(), this);
+    m_domWindow->dispatchEvent(beforeUnloadEvent.get(), this);
     m_loadEventProgress = BeforeUnloadEventCompleted;
     if (!beforeUnloadEvent->defaultPrevented())
         defaultEventHandler(beforeUnloadEvent.get());
     if (beforeUnloadEvent->returnValue().isNull())
         return true;
 
-    if (navigatingDocument->m_didAllowNavigationViaBeforeUnloadConfirmationPanel) {
+    if (didAllowNavigation) {
         addConsoleMessage(JSMessageSource, ErrorMessageLevel, "Blocked attempt to show multiple 'beforeunload' confirmation panels for a single navigation.");
         return true;
     }
 
     String text = beforeUnloadEvent->returnValue();
     if (chrome.runBeforeUnloadConfirmPanel(text, m_frame)) {
-        navigatingDocument->m_didAllowNavigationViaBeforeUnloadConfirmationPanel = true;
+        didAllowNavigation = true;
         return true;
     }
     return false;
@@ -2457,21 +2446,22 @@
             toHTMLInputElement(currentFocusedElement)->endEditing();
         if (m_loadEventProgress < PageHideInProgress) {
             m_loadEventProgress = PageHideInProgress;
-            dispatchWindowEvent(PageTransitionEvent::create(EventTypeNames::pagehide, false), this);
+            if (DOMWindow* window = domWindow())
+                window->dispatchEvent(PageTransitionEvent::create(EventTypeNames::pagehide, false), this);
             if (!m_frame)
                 return;
 
             // The DocumentLoader (and thus its DocumentLoadTiming) might get destroyed
             // while dispatching the event, so protect it to prevent writing the end
             // time into freed memory.
-            RefPtr<DocumentLoader> documentLoader =  m_frame->loader()->provisionalDocumentLoader();
+            RefPtr<DocumentLoader> documentLoader =  m_frame->loader().provisionalDocumentLoader();
             m_loadEventProgress = UnloadEventInProgress;
             RefPtr<Event> unloadEvent(Event::create(EventTypeNames::unload));
             if (documentLoader && !documentLoader->timing()->unloadEventStart() && !documentLoader->timing()->unloadEventEnd()) {
                 DocumentLoadTiming* timing = documentLoader->timing();
                 ASSERT(timing->navigationStart());
                 timing->markUnloadEventStart();
-                dispatchWindowEvent(unloadEvent, this);
+                m_frame->domWindow()->dispatchEvent(unloadEvent, this);
                 timing->markUnloadEventEnd();
             } else {
                 m_frame->domWindow()->dispatchEvent(unloadEvent, m_frame->document());
@@ -2485,8 +2475,8 @@
         return;
 
     // Don't remove event listeners from a transitional empty document (see https://bugs.webkit.org/show_bug.cgi?id=28716 for more information).
-    bool keepEventListeners = m_frame->loader()->stateMachine()->isDisplayingInitialEmptyDocument() && m_frame->loader()->provisionalDocumentLoader()
-        && isSecureTransitionTo(m_frame->loader()->provisionalDocumentLoader()->url());
+    bool keepEventListeners = m_frame->loader().stateMachine()->isDisplayingInitialEmptyDocument() && m_frame->loader().provisionalDocumentLoader()
+        && isSecureTransitionTo(m_frame->loader().provisionalDocumentLoader()->url());
     if (!keepEventListeners)
         removeAllEventListeners();
 }
@@ -2593,7 +2583,7 @@
 {
     Page* p = page();
     if (!p)
-        return ExecutionContext::timerAlignmentInterval();
+        return DOMTimer::visiblePageAlignmentInterval();
     return p->timerAlignmentInterval();
 }
 
@@ -2636,7 +2626,7 @@
         // FIXME: Now that we don't support Objective-C this can probably be removed.
         m_baseURL = KURL(ParsedURLString, documentURI());
     }
-    selectorQueryCache()->invalidate();
+    selectorQueryCache().invalidate();
 
     if (!m_baseURL.isValid())
         m_baseURL = KURL();
@@ -2705,7 +2695,7 @@
 
 String Document::userAgent(const KURL& url) const
 {
-    return frame() ? frame()->loader()->userAgent(url) : String();
+    return frame() ? frame()->loader().userAgent(url) : String();
 }
 
 void Document::disableEval(const String& errorMessage)
@@ -2713,7 +2703,7 @@
     if (!frame())
         return;
 
-    frame()->script()->disableEval(errorMessage);
+    frame()->script().disableEval(errorMessage);
 }
 
 bool Document::canNavigate(Frame* targetFrame)
@@ -2728,21 +2718,24 @@
         return true;
 
     // Frame-busting is generally allowed, but blocked for sandboxed frames lacking the 'allow-top-navigation' flag.
-    if (!isSandboxed(SandboxTopNavigation) && targetFrame == m_frame->tree()->top())
+    if (!isSandboxed(SandboxTopNavigation) && targetFrame == m_frame->tree().top())
         return true;
 
     if (isSandboxed(SandboxNavigation)) {
-        if (targetFrame->tree()->isDescendantOf(m_frame))
+        if (targetFrame->tree().isDescendantOf(m_frame))
             return true;
 
         const char* reason = "The frame attempting navigation is sandboxed, and is therefore disallowed from navigating its ancestors.";
-        if (isSandboxed(SandboxTopNavigation) && targetFrame == m_frame->tree()->top())
+        if (isSandboxed(SandboxTopNavigation) && targetFrame == m_frame->tree().top())
             reason = "The frame attempting navigation of the top-level window is sandboxed, but the 'allow-top-navigation' flag is not set.";
 
-        printNavigationErrorMessage(targetFrame, url(), reason);
+        printNavigationErrorMessage(*targetFrame, url(), reason);
         return false;
     }
 
+    ASSERT(securityOrigin());
+    SecurityOrigin& origin = *securityOrigin();
+
     // This is the normal case. A document can navigate its decendant frames,
     // or, more generally, a document can navigate a frame if the document is
     // in the same origin as any of that frame's ancestors (in the frame
@@ -2750,7 +2743,7 @@
     //
     // See http://www.adambarth.com/papers/2008/barth-jackson-mitchell.pdf for
     // historical information about this security check.
-    if (canAccessAncestor(securityOrigin(), targetFrame))
+    if (canAccessAncestor(origin, targetFrame))
         return true;
 
     // Top-level frames are easier to navigate than other frames because they
@@ -2764,28 +2757,28 @@
     // some way related to the frame being navigate (e.g., by the "opener"
     // and/or "parent" relation). Requiring some sort of relation prevents a
     // document from navigating arbitrary, unrelated top-level frames.
-    if (!targetFrame->tree()->parent()) {
-        if (targetFrame == m_frame->loader()->opener())
+    if (!targetFrame->tree().parent()) {
+        if (targetFrame == m_frame->loader().opener())
             return true;
 
-        if (canAccessAncestor(securityOrigin(), targetFrame->loader()->opener()))
+        if (canAccessAncestor(origin, targetFrame->loader().opener()))
             return true;
     }
 
-    printNavigationErrorMessage(targetFrame, url(), "The frame attempting navigation is neither same-origin with the target, nor is it the target's parent or opener.");
+    printNavigationErrorMessage(*targetFrame, url(), "The frame attempting navigation is neither same-origin with the target, nor is it the target's parent or opener.");
     return false;
 }
 
 Frame* Document::findUnsafeParentScrollPropagationBoundary()
 {
     Frame* currentFrame = m_frame;
-    Frame* ancestorFrame = currentFrame->tree()->parent();
+    Frame* ancestorFrame = currentFrame->tree().parent();
 
     while (ancestorFrame) {
         if (!ancestorFrame->document()->securityOrigin()->canAccess(securityOrigin()))
             return currentFrame;
         currentFrame = ancestorFrame;
-        ancestorFrame = ancestorFrame->tree()->parent();
+        ancestorFrame = ancestorFrame->tree().parent();
     }
     return 0;
 }
@@ -2905,7 +2898,7 @@
         addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, message);
         return;
     }
-    m_frame->navigationScheduler()->scheduleRedirect(delay, refreshURL);
+    m_frame->navigationScheduler().scheduleRedirect(delay, refreshURL);
 }
 
 void Document::processHttpEquivSetCookie(const String& content)
@@ -2924,15 +2917,15 @@
     if (!frame)
         return;
 
-    FrameLoader* frameLoader = frame->loader();
+    FrameLoader& frameLoader = frame->loader();
     unsigned long requestIdentifier = loader()->mainResourceIdentifier();
-    if (frameLoader->shouldInterruptLoadForXFrameOptions(content, url(), requestIdentifier)) {
+    if (frameLoader.shouldInterruptLoadForXFrameOptions(content, url(), requestIdentifier)) {
         String message = "Refused to display '" + url().elidedString() + "' in a frame because it set 'X-Frame-Options' to '" + content + "'.";
-        frameLoader->stopAllLoaders();
+        frameLoader.stopAllLoaders();
         // Stopping the loader isn't enough, as we're already parsing the document; to honor the header's
         // intent, we must navigate away from the possibly partially-rendered document to a location that
         // doesn't inherit the parent's SecurityOrigin.
-        frame->navigationScheduler()->scheduleLocationChange(securityOrigin(), SecurityOrigin::urlWithUniqueSecurityOrigin(), String());
+        frame->navigationScheduler().scheduleLocationChange(securityOrigin(), SecurityOrigin::urlWithUniqueSecurityOrigin(), String());
         addConsoleMessageWithRequestIdentifier(SecurityMessageSource, ErrorMessageLevel, message, requestIdentifier);
     }
 }
@@ -3211,7 +3204,7 @@
         return;
 
     // Seamless child frames are expected to notify their seamless children recursively, so we only do direct children.
-    for (Frame* child = frame()->tree()->firstChild(); child; child = child->tree()->nextSibling()) {
+    for (Frame* child = frame()->tree().firstChild(); child; child = child->tree().nextSibling()) {
         Document* childDocument = child->document();
         if (childDocument->shouldDisplaySeamlesslyWithParent()) {
             ASSERT(childDocument->seamlessParentIFrame()->document() == this);
@@ -3273,7 +3266,7 @@
         return;
 
     if (frame())
-        frame()->eventHandler()->scheduleHoverStateUpdate();
+        frame()->eventHandler().scheduleHoverStateUpdate();
 }
 
 void Document::activeChainNodeDetached(Node* node)
@@ -3354,7 +3347,7 @@
         }
 
         if (view()) {
-            Widget* oldWidget = widgetForElement(oldFocusedElement.get());
+            Widget* oldWidget = widgetForElement(*oldFocusedElement);
             if (oldWidget)
                 oldWidget->setFocus(false);
             else
@@ -3368,7 +3361,7 @@
     }
 
     if (newFocusedElement && newFocusedElement->isFocusable()) {
-        if (newFocusedElement->isRootEditableElement() && !acceptsEditingFocus(newFocusedElement.get())) {
+        if (newFocusedElement->isRootEditableElement() && !acceptsEditingFocus(*newFocusedElement)) {
             // delegate blocks focus change
             focusChangeBlocked = true;
             goto SetFocusedElementDone;
@@ -3410,14 +3403,14 @@
         // eww, I suck. set the qt focus correctly
         // ### find a better place in the code for this
         if (view()) {
-            Widget* focusWidget = widgetForElement(m_focusedElement.get());
+            Widget* focusWidget = widgetForElement(*m_focusedElement);
             if (focusWidget) {
                 // Make sure a widget has the right size before giving it focus.
                 // Otherwise, we are testing edge cases of the Widget code.
                 // Specifically, in WebCore this does not work well for text fields.
                 updateLayout();
                 // Re-get the widget in case updating the layout changed things.
-                focusWidget = widgetForElement(m_focusedElement.get());
+                focusWidget = widgetForElement(*m_focusedElement);
             }
             if (focusWidget)
                 focusWidget->setFocus(true);
@@ -3506,6 +3499,7 @@
 
 void Document::nodeChildrenWillBeRemoved(ContainerNode* container)
 {
+    NoEventDispatchAssertion assertNoEventDispatch;
     if (!m_ranges.isEmpty()) {
         HashSet<Range*>::const_iterator end = m_ranges.end();
         for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
@@ -3520,7 +3514,7 @@
 
     if (Frame* frame = this->frame()) {
         for (Node* n = container->firstChild(); n; n = n->nextSibling()) {
-            frame->eventHandler()->nodeWillBeRemoved(n);
+            frame->eventHandler().nodeWillBeRemoved(n);
             frame->selection().nodeWillBeRemoved(n);
             frame->page()->dragCaretController().nodeWillBeRemoved(n);
         }
@@ -3540,7 +3534,7 @@
     }
 
     if (Frame* frame = this->frame()) {
-        frame->eventHandler()->nodeWillBeRemoved(n);
+        frame->eventHandler().nodeWillBeRemoved(n);
         frame->selection().nodeWillBeRemoved(n);
         frame->page()->dragCaretController().nodeWillBeRemoved(n);
     }
@@ -3616,30 +3610,11 @@
     return domWindow->getAttributeEventListener(eventType, isolatedWorld);
 }
 
-void Document::dispatchWindowEvent(PassRefPtr<Event> event,  PassRefPtr<EventTarget> target)
-{
-    ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
-    DOMWindow* domWindow = this->domWindow();
-    if (!domWindow)
-        return;
-    domWindow->dispatchEvent(event, target);
-}
-
 EventQueue* Document::eventQueue() const
 {
-    return m_eventQueue.get();
-}
-
-void Document::enqueueWindowEvent(PassRefPtr<Event> event)
-{
-    event->setTarget(domWindow());
-    m_eventQueue->enqueueEvent(event);
-}
-
-void Document::enqueueDocumentEvent(PassRefPtr<Event> event)
-{
-    event->setTarget(this);
-    m_eventQueue->enqueueEvent(event);
+    if (!m_domWindow)
+        return 0;
+    return m_domWindow->eventQueue();
 }
 
 void Document::scheduleAnimationFrameEvent(PassRefPtr<Event> event)
@@ -3665,15 +3640,6 @@
     return 0;
 }
 
-void Document::dispatchWindowLoadEvent()
-{
-    ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
-    DOMWindow* domWindow = this->domWindow();
-    if (!domWindow)
-        return;
-    domWindow->dispatchLoadEvent();
-}
-
 void Document::addMutationEventListenerTypeIfEnabled(ListenerType listenerType)
 {
     if (ContextFeatures::mutationEventsEnabled(this))
@@ -3711,7 +3677,7 @@
     } else if (eventType == EventTypeNames::webkitTransitionEnd || eventType == EventTypeNames::transitionend) {
         addListenerType(TRANSITIONEND_LISTENER);
     } else if (eventType == EventTypeNames::beforeload) {
-        if (m_frame && m_frame->script()->shouldBypassMainWorldContentSecurityPolicy()) {
+        if (m_frame && m_frame->script().shouldBypassMainWorldContentSecurityPolicy()) {
             UseCounter::count(*this, UseCounter::BeforeLoadEventInIsolatedWorld);
         } else {
             UseCounter::count(*this, UseCounter::BeforeLoadEvent);
@@ -3819,7 +3785,7 @@
     if (equalIgnoringCase(domain(), newDomain)) {
         securityOrigin()->setDomainFromDOM(newDomain);
         if (m_frame)
-            m_frame->script()->updateSecurityOrigin();
+            m_frame->script().updateSecurityOrigin();
         return;
     }
 
@@ -3849,7 +3815,7 @@
 
     securityOrigin()->setDomainFromDOM(newDomain);
     if (m_frame)
-        m_frame->script()->updateSecurityOrigin();
+        m_frame->script().updateSecurityOrigin();
 }
 
 // http://www.whatwg.org/specs/web-apps/current-work/#dom-document-lastmodified
@@ -4114,15 +4080,15 @@
 
 KURL Document::openSearchDescriptionURL()
 {
-    static const char* const openSearchMIMEType = "application/opensearchdescription+xml";
-    static const char* const openSearchRelation = "search";
+    static const char openSearchMIMEType[] = "application/opensearchdescription+xml";
+    static const char openSearchRelation[] = "search";
 
     // FIXME: Why do only top-level frames have openSearchDescriptionURLs?
-    if (!frame() || frame()->tree()->parent())
+    if (!frame() || frame()->tree().parent())
         return KURL();
 
     // FIXME: Why do we need to wait for FrameStateComplete?
-    if (frame()->loader()->state() != FrameStateComplete)
+    if (frame()->loader().state() != FrameStateComplete)
         return KURL();
 
     if (!head())
@@ -4180,7 +4146,7 @@
 void Document::setDesignMode(InheritedBool value)
 {
     m_designMode = value;
-    for (Frame* frame = m_frame; frame && frame->document(); frame = frame->tree()->traverseNext(m_frame))
+    for (Frame* frame = m_frame; frame && frame->document(); frame = frame->tree().traverseNext(m_frame))
         frame->document()->setNeedsStyleRecalc();
 }
 
@@ -4202,7 +4168,7 @@
 {
     if (!m_frame)
         return 0;
-    Frame* parent = m_frame->tree()->parent();
+    Frame* parent = m_frame->tree().parent();
     if (!parent)
         return 0;
     return parent->document();
@@ -4267,7 +4233,7 @@
 
 PassRefPtr<HTMLCollection> Document::ensureCachedCollection(CollectionType type)
 {
-    return ensureRareData().ensureNodeLists()->addCacheWithAtomicName<HTMLCollection>(this, type);
+    return ensureRareData().ensureNodeLists().addCacheWithAtomicName<HTMLCollection>(this, type);
 }
 
 PassRefPtr<HTMLCollection> Document::images()
@@ -4319,17 +4285,17 @@
 
 PassRefPtr<HTMLCollection> Document::all()
 {
-    return ensureRareData().ensureNodeLists()->addCacheWithAtomicName<HTMLAllCollection>(this, DocAll);
+    return ensureRareData().ensureNodeLists().addCacheWithAtomicName<HTMLAllCollection>(this, DocAll);
 }
 
 PassRefPtr<HTMLCollection> Document::windowNamedItems(const AtomicString& name)
 {
-    return ensureRareData().ensureNodeLists()->addCacheWithAtomicName<HTMLNameCollection>(this, WindowNamedItems, name);
+    return ensureRareData().ensureNodeLists().addCacheWithAtomicName<HTMLNameCollection>(this, WindowNamedItems, name);
 }
 
 PassRefPtr<HTMLCollection> Document::documentNamedItems(const AtomicString& name)
 {
-    return ensureRareData().ensureNodeLists()->addCacheWithAtomicName<HTMLNameCollection>(this, DocumentNamedItems, name);
+    return ensureRareData().ensureNodeLists().addCacheWithAtomicName<HTMLNameCollection>(this, DocumentNamedItems, name);
 }
 
 void Document::finishedParsing()
@@ -4358,7 +4324,7 @@
         // See https://bugs.webkit.org/show_bug.cgi?id=36864 starting around comment 35.
         updateStyleIfNeeded();
 
-        f->loader()->finishedParsing();
+        f->loader().finishedParsing();
 
         InspectorInstrumentation::domContentLoadedEventFired(f.get());
     }
@@ -4436,20 +4402,6 @@
     return m_useSecureKeyboardEntryWhenActive;
 }
 
-static bool isEligibleForSeamless(Document* parent, Document* child)
-{
-    // It should not matter what we return for the top-most document.
-    if (!parent)
-        return false;
-    if (parent->isSandboxed(SandboxSeamlessIframes))
-        return false;
-    if (child->isSrcdocDocument())
-        return true;
-    if (parent->securityOrigin()->canAccess(child->securityOrigin()))
-        return true;
-    return parent->securityOrigin()->canRequest(child->url());
-}
-
 void Document::initSecurityContext()
 {
     initSecurityContext(DocumentInit(m_url, m_frame, contextDocument(), m_import));
@@ -4496,15 +4448,14 @@
         }
     }
 
-    Document* parentDocument = ownerElement() ? &ownerElement()->document() : 0;
-    if (parentDocument && initializer.shouldTreatURLAsSrcdocDocument()) {
+    if (initializer.shouldTreatURLAsSrcdocDocument()) {
         m_isSrcdocDocument = true;
-        setBaseURLOverride(parentDocument->baseURL());
+        setBaseURLOverride(initializer.parentBaseURL());
     }
 
     // FIXME: What happens if we inherit the security origin? This check may need to be later.
     // <iframe seamless src="about:blank"> likely won't work as-is.
-    m_mayDisplaySeamlesslyWithParent = isEligibleForSeamless(parentDocument, this);
+    m_mayDisplaySeamlesslyWithParent = initializer.isSeamlessAllowedFor(this);
 
     if (!shouldInheritSecurityOriginFromOwner(m_url))
         return;
@@ -4512,8 +4463,7 @@
     // If we do not obtain a meaningful origin from the URL, then we try to
     // find one via the frame hierarchy.
 
-    Frame* ownerFrame = initializer.ownerFrame();
-    if (!ownerFrame) {
+    if (!initializer.owner()) {
         didFailToInitializeSecurityOrigin();
         return;
     }
@@ -4523,21 +4473,21 @@
         // but we're also sandboxed, the only thing we inherit is the ability
         // to load local resources. This lets about:blank iframes in file://
         // URL documents load images and other resources from the file system.
-        if (ownerFrame->document()->securityOrigin()->canLoadLocalResources())
+        if (initializer.owner()->securityOrigin()->canLoadLocalResources())
             securityOrigin()->grantLoadLocalResources();
         return;
     }
 
-    m_cookieURL = ownerFrame->document()->cookieURL();
+    m_cookieURL = initializer.owner()->cookieURL();
     // We alias the SecurityOrigins to match Firefox, see Bug 15313
     // https://bugs.webkit.org/show_bug.cgi?id=15313
-    setSecurityOrigin(ownerFrame->document()->securityOrigin());
+    setSecurityOrigin(initializer.owner()->securityOrigin());
 }
 
 void Document::initContentSecurityPolicy(const ContentSecurityPolicyResponseHeaders& headers)
 {
-    if (m_frame && m_frame->tree()->parent() && (shouldInheritSecurityOriginFromOwner(m_url) || isPluginDocument()))
-        contentSecurityPolicy()->copyStateFrom(m_frame->tree()->parent()->document()->contentSecurityPolicy());
+    if (m_frame && m_frame->tree().parent() && (shouldInheritSecurityOriginFromOwner(m_url) || isPluginDocument()))
+        contentSecurityPolicy()->copyStateFrom(m_frame->tree().parent()->document()->contentSecurityPolicy());
     contentSecurityPolicy()->didReceiveHeaders(headers);
 }
 
@@ -4552,7 +4502,7 @@
     // we also need to ask the owner document of the node.
     if (!m_frame)
         return false;
-    if (!m_frame->script()->canExecuteScripts(NotAboutToExecuteScript))
+    if (!m_frame->script().canExecuteScripts(NotAboutToExecuteScript))
         return false;
     if (node && node->document() != this && !node->document().allowInlineEventHandlers(node, listener, contextURL, contextLine))
         return false;
@@ -4569,16 +4519,22 @@
         return false;
     if (!node->document().frame() && !node->document().import())
         return false;
-    if (!contextDocument().get()->frame()->script()->canExecuteScripts(AboutToExecuteScript))
+    if (!contextDocument().get()->frame()->script().canExecuteScripts(AboutToExecuteScript))
         return false;
     return true;
 }
 
+void Document::updateSecurityOrigin(PassRefPtr<SecurityOrigin> origin)
+{
+    setSecurityOrigin(origin);
+    didUpdateSecurityOrigin();
+}
+
 void Document::didUpdateSecurityOrigin()
 {
     if (!m_frame)
         return;
-    m_frame->script()->updateSecurityOrigin();
+    m_frame->script().updateSecurityOrigin();
 }
 
 bool Document::isContextThread() const
@@ -4586,19 +4542,6 @@
     return isMainThread();
 }
 
-void Document::statePopped(PassRefPtr<SerializedScriptValue> stateObject)
-{
-    if (!frame())
-        return;
-
-    // Per step 11 of section 6.5.9 (history traversal) of the HTML5 spec, we
-    // defer firing of popstate until we're in the complete state.
-    if (m_readyState == Complete)
-        enqueuePopstateEvent(stateObject);
-    else
-        m_pendingStateObject = stateObject;
-}
-
 void Document::updateFocusAppearanceSoon(bool restorePreviousSelection)
 {
     m_updateFocusAppearanceRestoresSelection = restorePreviousSelection;
@@ -4678,6 +4621,11 @@
     m_haveExplicitlyDisabledDNSPrefetch = true;
 }
 
+void Document::reportBlockedScriptExecutionToInspector(const String& directiveText)
+{
+    InspectorInstrumentation::scriptExecutionBlockedByCSP(this, directiveText);
+}
+
 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);
@@ -4804,26 +4752,6 @@
         m_scriptedAnimationController->resume();
 }
 
-void Document::enqueuePageshowEvent(PageshowEventPersistence persisted)
-{
-    // FIXME: https://bugs.webkit.org/show_bug.cgi?id=36334 Pageshow event needs to fire asynchronously.
-    dispatchWindowEvent(PageTransitionEvent::create(EventTypeNames::pageshow, persisted), this);
-}
-
-void Document::enqueueHashchangeEvent(const String& oldURL, const String& newURL)
-{
-    enqueueWindowEvent(HashChangeEvent::create(oldURL, newURL));
-}
-
-void Document::enqueuePopstateEvent(PassRefPtr<SerializedScriptValue> stateObject)
-{
-    if (!ContextFeatures::pushStateEnabled(this))
-        return;
-
-    // FIXME: https://bugs.webkit.org/show_bug.cgi?id=36202 Popstate event needs to fire asynchronously
-    dispatchWindowEvent(PopStateEvent::create(stateObject, domWindow() ? domWindow()->history() : 0));
-}
-
 void Document::addToTopLayer(Element* element, const Element* before)
 {
     if (element->isInTopLayer())
@@ -4891,7 +4819,7 @@
 void Document::loadEventDelayTimerFired(Timer<Document>*)
 {
     if (frame())
-        frame()->loader()->checkCompleted();
+        frame()->loader().checkCompleted();
 }
 
 ScriptedAnimationController& Document::ensureScriptedAnimationController()
@@ -4974,7 +4902,7 @@
         scrollingCoordinator->touchEventTargetRectsDidChange(this);
     if (m_touchEventTargets->size())
         return;
-    for (const Frame* frame = page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
+    for (const Frame* frame = page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
         if (frame->document() && frame->document()->hasTouchEventHandlers())
             return;
     }
@@ -5021,7 +4949,7 @@
     if (!m_frame)
         return 0;
 
-    DocumentLoader* loader = m_frame->loader()->documentLoader();
+    DocumentLoader* loader = m_frame->loader().documentLoader();
     if (!loader)
         return 0;
 
@@ -5090,7 +5018,7 @@
     // http/tests/security/feed-urls-from-remote.html to timeout on Mac WK1
     // see http://webkit.org/b/110554 and http://webkit.org/b/110401
     loader()->checkLoadComplete();
-    frame()->loader()->checkLoadComplete();
+    frame()->loader().checkLoadComplete();
 }
 
 void Document::setContextFeatures(PassRefPtr<ContextFeatures> features)
@@ -5292,13 +5220,6 @@
     return *m_templateDocument.get();
 }
 
-FontFaceSet* Document::fonts()
-{
-    if (!m_fonts)
-        m_fonts = FontFaceSet::create(this);
-    return m_fonts.get();
-}
-
 void Document::didAssociateFormControl(Element* element)
 {
     if (!frame() || !frame()->page())
@@ -5326,14 +5247,14 @@
     return m_frame ? m_frame->devicePixelRatio() : 1.0;
 }
 
-PassOwnPtr<LifecycleNotifier> Document::createLifecycleNotifier()
+PassOwnPtr<LifecycleNotifier<Document> > Document::createLifecycleNotifier()
 {
     return DocumentLifecycleNotifier::create(this);
 }
 
-DocumentLifecycleNotifier* Document::lifecycleNotifier()
+DocumentLifecycleNotifier& Document::lifecycleNotifier()
 {
-    return static_cast<DocumentLifecycleNotifier*>(ExecutionContext::lifecycleNotifier());
+    return static_cast<DocumentLifecycleNotifier&>(LifecycleContext<Document>::lifecycleNotifier());
 }
 
 void Document::removedStyleSheet(StyleSheet* sheet, RecalcStyleTime when, StyleResolverUpdateMode updateMode)
diff --git a/Source/core/dom/Document.h b/Source/core/dom/Document.h
index c82c6d8..12e5c3f 100644
--- a/Source/core/dom/Document.h
+++ b/Source/core/dom/Document.h
@@ -44,7 +44,6 @@
 #include "core/dom/UserActionElementSet.h"
 #include "core/dom/ViewportDescription.h"
 #include "core/dom/custom/CustomElement.h"
-#include "core/events/DocumentEventQueue.h"
 #include "core/html/CollectionType.h"
 #include "core/page/FocusDirection.h"
 #include "core/page/PageVisibilityState.h"
@@ -81,7 +80,6 @@
 class DOMWrapperWorld;
 class Database;
 class DatabaseThread;
-class DocumentEventQueue;
 class DocumentFragment;
 class DocumentLifecycleNotifier;
 class DocumentLifecycleObserver;
@@ -168,11 +166,6 @@
 
 typedef int ExceptionCode;
 
-enum PageshowEventPersistence {
-    PageshowEventNotPersisted = 0,
-    PageshowEventPersisted = 1
-};
-
 enum RecalcStyleTime {
     RecalcStyleImmediately, // synchronous
     RecalcStyleDeferred // asynchronous
@@ -212,7 +205,8 @@
 
 typedef unsigned char DocumentClassFlags;
 
-class Document : public ContainerNode, public TreeScope, public ExecutionContext, public ExecutionContextClient, public DocumentSupplementable {
+class Document : public ContainerNode, public TreeScope, public SecurityContext, public ExecutionContext, public ExecutionContextClient
+    , public DocumentSupplementable, public LifecycleContext<Document> {
 public:
     static PassRefPtr<Document> create(const DocumentInit& initializer = DocumentInit())
     {
@@ -224,94 +218,39 @@
     }
     virtual ~Document();
 
-    MediaQueryMatcher* mediaQueryMatcher();
+    MediaQueryMatcher& mediaQueryMatcher();
 
     using ContainerNode::ref;
     using ContainerNode::deref;
+    using SecurityContext::securityOrigin;
+    using SecurityContext::contentSecurityPolicy;
+    using ExecutionContextClient::addConsoleMessage;
 
     virtual bool canContainRangeEndPoint() const { return true; }
 
-    SelectorQueryCache* selectorQueryCache();
+    SelectorQueryCache& selectorQueryCache();
 
     // DOM methods & attributes for Document
 
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(abort);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecopy);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecut);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(beforepaste);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(blur);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(cancel);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(canplay);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(canplaythrough);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(change);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(click);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(close);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(contextmenu);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(copy);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(cuechange);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(cut);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(dblclick);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(drag);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(dragend);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(dragenter);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(dragleave);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(dragover);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(dragstart);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(drop);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(durationchange);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(emptied);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(ended);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(error);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(focus);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(input);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(invalid);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(keydown);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(keypress);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(keyup);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(load);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(loadeddata);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(loadedmetadata);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(loadstart);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(mousedown);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseenter);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseleave);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(mousemove);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseout);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseover);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseup);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(mousewheel);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(paste);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(pause);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(play);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(playing);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(progress);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(ratechange);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(readystatechange);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(reset);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(scroll);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(search);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(securitypolicyviolation);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(seeked);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(seeking);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(select);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(selectionchange);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(selectstart);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(show);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(stalled);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(submit);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(suspend);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(timeupdate);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(touchcancel);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(touchend);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(touchmove);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(touchstart);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(volumechange);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(waiting);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitfullscreenchange);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitfullscreenerror);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitpointerlockchange);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitpointerlockerror);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitvisibilitychange);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(wheel);
 
     bool shouldMergeWithLegacyDescription(ViewportDescription::Type);
@@ -569,7 +508,7 @@
     // implicitClose() actually does the work of closing the input stream.
     void implicitClose();
 
-    bool dispatchBeforeUnloadEvent(Chrome&, Document* navigatingDocument);
+    bool dispatchBeforeUnloadEvent(Chrome&, bool&);
     void dispatchUnloadEvents();
 
     enum PageDismissalType {
@@ -641,6 +580,8 @@
         Complete
     };
     void setReadyState(ReadyState);
+    bool isLoadCompleted();
+
     void setParsing(bool);
     bool parsing() const { return m_bParsing; }
     int minimumLayoutDelay();
@@ -650,7 +591,7 @@
     int elapsedTime() const;
 
     TextLinkColors& textLinkColors() { return m_textLinkColors; }
-    VisitedLinkState* visitedLinkState() const { return m_visitedLinkState.get(); }
+    VisitedLinkState& visitedLinkState() const { return *m_visitedLinkState; }
 
     MouseEventWithHitTestResults prepareMouseEvent(const HitTestRequest&, const LayoutPoint&, const PlatformMouseEvent&);
 
@@ -715,13 +656,12 @@
     void didMergeTextNodes(Text* oldNode, unsigned offset);
     void didSplitTextNode(Text* oldNode);
 
-    void setDOMWindow(DOMWindow* domWindow) { m_domWindow = domWindow; }
+    void clearDOMWindow() { m_domWindow = 0; }
     DOMWindow* domWindow() const { return m_domWindow; }
 
     // Helper functions for forwarding DOMWindow event related tasks to the DOMWindow if it exists.
     void setWindowAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, DOMWrapperWorld* isolatedWorld = 0);
     EventListener* getWindowAttributeEventListener(const AtomicString& eventType, DOMWrapperWorld* isolatedWorld);
-    void dispatchWindowEvent(PassRefPtr<Event>, PassRefPtr<EventTarget> = 0);
 
     PassRefPtr<Event> createEvent(const String& eventType, ExceptionState&);
 
@@ -950,11 +890,6 @@
     bool containsValidityStyleRules() const { return m_containsValidityStyleRules; }
     void setContainsValidityStyleRules() { m_containsValidityStyleRules = true; }
 
-    void enqueueWindowEvent(PassRefPtr<Event>);
-    void enqueueDocumentEvent(PassRefPtr<Event>);
-    void enqueuePageshowEvent(PageshowEventPersistence);
-    void enqueueHashchangeEvent(const String& oldURL, const String& newURL);
-    void enqueuePopstateEvent(PassRefPtr<SerializedScriptValue> stateObject);
     void enqueueScrollEventForNode(Node*);
     void scheduleAnimationFrameEvent(PassRefPtr<Event>);
 
@@ -1042,6 +977,7 @@
 
     AnimationClock& animationClock() { return *m_animationClock; }
     DocumentTimeline* timeline() const { return m_timeline.get(); }
+    DocumentTimeline* transitionTimeline() const { return m_transitionTimeline.get(); }
 
     void addToTopLayer(Element*, const Element* before = 0);
     void removeFromTopLayer(Element*);
@@ -1060,9 +996,7 @@
     virtual DOMWindow* executingWindow() OVERRIDE { return domWindow(); }
     virtual void userEventWasHandled() OVERRIDE { resetLastHandledUserGestureTimestamp(); }
 
-    // Can never return null.
-    FontFaceSet* fonts();
-    DocumentLifecycleNotifier* lifecycleNotifier();
+    DocumentLifecycleNotifier& lifecycleNotifier();
     bool isActive() const { return m_lifecyle.state() == DocumentLifecycle::Active; }
 
     enum HttpRefreshType {
@@ -1071,6 +1005,9 @@
     };
     void maybeHandleHttpRefresh(const String&, HttpRefreshType);
 
+    void updateSecurityOrigin(PassRefPtr<SecurityOrigin>);
+    PassOwnPtr<LifecycleNotifier<Document> > createLifecycleNotifier();
+
 protected:
     Document(const DocumentInit&, DocumentClassFlags = DefaultDocumentClass);
 
@@ -1087,6 +1024,7 @@
     friend class IgnoreDestructiveWriteCountIncrementer;
 
     ScriptedAnimationController& ensureScriptedAnimationController();
+    virtual SecurityContext& securityContext() OVERRIDE { return *this; }
     virtual EventQueue* eventQueue() const FINAL;
 
     void updateDistributionIfNeeded();
@@ -1105,11 +1043,11 @@
 
     virtual void refExecutionContext() { ref(); }
     virtual void derefExecutionContext() { deref(); }
-    virtual PassOwnPtr<LifecycleNotifier> createLifecycleNotifier() OVERRIDE;
 
     virtual const KURL& virtualURL() const; // Same as url(), but needed for ExecutionContext to implement it without a performance loss for direct calls.
     virtual KURL virtualCompleteURL(const String&) const; // Same as completeURL() for the same reason as above.
 
+    virtual void reportBlockedScriptExecutionToInspector(const String& directiveText) OVERRIDE;
     virtual void addMessage(MessageSource, MessageLevel, const String& message, const String& sourceURL, unsigned lineNumber, ScriptState*);
     void internalAddMessage(MessageSource, MessageLevel, const String& message, const String& sourceURL, unsigned lineNumber, PassRefPtr<ScriptCallStack>, ScriptState*);
 
@@ -1238,7 +1176,7 @@
     OwnPtr<FormController> m_formController;
 
     TextLinkColors m_textLinkColors;
-    OwnPtr<VisitedLinkState> m_visitedLinkState;
+    const OwnPtr<VisitedLinkState> m_visitedLinkState;
 
     bool m_loadingSheet;
     bool m_visuallyOrdered;
@@ -1271,7 +1209,6 @@
 
     LoadEventProgress m_loadEventProgress;
 
-    RefPtr<SerializedScriptValue> m_pendingStateObject;
     double m_startTime;
     bool m_overMinimumLayoutThreshold;
 
@@ -1322,7 +1259,6 @@
     bool m_mayDisplaySeamlesslyWithParent;
 
     RenderView* m_renderView;
-    RefPtr<DocumentEventQueue> m_eventQueue;
 
     WeakPtrFactory<Document> m_weakFactory;
     WeakPtr<Document> m_contextDocument;
@@ -1343,9 +1279,6 @@
 
     bool m_directionSetOnDocumentElement;
     bool m_writingModeSetOnDocumentElement;
-
-    bool m_didAllowNavigationViaBeforeUnloadConfirmationPanel;
-
     DocumentTiming m_documentTiming;
     RefPtr<MediaQueryMatcher> m_mediaQueryMatcher;
     bool m_writeRecursionIsTooDeep;
@@ -1384,12 +1317,11 @@
 
     OwnPtr<AnimationClock> m_animationClock;
     RefPtr<DocumentTimeline> m_timeline;
+    RefPtr<DocumentTimeline> m_transitionTimeline;
 
     RefPtr<Document> m_templateDocument;
     Document* m_templateDocumentHost; // Manually managed weakref (backpointer from m_templateDocument).
 
-    RefPtr<FontFaceSet> m_fonts;
-
     Timer<Document> m_didAssociateFormControlsTimer;
     HashSet<RefPtr<Element> > m_associatedFormControls;
 };
diff --git a/Source/core/dom/Document.idl b/Source/core/dom/Document.idl
index 75fe4a7..ba1e205 100644
--- a/Source/core/dom/Document.idl
+++ b/Source/core/dom/Document.idl
@@ -167,8 +167,6 @@
 
     [RuntimeEnabled=CSSRegions] WebKitNamedFlowCollection webkitGetNamedFlows();
 
-    [RuntimeEnabled=FontLoadEvents] readonly attribute FontFaceSet fonts;
-
     // Event handler attributes
     attribute EventHandler onbeforecopy;
     attribute EventHandler onbeforecut;
diff --git a/Source/core/dom/DocumentInit.cpp b/Source/core/dom/DocumentInit.cpp
index a52dfd3..90b4dd9 100644
--- a/Source/core/dom/DocumentInit.cpp
+++ b/Source/core/dom/DocumentInit.cpp
@@ -31,14 +31,41 @@
 #include "RuntimeEnabledFeatures.h"
 #include "core/dom/Document.h"
 #include "core/dom/custom/CustomElementRegistrationContext.h"
+#include "core/html/HTMLFrameOwnerElement.h"
 #include "core/html/HTMLImportsController.h"
 #include "core/frame/Frame.h"
 
 namespace WebCore {
 
+static Document* parentDocument(Frame* frame)
+{
+    if (!frame)
+        return 0;
+    Element* ownerElement = frame->ownerElement();
+    if (!ownerElement)
+        return 0;
+    return &ownerElement->document();
+}
+
+
+static Document* ownerDocument(Frame* frame)
+{
+    if (!frame)
+        return 0;
+
+    Frame* ownerFrame = frame->tree().parent();
+    if (!ownerFrame)
+        ownerFrame = frame->loader().opener();
+    if (!ownerFrame)
+        return 0;
+    return ownerFrame->document();
+}
+
 DocumentInit::DocumentInit(const KURL& url, Frame* frame, WeakPtr<Document> contextDocument, HTMLImport* import)
     : m_url(url)
     , m_frame(frame)
+    , m_parent(parentDocument(frame))
+    , m_owner(ownerDocument(frame))
     , m_contextDocument(contextDocument)
     , m_import(import)
 {
@@ -47,6 +74,8 @@
 DocumentInit::DocumentInit(const DocumentInit& other)
     : m_url(other.m_url)
     , m_frame(other.m_frame)
+    , m_parent(other.m_parent)
+    , m_owner(other.m_owner)
     , m_contextDocument(other.m_contextDocument)
     , m_import(other.m_import)
     , m_registrationContext(other.m_registrationContext)
@@ -65,8 +94,20 @@
 
 bool DocumentInit::shouldTreatURLAsSrcdocDocument() const
 {
-    ASSERT(m_frame);
-    return m_frame->loader()->shouldTreatURLAsSrcdocDocument(m_url);
+    return m_parent && m_frame->loader().shouldTreatURLAsSrcdocDocument(m_url);
+}
+
+bool DocumentInit::isSeamlessAllowedFor(Document* child) const
+{
+    if (!m_parent)
+        return false;
+    if (m_parent->isSandboxed(SandboxSeamlessIframes))
+        return false;
+    if (child->isSrcdocDocument())
+        return true;
+    if (m_parent->securityOrigin()->canAccess(child->securityOrigin()))
+        return true;
+    return m_parent->securityOrigin()->canRequest(child->url());
 }
 
 Frame* DocumentInit::frameForSecurityContext() const
@@ -81,7 +122,7 @@
 SandboxFlags DocumentInit::sandboxFlags() const
 {
     ASSERT(frameForSecurityContext());
-    return frameForSecurityContext()->loader()->effectiveSandboxFlags();
+    return frameForSecurityContext()->loader().effectiveSandboxFlags();
 }
 
 Settings* DocumentInit::settings() const
@@ -90,15 +131,9 @@
     return frameForSecurityContext()->settings();
 }
 
-Frame* DocumentInit::ownerFrame() const
+KURL DocumentInit::parentBaseURL() const
 {
-    if (!m_frame)
-        return 0;
-
-    Frame* ownerFrame = m_frame->tree()->parent();
-    if (!ownerFrame)
-        ownerFrame = m_frame->loader()->opener();
-    return ownerFrame;
+    return m_parent->baseURL();
 }
 
 DocumentInit& DocumentInit::withRegistrationContext(CustomElementRegistrationContext* registrationContext)
diff --git a/Source/core/dom/DocumentInit.h b/Source/core/dom/DocumentInit.h
index ee7d4b1..136d400 100644
--- a/Source/core/dom/DocumentInit.h
+++ b/Source/core/dom/DocumentInit.h
@@ -56,12 +56,17 @@
     bool hasSecurityContext() const { return frameForSecurityContext(); }
     bool shouldTreatURLAsSrcdocDocument() const;
     bool shouldSetURL() const;
+    bool isSeamlessAllowedFor(Document* child) const;
     SandboxFlags sandboxFlags() const;
 
+    Document* parent() const { return m_parent.get(); }
+    Document* owner() const { return m_owner.get(); }
+    KURL parentBaseURL() const;
     Frame* ownerFrame() const;
     Settings* settings() const;
 
     DocumentInit& withRegistrationContext(CustomElementRegistrationContext*);
+
     PassRefPtr<CustomElementRegistrationContext> registrationContext(Document*) const;
     WeakPtr<Document> contextDocument() const;
 
@@ -72,6 +77,8 @@
 
     KURL m_url;
     Frame* m_frame;
+    RefPtr<Document> m_parent;
+    RefPtr<Document> m_owner;
     WeakPtr<Document> m_contextDocument;
     HTMLImport* m_import;
     RefPtr<CustomElementRegistrationContext> m_registrationContext;
diff --git a/Source/core/dom/DocumentLifecycleNotifier.cpp b/Source/core/dom/DocumentLifecycleNotifier.cpp
index ddf28a2..36c7997 100644
--- a/Source/core/dom/DocumentLifecycleNotifier.cpp
+++ b/Source/core/dom/DocumentLifecycleNotifier.cpp
@@ -32,29 +32,29 @@
 
 namespace WebCore {
 
-DocumentLifecycleNotifier::DocumentLifecycleNotifier(ExecutionContext* context)
-    : ContextLifecycleNotifier(context)
+DocumentLifecycleNotifier::DocumentLifecycleNotifier(Document* document)
+    : LifecycleNotifier<Document>(document)
 {
 }
 
-void DocumentLifecycleNotifier::addObserver(LifecycleObserver* observer)
+void DocumentLifecycleNotifier::addObserver(DocumentLifecycleNotifier::Observer* observer)
 {
-    if (observer->observerType() == LifecycleObserver::DocumentLifecycleObserverType) {
+    if (observer->observerType() == Observer::DocumentLifecycleObserverType) {
         RELEASE_ASSERT(m_iterating != IteratingOverDocumentObservers);
         m_documentObservers.add(static_cast<DocumentLifecycleObserver*>(observer));
     }
 
-    ContextLifecycleNotifier::addObserver(observer);
+    LifecycleNotifier<Document>::addObserver(observer);
 }
 
-void DocumentLifecycleNotifier::removeObserver(LifecycleObserver* observer)
+void DocumentLifecycleNotifier::removeObserver(DocumentLifecycleNotifier::Observer* observer)
 {
-    if (observer->observerType() == LifecycleObserver::DocumentLifecycleObserverType) {
+    if (observer->observerType() == Observer::DocumentLifecycleObserverType) {
         RELEASE_ASSERT(m_iterating != IteratingOverDocumentObservers);
         m_documentObservers.remove(static_cast<DocumentLifecycleObserver*>(observer));
     }
 
-    ContextLifecycleNotifier::removeObserver(observer);
+    LifecycleNotifier<Document>::removeObserver(observer);
 }
 
 } // namespace WebCore
diff --git a/Source/core/dom/DocumentLifecycleNotifier.h b/Source/core/dom/DocumentLifecycleNotifier.h
index 6c730eb..07888bd 100644
--- a/Source/core/dom/DocumentLifecycleNotifier.h
+++ b/Source/core/dom/DocumentLifecycleNotifier.h
@@ -26,33 +26,34 @@
 #ifndef DocumentLifecycleNotifier_h
 #define DocumentLifecycleNotifier_h
 
-#include "core/dom/ContextLifecycleNotifier.h"
 #include "core/dom/DocumentLifecycleObserver.h"
 #include "wtf/PassOwnPtr.h"
 #include "wtf/TemporaryChange.h"
 
 namespace WebCore {
 
-class DocumentLifecycleNotifier : public ContextLifecycleNotifier {
+class Document;
+
+class DocumentLifecycleNotifier : public LifecycleNotifier<Document> {
 public:
-    static PassOwnPtr<DocumentLifecycleNotifier> create(ExecutionContext*);
+    static PassOwnPtr<DocumentLifecycleNotifier> create(Document*);
 
     void notifyDocumentWasDetached();
     void notifyDocumentWasDisposed();
 
-    virtual void addObserver(LifecycleObserver*) OVERRIDE;
-    virtual void removeObserver(LifecycleObserver*) OVERRIDE;
+    virtual void addObserver(Observer*) OVERRIDE;
+    virtual void removeObserver(Observer*) OVERRIDE;
 
 private:
-    explicit DocumentLifecycleNotifier(ExecutionContext*);
+    explicit DocumentLifecycleNotifier(Document*);
 
     typedef HashSet<DocumentLifecycleObserver*> DocumentObserverSet;
     DocumentObserverSet m_documentObservers;
 };
 
-inline PassOwnPtr<DocumentLifecycleNotifier> DocumentLifecycleNotifier::create(ExecutionContext* context)
+inline PassOwnPtr<DocumentLifecycleNotifier> DocumentLifecycleNotifier::create(Document* document)
 {
-    return adoptPtr(new DocumentLifecycleNotifier(context));
+    return adoptPtr(new DocumentLifecycleNotifier(document));
 }
 
 inline void DocumentLifecycleNotifier::notifyDocumentWasDetached()
diff --git a/Source/core/dom/DocumentLifecycleObserver.cpp b/Source/core/dom/DocumentLifecycleObserver.cpp
index 413d1ce..b0abbfd 100644
--- a/Source/core/dom/DocumentLifecycleObserver.cpp
+++ b/Source/core/dom/DocumentLifecycleObserver.cpp
@@ -31,8 +31,18 @@
 
 namespace WebCore {
 
+template<> void observerContext(Document* context, LifecycleObserver<Document>* observer)
+{
+    static_cast<LifecycleContext<Document>*>(context)->wasObservedBy(observer);
+}
+
+template<> void unobserverContext(Document* context, LifecycleObserver<Document>* observer)
+{
+    static_cast<LifecycleContext<Document>*>(context)->wasUnobservedBy(observer);
+}
+
 DocumentLifecycleObserver::DocumentLifecycleObserver(Document* document)
-    : ContextLifecycleObserver(document, DocumentLifecycleObserverType)
+    : LifecycleObserver<Document>(document, DocumentLifecycleObserverType)
 {
 }
 
diff --git a/Source/core/dom/DocumentLifecycleObserver.h b/Source/core/dom/DocumentLifecycleObserver.h
index 3005f72..47233c5 100644
--- a/Source/core/dom/DocumentLifecycleObserver.h
+++ b/Source/core/dom/DocumentLifecycleObserver.h
@@ -26,14 +26,16 @@
 #ifndef DocumentLifecycleObserver_h
 #define DocumentLifecycleObserver_h
 
-#include "core/dom/ContextLifecycleNotifier.h"
-#include "core/dom/ContextLifecycleObserver.h"
+#include "platform/LifecycleContext.h"
 
 namespace WebCore {
 
 class Document;
 
-class DocumentLifecycleObserver : public ContextLifecycleObserver {
+template<> void observerContext(Document*, LifecycleObserver<Document>*);
+template<> void unobserverContext(Document*, LifecycleObserver<Document>*);
+
+class DocumentLifecycleObserver : public LifecycleObserver<Document> {
 public:
     explicit DocumentLifecycleObserver(Document*);
     virtual ~DocumentLifecycleObserver();
diff --git a/Source/core/dom/DocumentOrderedList.cpp b/Source/core/dom/DocumentOrderedList.cpp
index 62802cc..49520e6 100644
--- a/Source/core/dom/DocumentOrderedList.cpp
+++ b/Source/core/dom/DocumentOrderedList.cpp
@@ -64,9 +64,9 @@
     m_nodes.add(node);
 }
 
-void DocumentOrderedList::remove(Node* node)
+void DocumentOrderedList::remove(const Node* node)
 {
-    m_nodes.remove(node);
+    m_nodes.remove(const_cast<Node*>(node));
 }
 
 }
diff --git a/Source/core/dom/DocumentOrderedList.h b/Source/core/dom/DocumentOrderedList.h
index 8dde172..133a34d 100644
--- a/Source/core/dom/DocumentOrderedList.h
+++ b/Source/core/dom/DocumentOrderedList.h
@@ -42,7 +42,7 @@
 
     void add(Node*);
     void parserAdd(Node*);
-    void remove(Node*);
+    void remove(const Node*);
     bool isEmpty() const { return m_nodes.isEmpty(); }
     void clear() { m_nodes.clear(); }
 
diff --git a/Source/core/dom/Element.cpp b/Source/core/dom/Element.cpp
index cb09066..41c734a 100644
--- a/Source/core/dom/Element.cpp
+++ b/Source/core/dom/Element.cpp
@@ -193,14 +193,10 @@
 
 Element::~Element()
 {
-#ifndef NDEBUG
-    if (document().renderer()) {
-        // When the document is not destroyed, an element that was part of a named flow
-        // content nodes should have been removed from the content nodes collection
-        // and the inNamedFlow flag reset.
-        ASSERT(!inNamedFlow());
-    }
-#endif
+    // When the document is not destroyed, an element that was part of a named flow
+    // content nodes should have been removed from the content nodes collection
+    // and the inNamedFlow flag reset.
+    ASSERT(!document().renderView() || !inNamedFlow());
 
     if (PropertySetCSSStyleDeclaration* cssomWrapper = inlineStyleCSSOMWrapper())
         cssomWrapper->clearParentElement();
@@ -214,7 +210,7 @@
 
         if (RuntimeEnabledFeatures::webAnimationsCSSEnabled()) {
             if (ActiveAnimations* activeAnimations = data->activeAnimations())
-                activeAnimations->cssAnimations()->cancel();
+                activeAnimations->cssAnimations().cancel();
         }
     }
 
@@ -294,12 +290,6 @@
     return true;
 }
 
-DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, blur);
-DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, error);
-DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, focus);
-DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, load);
-DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, scroll);
-
 PassRefPtr<Node> Element::cloneNode(bool deep)
 {
     return deep ? cloneElementWithChildren() : cloneElementWithoutChildren();
@@ -980,7 +970,7 @@
     document().incDOMTreeVersion();
 
     StyleResolver* styleResolver = document().styleResolverIfExists();
-    bool testShouldInvalidateStyle = confusingAndOftenMisusedAttached() && styleResolver && styleChangeType() < SubtreeStyleChange;
+    bool testShouldInvalidateStyle = inActiveDocument() && styleResolver && styleChangeType() < SubtreeStyleChange;
     bool shouldInvalidateStyle = false;
 
     if (isStyledElement() && name == styleAttr) {
@@ -1095,7 +1085,7 @@
 void Element::classAttributeChanged(const AtomicString& newClassString)
 {
     StyleResolver* styleResolver = document().styleResolverIfExists();
-    bool testShouldInvalidateStyle = confusingAndOftenMisusedAttached() && styleResolver && styleChangeType() < SubtreeStyleChange;
+    bool testShouldInvalidateStyle = inActiveDocument() && styleResolver && styleChangeType() < SubtreeStyleChange;
     bool shouldInvalidateStyle = false;
 
     if (classStringHasClassName(newClassString)) {
@@ -1451,7 +1441,7 @@
 
         if (RuntimeEnabledFeatures::webAnimationsCSSEnabled() && !context.performingReattach) {
             if (ActiveAnimations* activeAnimations = data->activeAnimations())
-                activeAnimations->cssAnimations()->cancel();
+                activeAnimations->cssAnimations().cancel();
         }
     }
     if (ElementShadow* shadow = this->shadow())
@@ -1578,9 +1568,11 @@
     if (RenderObject* renderer = this->renderer()) {
         if (localChange != NoChange || pseudoStyleCacheIsInvalid(oldStyle.get(), newStyle.get()) || (change == Force && renderer->requiresForcedStyleRecalcPropagation()) || shouldNotifyRendererWithIdenticalStyles()) {
             renderer->setAnimatableStyle(newStyle.get());
-        } else if (needsStyleRecalc()) {
+        } else {
             // Although no change occurred, we use the new style so that the cousin style sharing code won't get
             // fooled into believing this style is the same.
+            // FIXME: We may be able to remove this hack, see discussion in
+            // https://codereview.chromium.org/30453002/
             renderer->setStyleInternal(newStyle.get());
         }
     }
@@ -1615,12 +1607,9 @@
     if (shouldRecalcStyle(change, this))
         updatePseudoElement(BEFORE, change);
 
-    // FIXME: This check is good enough for :hover + foo, but it is not good enough for :hover + foo + bar.
-    // For now we will just worry about the common case, since it's a lot trickier to get the second case right
-    // without doing way too much re-resolution.
     bool hasDirectAdjacentRules = childrenAffectedByDirectAdjacentRules();
     bool hasIndirectAdjacentRules = childrenAffectedByForwardPositionalRules();
-    bool forceCheckOfNextElementSibling = false;
+    unsigned forceCheckOfNextElementCount = 0;
     bool forceCheckOfAnyElementSibling = false;
     if (hasDirectAdjacentRules || hasIndirectAdjacentRules) {
         for (Node* child = firstChild(); child; child = child->nextSibling()) {
@@ -1628,9 +1617,16 @@
                 continue;
             Element* element = toElement(child);
             bool childRulesChanged = element->needsStyleRecalc() && element->styleChangeType() >= SubtreeStyleChange;
-            if (forceCheckOfNextElementSibling || forceCheckOfAnyElementSibling)
+
+            if (forceCheckOfNextElementCount || forceCheckOfAnyElementSibling)
                 element->setNeedsStyleRecalc();
-            forceCheckOfNextElementSibling = childRulesChanged && hasDirectAdjacentRules;
+
+            if (forceCheckOfNextElementCount)
+                forceCheckOfNextElementCount--;
+
+            if (childRulesChanged && hasDirectAdjacentRules)
+                forceCheckOfNextElementCount = document().styleEngine()->maxDirectAdjacentSelectors();
+
             forceCheckOfAnyElementSibling = forceCheckOfAnyElementSibling || (childRulesChanged && hasIndirectAdjacentRules);
         }
     }
@@ -1692,7 +1688,7 @@
         ensureUserAgentShadowRoot();
 
     if (RuntimeEnabledFeatures::authorShadowDOMForAnyElementEnabled())
-        return ensureShadow().addShadowRoot(this, ShadowRoot::AuthorShadowRoot);
+        return ensureShadow().addShadowRoot(*this, ShadowRoot::AuthorShadowRoot);
 
     // Since some elements recreates shadow root dynamically, multiple shadow
     // subtrees won't work well in that element. Until they are fixed, we disable
@@ -1701,7 +1697,7 @@
         es.throwUninformativeAndGenericDOMException(HierarchyRequestError);
         return 0;
     }
-    return ensureShadow().addShadowRoot(this, ShadowRoot::AuthorShadowRoot);
+    return ensureShadow().addShadowRoot(*this, ShadowRoot::AuthorShadowRoot);
 }
 
 ShadowRoot* Element::shadowRoot() const
@@ -1735,7 +1731,7 @@
 {
     if (ShadowRoot* shadowRoot = userAgentShadowRoot())
         return shadowRoot;
-    ShadowRoot* shadowRoot = ensureShadow().addShadowRoot(this, ShadowRoot::UserAgentShadowRoot);
+    ShadowRoot* shadowRoot = ensureShadow().addShadowRoot(*this, ShadowRoot::UserAgentShadowRoot);
     didAddUserAgentShadowRoot(shadowRoot);
     return shadowRoot;
 }
@@ -1767,7 +1763,7 @@
 static void checkForSiblingStyleChanges(Element* e, RenderStyle* style, bool finishedParsingCallback,
                                         Node* beforeChange, Node* afterChange, int childCountDelta)
 {
-    if (!e->confusingAndOftenMisusedAttached() || e->document().hasPendingForcedStyleRecalc() || e->styleChangeType() >= SubtreeStyleChange)
+    if (!e->inActiveDocument() || e->document().hasPendingForcedStyleRecalc() || e->styleChangeType() >= SubtreeStyleChange)
         return;
 
     // :empty selector.
@@ -1935,7 +1931,7 @@
     setAttributeInternal(index, attrNode->qualifiedName(), attrNode->value(), NotInSynchronizationOfLazyAttribute);
 
     attrNode->attachToElement(this);
-    treeScope().adoptIfNeeded(attrNode);
+    treeScope().adoptIfNeeded(*attrNode);
     ensureAttrNodeListForElement(this).append(attrNode);
 
     return oldAttrNode.release();
@@ -2311,7 +2307,7 @@
             return usedStyle;
     }
 
-    if (!confusingAndOftenMisusedAttached())
+    if (!inActiveDocument())
         // FIXME: Try to do better than this. Ensure that styleForElement() works for elements that are not in the
         // document tree and figure out when to destroy the computed style for such elements.
         return 0;
@@ -2608,7 +2604,7 @@
         return false;
     }
 
-    SelectorQuery* selectorQuery = document().selectorQueryCache()->add(selector, document(), es);
+    SelectorQuery* selectorQuery = document().selectorQueryCache().add(selector, document(), es);
     if (!selectorQuery)
         return false;
     return selectorQuery->matches(this);
@@ -2929,14 +2925,14 @@
     }
 
     if (oldValue != newValue) {
-        if (confusingAndOftenMisusedAttached() && hasSelectorForAttribute(&document(), name.localName()))
+        if (inActiveDocument() && hasSelectorForAttribute(&document(), name.localName()))
            setNeedsStyleRecalc();
 
         if (isUpgradedCustomElement())
             CustomElement::attributeDidChange(this, name.localName(), oldValue, newValue);
     }
 
-    if (OwnPtr<MutationObserverInterestGroup> recipients = MutationObserverInterestGroup::createForAttributesMutation(this, name))
+    if (OwnPtr<MutationObserverInterestGroup> recipients = MutationObserverInterestGroup::createForAttributesMutation(*this, name))
         recipients->enqueueMutationRecord(MutationRecord::createAttributes(this, name, oldValue));
 
     InspectorInstrumentation::willModifyDOMAttr(this, oldValue, newValue);
@@ -3010,15 +3006,15 @@
     RefPtr<HTMLCollection> collection;
     if (type == TableRows) {
         ASSERT(hasTagName(tableTag));
-        return ensureRareData().ensureNodeLists()->addCacheWithAtomicName<HTMLTableRowsCollection>(this, type);
+        return ensureRareData().ensureNodeLists().addCacheWithAtomicName<HTMLTableRowsCollection>(this, type);
     } else if (type == SelectOptions) {
         ASSERT(hasTagName(selectTag));
-        return ensureRareData().ensureNodeLists()->addCacheWithAtomicName<HTMLOptionsCollection>(this, type);
+        return ensureRareData().ensureNodeLists().addCacheWithAtomicName<HTMLOptionsCollection>(this, type);
     } else if (type == FormControls) {
         ASSERT(hasTagName(formTag) || hasTagName(fieldsetTag));
-        return ensureRareData().ensureNodeLists()->addCacheWithAtomicName<HTMLFormControlsCollection>(this, type);
+        return ensureRareData().ensureNodeLists().addCacheWithAtomicName<HTMLFormControlsCollection>(this, type);
     }
-    return ensureRareData().ensureNodeLists()->addCacheWithAtomicName<HTMLCollection>(this, type);
+    return ensureRareData().ensureNodeLists().addCacheWithAtomicName<HTMLCollection>(this, type);
 }
 
 static void scheduleLayerUpdateCallback(Node* node)
@@ -3066,7 +3062,7 @@
     RefPtr<Attr> attrNode = findAttrNodeInList(attrNodeList, name);
     if (!attrNode) {
         attrNode = Attr::create(*this, name);
-        treeScope().adoptIfNeeded(attrNode.get());
+        treeScope().adoptIfNeeded(*attrNode);
         attrNodeList.append(attrNode);
     }
     return attrNode.release();
@@ -3226,8 +3222,10 @@
 {
     ASSERT(isStyledElement());
     RefPtr<StylePropertySet>& inlineStyle = ensureUniqueElementData()->m_inlineStyle;
-    if (!inlineStyle)
-        inlineStyle = MutableStylePropertySet::create(strictToCSSParserMode(isHTMLElement() && !document().inQuirksMode()));
+    if (!inlineStyle) {
+        CSSParserMode mode = (!isHTMLElement() || document().inQuirksMode()) ? HTMLQuirksMode : HTMLStandardMode;
+        inlineStyle = MutableStylePropertySet::create(mode);
+    }
     else if (!inlineStyle->isMutable())
         inlineStyle = inlineStyle->mutableCopy();
     ASSERT(inlineStyle->isMutable());
@@ -3433,206 +3431,4 @@
     return true;
 }
 
-void ElementData::deref()
-{
-    if (!derefBase())
-        return;
-
-    if (m_isUnique)
-        delete static_cast<UniqueElementData*>(this);
-    else
-        delete static_cast<ShareableElementData*>(this);
-}
-
-ElementData::ElementData()
-    : m_isUnique(true)
-    , m_arraySize(0)
-    , m_presentationAttributeStyleIsDirty(false)
-    , m_styleAttributeIsDirty(false)
-    , m_animatedSVGAttributesAreDirty(false)
-{
-}
-
-ElementData::ElementData(unsigned arraySize)
-    : m_isUnique(false)
-    , m_arraySize(arraySize)
-    , m_presentationAttributeStyleIsDirty(false)
-    , m_styleAttributeIsDirty(false)
-    , m_animatedSVGAttributesAreDirty(false)
-{
-}
-
-struct SameSizeAsElementData : public RefCounted<SameSizeAsElementData> {
-    unsigned bitfield;
-    void* refPtrs[3];
-};
-
-COMPILE_ASSERT(sizeof(ElementData) == sizeof(SameSizeAsElementData), element_attribute_data_should_stay_small);
-
-static size_t sizeForShareableElementDataWithAttributeCount(unsigned count)
-{
-    return sizeof(ShareableElementData) + sizeof(Attribute) * count;
-}
-
-PassRefPtr<ShareableElementData> ShareableElementData::createWithAttributes(const Vector<Attribute>& attributes)
-{
-    void* slot = WTF::fastMalloc(sizeForShareableElementDataWithAttributeCount(attributes.size()));
-    return adoptRef(new (slot) ShareableElementData(attributes));
-}
-
-PassRefPtr<UniqueElementData> UniqueElementData::create()
-{
-    return adoptRef(new UniqueElementData);
-}
-
-ShareableElementData::ShareableElementData(const Vector<Attribute>& attributes)
-    : ElementData(attributes.size())
-{
-    for (unsigned i = 0; i < m_arraySize; ++i)
-        new (&m_attributeArray[i]) Attribute(attributes[i]);
-}
-
-ShareableElementData::~ShareableElementData()
-{
-    for (unsigned i = 0; i < m_arraySize; ++i)
-        m_attributeArray[i].~Attribute();
-}
-
-ShareableElementData::ShareableElementData(const UniqueElementData& other)
-    : ElementData(other, false)
-{
-    ASSERT(!other.m_presentationAttributeStyle);
-
-    if (other.m_inlineStyle) {
-        ASSERT(!other.m_inlineStyle->hasCSSOMWrapper());
-        m_inlineStyle = other.m_inlineStyle->immutableCopyIfNeeded();
-    }
-
-    for (unsigned i = 0; i < m_arraySize; ++i)
-        new (&m_attributeArray[i]) Attribute(other.m_attributeVector.at(i));
-}
-
-ElementData::ElementData(const ElementData& other, bool isUnique)
-    : m_isUnique(isUnique)
-    , m_arraySize(isUnique ? 0 : other.length())
-    , m_presentationAttributeStyleIsDirty(other.m_presentationAttributeStyleIsDirty)
-    , m_styleAttributeIsDirty(other.m_styleAttributeIsDirty)
-    , m_animatedSVGAttributesAreDirty(other.m_animatedSVGAttributesAreDirty)
-    , m_classNames(other.m_classNames)
-    , m_idForStyleResolution(other.m_idForStyleResolution)
-{
-    // NOTE: The inline style is copied by the subclass copy constructor since we don't know what to do with it here.
-}
-
-UniqueElementData::UniqueElementData()
-{
-}
-
-UniqueElementData::UniqueElementData(const UniqueElementData& other)
-    : ElementData(other, true)
-    , m_presentationAttributeStyle(other.m_presentationAttributeStyle)
-    , m_attributeVector(other.m_attributeVector)
-{
-    m_inlineStyle = other.m_inlineStyle ? other.m_inlineStyle->mutableCopy() : 0;
-}
-
-UniqueElementData::UniqueElementData(const ShareableElementData& other)
-    : ElementData(other, true)
-{
-    // An ShareableElementData should never have a mutable inline StylePropertySet attached.
-    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)
-        m_attributeVector.uncheckedAppend(other.m_attributeArray[i]);
-}
-
-PassRefPtr<UniqueElementData> ElementData::makeUniqueCopy() const
-{
-    if (isUnique())
-        return adoptRef(new UniqueElementData(static_cast<const UniqueElementData&>(*this)));
-    return adoptRef(new UniqueElementData(static_cast<const ShareableElementData&>(*this)));
-}
-
-PassRefPtr<ShareableElementData> UniqueElementData::makeShareableCopy() const
-{
-    void* slot = WTF::fastMalloc(sizeForShareableElementDataWithAttributeCount(m_attributeVector.size()));
-    return adoptRef(new (slot) ShareableElementData(*this));
-}
-
-void UniqueElementData::addAttribute(const QualifiedName& attributeName, const AtomicString& value)
-{
-    m_attributeVector.append(Attribute(attributeName, value));
-}
-
-void UniqueElementData::removeAttribute(size_t index)
-{
-    ASSERT_WITH_SECURITY_IMPLICATION(index < length());
-    m_attributeVector.remove(index);
-}
-
-bool ElementData::isEquivalent(const ElementData* other) const
-{
-    if (!other)
-        return isEmpty();
-
-    unsigned len = length();
-    if (len != 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())
-            return false;
-    }
-
-    return true;
-}
-
-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())
-            return i;
-    }
-    return kNotFound;
-}
-
-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);
-        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))
-                return i;
-        }
-    }
-    return kNotFound;
-}
-
-Attribute* UniqueElementData::getAttributeItem(const QualifiedName& name)
-{
-    for (unsigned i = 0; i < length(); ++i) {
-        if (m_attributeVector.at(i).name().matches(name))
-            return &m_attributeVector.at(i);
-    }
-    return 0;
-}
-
-Attribute* UniqueElementData::attributeItem(unsigned index)
-{
-    ASSERT_WITH_SECURITY_IMPLICATION(index < length());
-    return &m_attributeVector.at(index);
-}
-
 } // namespace WebCore
diff --git a/Source/core/dom/Element.h b/Source/core/dom/Element.h
index e28bdd2..c35fe66 100644
--- a/Source/core/dom/Element.h
+++ b/Source/core/dom/Element.h
@@ -30,6 +30,7 @@
 #include "core/css/CSSPrimitiveValue.h"
 #include "core/dom/Attribute.h"
 #include "core/dom/Document.h"
+#include "core/dom/ElementData.h"
 #include "core/dom/SpaceSplitString.h"
 #include "core/html/CollectionType.h"
 #include "core/page/FocusDirection.h"
@@ -45,7 +46,6 @@
 class ClientRectList;
 class DOMStringMap;
 class DOMTokenList;
-class Element;
 class ElementRareData;
 class ElementShadow;
 class ExceptionState;
@@ -58,111 +58,7 @@
 class PseudoElement;
 class RenderRegion;
 class ShadowRoot;
-class ShareableElementData;
 class StylePropertySet;
-class UniqueElementData;
-
-class ElementData : public RefCounted<ElementData> {
-    WTF_MAKE_FAST_ALLOCATED;
-public:
-    // Override RefCounted's deref() to ensure operator delete is called on
-    // the appropriate subclass type.
-    void deref();
-
-    void clearClass() const { m_classNames.clear(); }
-    void setClass(const AtomicString& className, bool shouldFoldCase) const { m_classNames.set(className, shouldFoldCase); }
-    const SpaceSplitString& classNames() const { return m_classNames; }
-
-    const AtomicString& idForStyleResolution() const { return m_idForStyleResolution; }
-    void setIdForStyleResolution(const AtomicString& newId) const { m_idForStyleResolution = newId; }
-
-    const StylePropertySet* inlineStyle() const { return m_inlineStyle.get(); }
-
-    const StylePropertySet* presentationAttributeStyle() const;
-
-    size_t length() const;
-    bool isEmpty() const { return !length(); }
-
-    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;
-    size_t getAttrIndex(Attr*) const;
-
-    bool hasID() const { return !m_idForStyleResolution.isNull(); }
-    bool hasClass() const { return !m_classNames.isNull(); }
-
-    bool isEquivalent(const ElementData* other) const;
-
-    bool isUnique() const { return m_isUnique; }
-
-protected:
-    ElementData();
-    ElementData(unsigned arraySize);
-    ElementData(const ElementData&, bool isUnique);
-
-    unsigned m_isUnique : 1;
-    unsigned m_arraySize : 28;
-    mutable unsigned m_presentationAttributeStyleIsDirty : 1;
-    mutable unsigned m_styleAttributeIsDirty : 1;
-    mutable unsigned m_animatedSVGAttributesAreDirty : 1;
-
-    mutable RefPtr<StylePropertySet> m_inlineStyle;
-    mutable SpaceSplitString m_classNames;
-    mutable AtomicString m_idForStyleResolution;
-
-private:
-    friend class Element;
-    friend class ShareableElementData;
-    friend class UniqueElementData;
-    friend class SVGElement;
-
-    const Attribute* attributeBase() const;
-    const Attribute* getAttributeItem(const AtomicString& name, bool shouldIgnoreAttributeCase) const;
-    size_t getAttributeItemIndexSlowCase(const AtomicString& name, bool shouldIgnoreAttributeCase) const;
-
-    PassRefPtr<UniqueElementData> makeUniqueCopy() const;
-};
-
-#if COMPILER(MSVC)
-#pragma warning(push)
-#pragma warning(disable: 4200) // Disable "zero-sized array in struct/union" warning
-#endif
-
-class ShareableElementData : public ElementData {
-public:
-    static PassRefPtr<ShareableElementData> createWithAttributes(const Vector<Attribute>&);
-
-    explicit ShareableElementData(const Vector<Attribute>&);
-    explicit ShareableElementData(const UniqueElementData&);
-    ~ShareableElementData();
-
-    Attribute m_attributeArray[0];
-};
-
-#if COMPILER(MSVC)
-#pragma warning(pop)
-#endif
-
-class UniqueElementData : public ElementData {
-public:
-    static PassRefPtr<UniqueElementData> create();
-    PassRefPtr<ShareableElementData> makeShareableCopy() const;
-
-    // These functions do no error/duplicate checking.
-    void addAttribute(const QualifiedName&, const AtomicString&);
-    void removeAttribute(size_t index);
-
-    Attribute* attributeItem(unsigned index);
-    Attribute* getAttributeItem(const QualifiedName&);
-
-    UniqueElementData();
-    explicit UniqueElementData(const ShareableElementData&);
-    explicit UniqueElementData(const UniqueElementData&);
-
-    mutable RefPtr<StylePropertySet> m_presentationAttributeStyle;
-    Vector<Attribute, 4> m_attributeVector;
-};
 
 enum AffectedSelectorType {
     AffectedSelectorChecked = 1,
@@ -186,82 +82,22 @@
     static PassRefPtr<Element> create(const QualifiedName&, Document*);
     virtual ~Element();
 
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(abort);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecopy);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecut);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(beforepaste);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(cancel);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(canplay);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(canplaythrough);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(change);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(click);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(close);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(contextmenu);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(copy);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(cuechange);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(cut);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(dblclick);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(drag);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(dragend);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(dragenter);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(dragleave);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(dragover);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(dragstart);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(drop);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(durationchange);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(emptied);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(ended);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(input);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(invalid);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(keydown);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(keypress);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(keyup);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(loadeddata);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(loadedmetadata);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(loadstart);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(mousedown);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseenter);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseleave);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(mousemove);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseout);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseover);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseup);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(mousewheel);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(paste);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(pause);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(play);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(playing);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(progress);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(ratechange);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(reset);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(search);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(seeked);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(seeking);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(select);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(selectstart);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(show);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(stalled);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(submit);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(suspend);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(timeupdate);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(touchcancel);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(touchend);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(touchmove);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(touchstart);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(volumechange);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(waiting);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitfullscreenchange);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitfullscreenerror);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(wheel);
 
-    // These four attribute event handler attributes are overridden by HTMLBodyElement
-    // and HTMLFrameSetElement to forward to the DOMWindow.
-    DECLARE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(blur);
-    DECLARE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(error);
-    DECLARE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(focus);
-    DECLARE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(load);
-    DECLARE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(scroll);
-
     bool hasAttribute(const QualifiedName&) const;
     const AtomicString& getAttribute(const QualifiedName&) const;
     void setAttribute(const QualifiedName&, const AtomicString& value);
@@ -472,7 +308,7 @@
     virtual void didAddShadowRoot(ShadowRoot&);
     ShadowRoot* userAgentShadowRoot() const;
     ShadowRoot* ensureUserAgentShadowRoot();
-    virtual const AtomicString& shadowPseudoId() const { return !part().isEmpty() ? part() : pseudo(); }
+    const AtomicString& shadowPseudoId() const;
 
     RenderStyle* computedStyle(PseudoId = NOPSEUDO);
 
@@ -876,6 +712,15 @@
     return elementData()->idForStyleResolution();
 }
 
+inline const AtomicString& Element::shadowPseudoId() const
+{
+    // FIXME: We should remove both part() and pseudo(), neither are in the new spec.
+    const AtomicString& part = this->part();
+    if (!part.isEmpty())
+        return part;
+    return pseudo();
+}
+
 inline bool Element::isIdAttributeName(const QualifiedName& attributeName) const
 {
     // FIXME: This check is probably not correct for the case where the document has an id attribute
@@ -1015,86 +860,6 @@
     return element && element->shadow();
 }
 
-inline size_t ElementData::length() const
-{
-    if (isUnique())
-        return static_cast<const UniqueElementData*>(this)->m_attributeVector.size();
-    return m_arraySize;
-}
-
-inline const StylePropertySet* ElementData::presentationAttributeStyle() const
-{
-    if (!m_isUnique)
-        return 0;
-    return static_cast<const UniqueElementData*>(this)->m_presentationAttributeStyle.get();
-}
-
-inline const Attribute* ElementData::getAttributeItem(const AtomicString& name, bool shouldIgnoreAttributeCase) const
-{
-    size_t index = getAttributeItemIndex(name, shouldIgnoreAttributeCase);
-    if (index != kNotFound)
-        return attributeItem(index);
-    return 0;
-}
-
-inline const Attribute* ElementData::attributeBase() const
-{
-    if (m_isUnique)
-        return static_cast<const UniqueElementData*>(this)->m_attributeVector.begin();
-    return static_cast<const ShareableElementData*>(this)->m_attributeArray;
-}
-
-inline size_t ElementData::getAttributeItemIndex(const QualifiedName& name, bool shouldIgnoreCase) const
-{
-    const Attribute* begin = attributeBase();
-    for (unsigned i = 0; i < length(); ++i) {
-        const Attribute& attribute = begin[i];
-        if (attribute.name().matchesPossiblyIgnoringCase(name, shouldIgnoreCase))
-            return i;
-    }
-    return kNotFound;
-}
-
-// We use a boolean parameter instead of calling shouldIgnoreAttributeCase so that the caller
-// can tune the behavior (hasAttribute is case sensitive whereas getAttribute is not).
-inline size_t ElementData::getAttributeItemIndex(const AtomicString& name, bool shouldIgnoreAttributeCase) const
-{
-    unsigned len = 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) {
-        const Attribute& attribute = begin[i];
-        if (!attribute.name().hasPrefix()) {
-            if (name == attribute.localName())
-                return i;
-        } else
-            doSlowCheck = true;
-    }
-
-    if (doSlowCheck)
-        return getAttributeItemIndexSlowCase(name, shouldIgnoreAttributeCase);
-    return kNotFound;
-}
-
-inline const Attribute* ElementData::getAttributeItem(const QualifiedName& name) const
-{
-    const Attribute* begin = attributeBase();
-    for (unsigned i = 0; i < length(); ++i) {
-        const Attribute& attribute = begin[i];
-        if (attribute.name().matches(name))
-            return &attribute;
-    }
-    return 0;
-}
-
-inline const Attribute* ElementData::attributeItem(unsigned index) const
-{
-    RELEASE_ASSERT(index < length());
-    return attributeBase() + index;
-}
-
 } // namespace
 
 #endif
diff --git a/Source/core/dom/Element.idl b/Source/core/dom/Element.idl
index 8d08592..8d45e7d 100644
--- a/Source/core/dom/Element.idl
+++ b/Source/core/dom/Element.idl
@@ -122,10 +122,10 @@
 
     // Mozilla version
     const unsigned short ALLOW_KEYBOARD_INPUT = 1;
-    [RuntimeEnabled=Fullscreen, PerWorldBindings, ActivityLogging=AccessForAllWorlds] void webkitRequestFullScreen([Default=Undefined] optional unsigned short flags);
+    [RuntimeEnabled=Fullscreen, PerWorldBindings, ActivityLogging=AccessForAllWorlds, MeasureAs=PrefixedElementRequestFullScreen] void webkitRequestFullScreen([Default=Undefined] optional unsigned short flags);
 
     // W3C version
-    [RuntimeEnabled=Fullscreen, PerWorldBindings, ActivityLogging=AccessForAllWorlds] void webkitRequestFullscreen();
+    [RuntimeEnabled=Fullscreen, PerWorldBindings, ActivityLogging=AccessForAllWorlds, MeasureAs=PrefixedElementRequestFullscreen] void webkitRequestFullscreen();
 
     void webkitRequestPointerLock();
 
diff --git a/Source/core/dom/ElementData.cpp b/Source/core/dom/ElementData.cpp
new file mode 100644
index 0000000..9248276
--- /dev/null
+++ b/Source/core/dom/ElementData.cpp
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/dom/ElementData.h"
+
+#include "core/css/StylePropertySet.h"
+#include "core/dom/Attr.h"
+#include "core/dom/QualifiedName.h"
+#include "wtf/Vector.h"
+#include "wtf/text/AtomicString.h"
+
+namespace WebCore {
+
+struct SameSizeAsElementData : public RefCounted<SameSizeAsElementData> {
+    unsigned bitfield;
+    void* refPtrs[3];
+};
+
+COMPILE_ASSERT(sizeof(ElementData) == sizeof(SameSizeAsElementData), element_attribute_data_should_stay_small);
+
+static size_t sizeForShareableElementDataWithAttributeCount(unsigned count)
+{
+    return sizeof(ShareableElementData) + sizeof(Attribute) * count;
+}
+
+ElementData::ElementData()
+    : m_isUnique(true)
+    , m_arraySize(0)
+    , m_presentationAttributeStyleIsDirty(false)
+    , m_styleAttributeIsDirty(false)
+    , m_animatedSVGAttributesAreDirty(false)
+{
+}
+
+ElementData::ElementData(unsigned arraySize)
+    : m_isUnique(false)
+    , m_arraySize(arraySize)
+    , m_presentationAttributeStyleIsDirty(false)
+    , m_styleAttributeIsDirty(false)
+    , m_animatedSVGAttributesAreDirty(false)
+{
+}
+
+ElementData::ElementData(const ElementData& other, bool isUnique)
+    : m_isUnique(isUnique)
+    , m_arraySize(isUnique ? 0 : other.length())
+    , m_presentationAttributeStyleIsDirty(other.m_presentationAttributeStyleIsDirty)
+    , m_styleAttributeIsDirty(other.m_styleAttributeIsDirty)
+    , m_animatedSVGAttributesAreDirty(other.m_animatedSVGAttributesAreDirty)
+    , m_classNames(other.m_classNames)
+    , m_idForStyleResolution(other.m_idForStyleResolution)
+{
+    // NOTE: The inline style is copied by the subclass copy constructor since we don't know what to do with it here.
+}
+
+void ElementData::deref()
+{
+    if (!derefBase())
+        return;
+
+    if (m_isUnique)
+        delete static_cast<UniqueElementData*>(this);
+    else
+        delete static_cast<ShareableElementData*>(this);
+}
+
+PassRefPtr<UniqueElementData> ElementData::makeUniqueCopy() const
+{
+    if (isUnique())
+        return adoptRef(new UniqueElementData(static_cast<const UniqueElementData&>(*this)));
+    return adoptRef(new UniqueElementData(static_cast<const ShareableElementData&>(*this)));
+}
+
+bool ElementData::isEquivalent(const ElementData* other) const
+{
+    if (!other)
+        return isEmpty();
+
+    unsigned len = length();
+    if (len != 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())
+            return false;
+    }
+
+    return true;
+}
+
+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())
+            return i;
+    }
+    return kNotFound;
+}
+
+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);
+        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))
+                return i;
+        }
+    }
+    return kNotFound;
+}
+
+ShareableElementData::ShareableElementData(const Vector<Attribute>& attributes)
+    : ElementData(attributes.size())
+{
+    for (unsigned i = 0; i < m_arraySize; ++i)
+        new (&m_attributeArray[i]) Attribute(attributes[i]);
+}
+
+ShareableElementData::~ShareableElementData()
+{
+    for (unsigned i = 0; i < m_arraySize; ++i)
+        m_attributeArray[i].~Attribute();
+}
+
+ShareableElementData::ShareableElementData(const UniqueElementData& other)
+    : ElementData(other, false)
+{
+    ASSERT(!other.m_presentationAttributeStyle);
+
+    if (other.m_inlineStyle) {
+        ASSERT(!other.m_inlineStyle->hasCSSOMWrapper());
+        m_inlineStyle = other.m_inlineStyle->immutableCopyIfNeeded();
+    }
+
+    for (unsigned i = 0; i < m_arraySize; ++i)
+        new (&m_attributeArray[i]) Attribute(other.m_attributeVector.at(i));
+}
+
+PassRefPtr<ShareableElementData> ShareableElementData::createWithAttributes(const Vector<Attribute>& attributes)
+{
+    void* slot = WTF::fastMalloc(sizeForShareableElementDataWithAttributeCount(attributes.size()));
+    return adoptRef(new (slot) ShareableElementData(attributes));
+}
+
+UniqueElementData::UniqueElementData()
+{
+}
+
+UniqueElementData::UniqueElementData(const UniqueElementData& other)
+    : ElementData(other, true)
+    , m_presentationAttributeStyle(other.m_presentationAttributeStyle)
+    , m_attributeVector(other.m_attributeVector)
+{
+    m_inlineStyle = other.m_inlineStyle ? other.m_inlineStyle->mutableCopy() : 0;
+}
+
+UniqueElementData::UniqueElementData(const ShareableElementData& other)
+    : ElementData(other, true)
+{
+    // An ShareableElementData should never have a mutable inline StylePropertySet attached.
+    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)
+        m_attributeVector.uncheckedAppend(other.m_attributeArray[i]);
+}
+
+PassRefPtr<UniqueElementData> UniqueElementData::create()
+{
+    return adoptRef(new UniqueElementData);
+}
+
+PassRefPtr<ShareableElementData> UniqueElementData::makeShareableCopy() const
+{
+    void* slot = WTF::fastMalloc(sizeForShareableElementDataWithAttributeCount(m_attributeVector.size()));
+    return adoptRef(new (slot) ShareableElementData(*this));
+}
+
+void UniqueElementData::addAttribute(const QualifiedName& attributeName, const AtomicString& value)
+{
+    m_attributeVector.append(Attribute(attributeName, value));
+}
+
+void UniqueElementData::removeAttribute(size_t index)
+{
+    ASSERT_WITH_SECURITY_IMPLICATION(index < length());
+    m_attributeVector.remove(index);
+}
+
+Attribute* UniqueElementData::getAttributeItem(const QualifiedName& name)
+{
+    for (unsigned i = 0; i < length(); ++i) {
+        if (m_attributeVector.at(i).name().matches(name))
+            return &m_attributeVector.at(i);
+    }
+    return 0;
+}
+
+Attribute* UniqueElementData::attributeItem(unsigned index)
+{
+    ASSERT_WITH_SECURITY_IMPLICATION(index < length());
+    return &m_attributeVector.at(index);
+}
+
+} // namespace WebCore
diff --git a/Source/core/dom/ElementData.h b/Source/core/dom/ElementData.h
new file mode 100644
index 0000000..50c2879
--- /dev/null
+++ b/Source/core/dom/ElementData.h
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ElementData_h
+#define ElementData_h
+
+#include "core/dom/Attribute.h"
+#include "core/dom/SpaceSplitString.h"
+#include "wtf/text/AtomicString.h"
+
+namespace WebCore {
+
+class Attr;
+class ShareableElementData;
+class StylePropertySet;
+class UniqueElementData;
+
+class ElementData : public RefCounted<ElementData> {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    // Override RefCounted's deref() to ensure operator delete is called on
+    // the appropriate subclass type.
+    void deref();
+
+    void clearClass() const { m_classNames.clear(); }
+    void setClass(const AtomicString& className, bool shouldFoldCase) const { m_classNames.set(className, shouldFoldCase); }
+    const SpaceSplitString& classNames() const { return m_classNames; }
+
+    const AtomicString& idForStyleResolution() const { return m_idForStyleResolution; }
+    void setIdForStyleResolution(const AtomicString& newId) const { m_idForStyleResolution = newId; }
+
+    const StylePropertySet* inlineStyle() const { return m_inlineStyle.get(); }
+
+    const StylePropertySet* presentationAttributeStyle() const;
+
+    size_t length() const;
+    bool isEmpty() const { return !length(); }
+
+    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;
+    size_t getAttrIndex(Attr*) const;
+
+    bool hasID() const { return !m_idForStyleResolution.isNull(); }
+    bool hasClass() const { return !m_classNames.isNull(); }
+
+    bool isEquivalent(const ElementData* other) const;
+
+    bool isUnique() const { return m_isUnique; }
+
+protected:
+    ElementData();
+    explicit ElementData(unsigned arraySize);
+    ElementData(const ElementData&, bool isUnique);
+
+    unsigned m_isUnique : 1;
+    unsigned m_arraySize : 28;
+    mutable unsigned m_presentationAttributeStyleIsDirty : 1;
+    mutable unsigned m_styleAttributeIsDirty : 1;
+    mutable unsigned m_animatedSVGAttributesAreDirty : 1;
+
+    mutable RefPtr<StylePropertySet> m_inlineStyle;
+    mutable SpaceSplitString m_classNames;
+    mutable AtomicString m_idForStyleResolution;
+
+private:
+    friend class Element;
+    friend class ShareableElementData;
+    friend class UniqueElementData;
+    friend class SVGElement;
+
+    const Attribute* attributeBase() const;
+    const Attribute* getAttributeItem(const AtomicString& name, bool shouldIgnoreAttributeCase) const;
+    size_t getAttributeItemIndexSlowCase(const AtomicString& name, bool shouldIgnoreAttributeCase) const;
+
+    PassRefPtr<UniqueElementData> makeUniqueCopy() const;
+};
+
+#if COMPILER(MSVC)
+#pragma warning(push)
+#pragma warning(disable: 4200) // Disable "zero-sized array in struct/union" warning
+#endif
+
+class ShareableElementData : public ElementData {
+public:
+    static PassRefPtr<ShareableElementData> createWithAttributes(const Vector<Attribute>&);
+
+    explicit ShareableElementData(const Vector<Attribute>&);
+    explicit ShareableElementData(const UniqueElementData&);
+    ~ShareableElementData();
+
+    Attribute m_attributeArray[0];
+};
+
+#if COMPILER(MSVC)
+#pragma warning(pop)
+#endif
+
+class UniqueElementData : public ElementData {
+public:
+    static PassRefPtr<UniqueElementData> create();
+    PassRefPtr<ShareableElementData> makeShareableCopy() const;
+
+    // These functions do no error/duplicate checking.
+    void addAttribute(const QualifiedName&, const AtomicString&);
+    void removeAttribute(size_t index);
+
+    Attribute* attributeItem(unsigned index);
+    Attribute* getAttributeItem(const QualifiedName&);
+
+    UniqueElementData();
+    explicit UniqueElementData(const ShareableElementData&);
+    explicit UniqueElementData(const UniqueElementData&);
+
+    mutable RefPtr<StylePropertySet> m_presentationAttributeStyle;
+    Vector<Attribute, 4> m_attributeVector;
+};
+
+inline size_t ElementData::length() const
+{
+    if (isUnique())
+        return static_cast<const UniqueElementData*>(this)->m_attributeVector.size();
+    return m_arraySize;
+}
+
+inline const StylePropertySet* ElementData::presentationAttributeStyle() const
+{
+    if (!m_isUnique)
+        return 0;
+    return static_cast<const UniqueElementData*>(this)->m_presentationAttributeStyle.get();
+}
+
+inline const Attribute* ElementData::getAttributeItem(const AtomicString& name, bool shouldIgnoreAttributeCase) const
+{
+    size_t index = getAttributeItemIndex(name, shouldIgnoreAttributeCase);
+    if (index != kNotFound)
+        return attributeItem(index);
+    return 0;
+}
+
+inline const Attribute* ElementData::attributeBase() const
+{
+    if (m_isUnique)
+        return static_cast<const UniqueElementData*>(this)->m_attributeVector.begin();
+    return static_cast<const ShareableElementData*>(this)->m_attributeArray;
+}
+
+inline size_t ElementData::getAttributeItemIndex(const QualifiedName& name, bool shouldIgnoreCase) const
+{
+    const Attribute* begin = attributeBase();
+    for (unsigned i = 0; i < length(); ++i) {
+        const Attribute& attribute = begin[i];
+        if (attribute.name().matchesPossiblyIgnoringCase(name, shouldIgnoreCase))
+            return i;
+    }
+    return kNotFound;
+}
+
+// We use a boolean parameter instead of calling shouldIgnoreAttributeCase so that the caller
+// can tune the behavior (hasAttribute is case sensitive whereas getAttribute is not).
+inline size_t ElementData::getAttributeItemIndex(const AtomicString& name, bool shouldIgnoreAttributeCase) const
+{
+    unsigned len = 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) {
+        const Attribute& attribute = begin[i];
+        if (!attribute.name().hasPrefix()) {
+            if (name == attribute.localName())
+                return i;
+        } else {
+            doSlowCheck = true;
+        }
+    }
+
+    if (doSlowCheck)
+        return getAttributeItemIndexSlowCase(name, shouldIgnoreAttributeCase);
+    return kNotFound;
+}
+
+inline const Attribute* ElementData::getAttributeItem(const QualifiedName& name) const
+{
+    const Attribute* begin = attributeBase();
+    for (unsigned i = 0; i < length(); ++i) {
+        const Attribute& attribute = begin[i];
+        if (attribute.name().matches(name))
+            return &attribute;
+    }
+    return 0;
+}
+
+inline const Attribute* ElementData::attributeItem(unsigned index) const
+{
+    RELEASE_ASSERT(index < length());
+    return attributeBase() + index;
+}
+
+} // namespace WebCore
+
+#endif // ElementData_h
diff --git a/Source/core/dom/ElementRareData.h b/Source/core/dom/ElementRareData.h
index 0608531..d9be4ce 100644
--- a/Source/core/dom/ElementRareData.h
+++ b/Source/core/dom/ElementRareData.h
@@ -271,12 +271,10 @@
 
     InspectorInstrumentation::pseudoElementDestroyed(element);
 
-    if (element->confusingAndOftenMisusedAttached())
-        element->detach();
-
     ASSERT(!element->nextSibling());
     ASSERT(!element->previousSibling());
 
+    element->detach();
     element->document().removeFromTopLayer(element);
     element->setParentOrShadowHostNode(0);
 }
diff --git a/Source/core/dom/ExecutionContext.cpp b/Source/core/dom/ExecutionContext.cpp
index 8f1a50f..321fe69 100644
--- a/Source/core/dom/ExecutionContext.cpp
+++ b/Source/core/dom/ExecutionContext.cpp
@@ -137,7 +137,7 @@
 
 bool ExecutionContext::hasPendingActivity()
 {
-    if (lifecycleNotifier()->hasPendingActivity())
+    if (lifecycleNotifier().hasPendingActivity())
         return true;
 
     HashSet<MessagePort*>::const_iterator messagePortsEnd = m_messagePorts.end();
@@ -151,27 +151,27 @@
 
 void ExecutionContext::suspendActiveDOMObjects()
 {
-    lifecycleNotifier()->notifySuspendingActiveDOMObjects();
+    lifecycleNotifier().notifySuspendingActiveDOMObjects();
     m_activeDOMObjectsAreSuspended = true;
 }
 
 void ExecutionContext::resumeActiveDOMObjects()
 {
     m_activeDOMObjectsAreSuspended = false;
-    lifecycleNotifier()->notifyResumingActiveDOMObjects();
+    lifecycleNotifier().notifyResumingActiveDOMObjects();
 }
 
 void ExecutionContext::stopActiveDOMObjects()
 {
     m_activeDOMObjectsAreStopped = true;
-    lifecycleNotifier()->notifyStoppingActiveDOMObjects();
+    lifecycleNotifier().notifyStoppingActiveDOMObjects();
     // Also close MessagePorts. If they were ActiveDOMObjects (they could be) then they could be stopped instead.
     closeMessagePorts();
 }
 
 void ExecutionContext::suspendActiveDOMObjectIfNeeded(ActiveDOMObject* object)
 {
-    ASSERT(lifecycleNotifier()->contains(object));
+    ASSERT(lifecycleNotifier().contains(object));
     // Ensure all ActiveDOMObjects are suspended also newly created ones.
     if (m_activeDOMObjectsAreSuspended)
         object->suspend();
@@ -294,11 +294,16 @@
         iter->value->didChangeAlignmentInterval();
 }
 
-EventQueue* ExecutionContext::eventQueue() const
+SecurityOrigin* ExecutionContext::securityOrigin() const
 {
-    if (!m_client)
-        return 0;
-    return m_client->eventQueue();
+    RELEASE_ASSERT(m_client);
+    return m_client->securityContext().securityOrigin();
+}
+
+ContentSecurityPolicy* ExecutionContext::contentSecurityPolicy() const
+{
+    RELEASE_ASSERT(m_client);
+    return m_client->securityContext().contentSecurityPolicy();
 }
 
 const KURL& ExecutionContext::url() const
@@ -338,8 +343,7 @@
 
 DOMWindow* ExecutionContext::executingWindow() const
 {
-    if (!m_client)
-        return 0;
+    RELEASE_ASSERT(m_client);
     return m_client->executingWindow();
 }
 
@@ -364,16 +368,14 @@
     m_client->postTask(task);
 }
 
-PassOwnPtr<LifecycleNotifier> ExecutionContext::createLifecycleNotifier()
+PassOwnPtr<LifecycleNotifier<ExecutionContext> > ExecutionContext::createLifecycleNotifier()
 {
-    if (!m_client)
-        return PassOwnPtr<LifecycleNotifier>();
-    return m_client->createLifecycleNotifier();
+    return ContextLifecycleNotifier::create(this);
 }
 
-ContextLifecycleNotifier* ExecutionContext::lifecycleNotifier()
+ContextLifecycleNotifier& ExecutionContext::lifecycleNotifier()
 {
-    return static_cast<ContextLifecycleNotifier*>(LifecycleContext::lifecycleNotifier());
+    return static_cast<ContextLifecycleNotifier&>(LifecycleContext<ExecutionContext>::lifecycleNotifier());
 }
 
 bool ExecutionContext::isIteratingOverObservers() const
@@ -385,9 +387,10 @@
 {
     m_sandboxFlags |= mask;
 
+    RELEASE_ASSERT(m_client);
     // The SandboxOrigin is stored redundantly in the security origin.
-    if (isSandboxed(SandboxOrigin) && securityOrigin() && !securityOrigin()->isUnique()) {
-        setSecurityOrigin(SecurityOrigin::createUnique());
+    if (isSandboxed(SandboxOrigin) && m_client->securityContext().securityOrigin() && !m_client->securityContext().securityOrigin()->isUnique()) {
+        m_client->securityContext().setSecurityOrigin(SecurityOrigin::createUnique());
         m_client->didUpdateSecurityOrigin();
     }
 }
diff --git a/Source/core/dom/ExecutionContext.h b/Source/core/dom/ExecutionContext.h
index b5b7bb9..ac26fdf 100644
--- a/Source/core/dom/ExecutionContext.h
+++ b/Source/core/dom/ExecutionContext.h
@@ -36,7 +36,7 @@
 #include "core/fetch/CrossOriginAccessControl.h"
 #include "core/frame/ConsoleTypes.h"
 #include "core/frame/DOMTimer.h"
-#include "core/platform/LifecycleContext.h"
+#include "platform/LifecycleContext.h"
 #include "weborigin/KURL.h"
 #include "wtf/HashSet.h"
 #include "wtf/OwnPtr.h"
@@ -56,10 +56,11 @@
 class ExecutionContextTask;
 class MessagePort;
 class PublicURLManager;
+class SecurityOrigin;
 class ScriptCallStack;
 class ScriptState;
 
-class ExecutionContext : public LifecycleContext, public SecurityContext {
+class ExecutionContext : public LifecycleContext<ExecutionContext> {
 public:
     ExecutionContext();
     virtual ~ExecutionContext();
@@ -69,7 +70,8 @@
     bool isDocument() const { return m_client && m_client->isDocument(); }
     bool isWorkerGlobalScope() { return m_client && m_client->isWorkerGlobalScope(); }
     bool isJSExecutionForbidden() { return m_client && m_client->isJSExecutionForbidden(); }
-    EventQueue* eventQueue() const;
+    SecurityOrigin* securityOrigin() const;
+    ContentSecurityPolicy* contentSecurityPolicy() const;
     const KURL& url() const;
     KURL completeURL(const String& url) const;
     void userEventWasHandled();
@@ -120,9 +122,13 @@
     bool isSandboxed(SandboxFlags mask) const { return m_sandboxFlags & mask; }
     void enforceSandboxFlags(SandboxFlags mask);
 
+    PassOwnPtr<LifecycleNotifier<ExecutionContext> > createLifecycleNotifier();
+
+    virtual EventQueue* eventQueue() const = 0;
+
 protected:
 
-    ContextLifecycleNotifier* lifecycleNotifier();
+    ContextLifecycleNotifier& lifecycleNotifier();
 
 private:
     friend class DOMTimer; // For installNewTimeout() and removeTimeoutByID() below.
@@ -133,7 +139,7 @@
 
     virtual void refExecutionContext() = 0;
     virtual void derefExecutionContext() = 0;
-    virtual PassOwnPtr<LifecycleNotifier> createLifecycleNotifier() OVERRIDE;
+    // LifecycleContext implementation.
 
     // Implementation details for DOMTimer. No other classes should call these functions.
     int installNewTimeout(PassOwnPtr<ScheduledAction>, int timeout, bool singleShot);
diff --git a/Source/core/dom/ExecutionContextClient.h b/Source/core/dom/ExecutionContextClient.h
index d27dec9..f9cd303 100644
--- a/Source/core/dom/ExecutionContextClient.h
+++ b/Source/core/dom/ExecutionContextClient.h
@@ -28,7 +28,8 @@
 #define ExecutionContextClient_h
 
 #include "core/frame/ConsoleTypes.h"
-#include "core/platform/LifecycleNotifier.h"
+#include "platform/LifecycleNotifier.h"
+#include "weborigin/KURL.h"
 #include "wtf/Forward.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/text/WTFString.h"
@@ -40,7 +41,7 @@
 class EventTarget;
 class ExecutionContextTask;
 class KURL;
-class LifecycleNotifier;
+template<class T> class LifecycleNotifier;
 class ScriptCallStack;
 class ScriptState;
 class SecurityContext;
@@ -51,25 +52,32 @@
 
     virtual bool isDocument() const { return false; }
     virtual bool isWorkerGlobalScope() const { return false; }
-
     virtual bool isJSExecutionForbidden() const = 0;
     virtual DOMWindow* executingWindow() { return 0; }
     virtual void userEventWasHandled() { }
     virtual String userAgent(const KURL&) const = 0;
     virtual void disableEval(const String& errorMessage) = 0;
-    virtual EventQueue* eventQueue() const = 0;
+    virtual SecurityContext& securityContext() = 0;
     virtual const KURL& virtualURL() const = 0;
     virtual KURL virtualCompleteURL(const String&) const = 0;
     virtual void addMessage(MessageSource, MessageLevel, const String& message, const String& sourceURL, unsigned lineNumber, ScriptState*) = 0;
+    virtual void reportBlockedScriptExecutionToInspector(const String& directiveText) = 0;
     virtual EventTarget* errorEventTarget() = 0;
     virtual void logExceptionToConsole(const String& errorMessage, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtr<ScriptCallStack>) = 0;
     virtual double timerAlignmentInterval() const = 0;
-    virtual PassOwnPtr<LifecycleNotifier> createLifecycleNotifier() = 0;
     virtual void didUpdateSecurityOrigin() = 0;
+
+    void addConsoleMessage(MessageSource source, MessageLevel level, const String& message, const String& sourceURL, unsigned lineNumber) { addMessage(source, level, message, sourceURL, lineNumber, 0); }
+    void addConsoleMessage(MessageSource source, MessageLevel level, const String& message, ScriptState* state = 0) { addMessage(source, level, message, String(), 0, state); }
+    KURL contextURL() const { return virtualURL(); }
+    KURL contextCompleteURL(const String& url) const { return virtualCompleteURL(url); }
+
 protected:
     virtual ~ExecutionContextClient() { }
+
 };
 
+
 } // namespace
 
 #endif
diff --git a/Source/core/dom/FullscreenElementStack.cpp b/Source/core/dom/FullscreenElementStack.cpp
index 550bd42..6d0b514 100644
--- a/Source/core/dom/FullscreenElementStack.cpp
+++ b/Source/core/dom/FullscreenElementStack.cpp
@@ -113,7 +113,7 @@
 
 inline Document* FullscreenElementStack::document()
 {
-    return toDocument(executionContext());
+    return lifecycleContext();
 }
 
 void FullscreenElementStack::documentWasDetached()
@@ -171,7 +171,7 @@
 
         // 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()) {
+        for (Frame* descendant = document()->frame() ? document()->frame()->tree().traverseNext() : 0; descendant; descendant = descendant->tree().traverseNext()) {
             if (fullscreenElementFrom(descendant->document())) {
                 descendentHasNonEmptyStack = true;
                 break;
@@ -285,7 +285,7 @@
     // 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()) {
+    for (Frame* descendant = document()->frame() ?  document()->frame()->tree().traverseNext() : 0; descendant; descendant = descendant->tree().traverseNext()) {
         if (fullscreenElementFrom(descendant->document()))
             descendants.prepend(descendant->document());
     }
@@ -353,7 +353,7 @@
 
 void FullscreenElementStack::webkitWillEnterFullScreenForElement(Element* element)
 {
-    if (!document()->confusingAndOftenMisusedAttached())
+    if (!document()->isActive())
         return;
 
     ASSERT(element);
@@ -393,7 +393,7 @@
     if (!m_fullScreenElement)
         return;
 
-    if (!document()->confusingAndOftenMisusedAttached())
+    if (!document()->isActive())
         return;
 
     m_fullScreenElement->didBecomeFullscreenElement();
@@ -406,7 +406,7 @@
     if (!m_fullScreenElement)
         return;
 
-    if (!document()->confusingAndOftenMisusedAttached())
+    if (!document()->isActive())
         return;
 
     m_fullScreenElement->willStopBeingFullscreenElement();
@@ -417,7 +417,7 @@
     if (!m_fullScreenElement)
         return;
 
-    if (!document()->confusingAndOftenMisusedAttached())
+    if (!document()->isActive())
         return;
 
     m_fullScreenElement->setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(false);
diff --git a/Source/core/dom/GlobalEventHandlers.h b/Source/core/dom/GlobalEventHandlers.h
index 4df0ef0..8da83b9 100644
--- a/Source/core/dom/GlobalEventHandlers.h
+++ b/Source/core/dom/GlobalEventHandlers.h
@@ -30,9 +30,68 @@
 #ifndef GlobalEventHandlers_h
 #define GlobalEventHandlers_h
 
+#include "core/events/EventTarget.h"
+
 namespace WebCore {
 
 namespace GlobalEventHandlers {
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(abort);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(blur);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(cancel);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(canplay);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(canplaythrough);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(change);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(click);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(close);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(contextmenu);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(cuechange);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(dblclick);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(drag);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(dragend);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(dragenter);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(dragleave);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(dragover);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(dragstart);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(drop);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(durationchange);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(emptied);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(ended);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(error);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(focus);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(input);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(invalid);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(keydown);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(keypress);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(keyup);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(load);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(loadeddata);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(loadedmetadata);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(loadstart);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(mousedown);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(mouseenter);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(mouseleave);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(mousemove);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(mouseout);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(mouseover);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(mouseup);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(mousewheel);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pause);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(play);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(playing);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(progress);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(ratechange);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(reset);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(scroll);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(seeked);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(seeking);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(select);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(show);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(stalled);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(submit);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(suspend);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(timeupdate);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(volumechange);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(waiting);
 }
 
 } // namespace
diff --git a/Source/core/dom/MutationObserverInterestGroup.cpp b/Source/core/dom/MutationObserverInterestGroup.cpp
index 7169bb2..48cd761 100644
--- a/Source/core/dom/MutationObserverInterestGroup.cpp
+++ b/Source/core/dom/MutationObserverInterestGroup.cpp
@@ -38,11 +38,11 @@
 
 namespace WebCore {
 
-PassOwnPtr<MutationObserverInterestGroup> MutationObserverInterestGroup::createIfNeeded(Node* target, MutationObserver::MutationType type, MutationRecordDeliveryOptions oldValueFlag, const QualifiedName* attributeName)
+PassOwnPtr<MutationObserverInterestGroup> MutationObserverInterestGroup::createIfNeeded(Node& target, MutationObserver::MutationType type, MutationRecordDeliveryOptions oldValueFlag, const QualifiedName* attributeName)
 {
     ASSERT((type == MutationObserver::Attributes && attributeName) || !attributeName);
     HashMap<MutationObserver*, MutationRecordDeliveryOptions> observers;
-    target->getRegisteredMutationObserversOfType(observers, type, attributeName);
+    target.getRegisteredMutationObserversOfType(observers, type, attributeName);
     if (observers.isEmpty())
         return nullptr;
 
diff --git a/Source/core/dom/MutationObserverInterestGroup.h b/Source/core/dom/MutationObserverInterestGroup.h
index 4950f31..b149afc 100644
--- a/Source/core/dom/MutationObserverInterestGroup.h
+++ b/Source/core/dom/MutationObserverInterestGroup.h
@@ -42,26 +42,26 @@
 
 class MutationObserverInterestGroup {
 public:
-    static PassOwnPtr<MutationObserverInterestGroup> createForChildListMutation(Node* target)
+    static PassOwnPtr<MutationObserverInterestGroup> createForChildListMutation(Node& target)
     {
-        if (!target->document().hasMutationObserversOfType(MutationObserver::ChildList))
+        if (!target.document().hasMutationObserversOfType(MutationObserver::ChildList))
             return nullptr;
 
         MutationRecordDeliveryOptions oldValueFlag = 0;
         return createIfNeeded(target, MutationObserver::ChildList, oldValueFlag);
     }
 
-    static PassOwnPtr<MutationObserverInterestGroup> createForCharacterDataMutation(Node* target)
+    static PassOwnPtr<MutationObserverInterestGroup> createForCharacterDataMutation(Node& target)
     {
-        if (!target->document().hasMutationObserversOfType(MutationObserver::CharacterData))
+        if (!target.document().hasMutationObserversOfType(MutationObserver::CharacterData))
             return nullptr;
 
         return createIfNeeded(target, MutationObserver::CharacterData, MutationObserver::CharacterDataOldValue);
     }
 
-    static PassOwnPtr<MutationObserverInterestGroup> createForAttributesMutation(Node* target, const QualifiedName& attributeName)
+    static PassOwnPtr<MutationObserverInterestGroup> createForAttributesMutation(Node& target, const QualifiedName& attributeName)
     {
-        if (!target->document().hasMutationObserversOfType(MutationObserver::Attributes))
+        if (!target.document().hasMutationObserversOfType(MutationObserver::Attributes))
             return nullptr;
 
         return createIfNeeded(target, MutationObserver::Attributes, MutationObserver::AttributeOldValue, &attributeName);
@@ -71,7 +71,7 @@
     void enqueueMutationRecord(PassRefPtr<MutationRecord>);
 
 private:
-    static PassOwnPtr<MutationObserverInterestGroup> createIfNeeded(Node* target, MutationObserver::MutationType, MutationRecordDeliveryOptions oldValueFlag, const QualifiedName* attributeName = 0);
+    static PassOwnPtr<MutationObserverInterestGroup> createIfNeeded(Node& target, MutationObserver::MutationType, MutationRecordDeliveryOptions oldValueFlag, const QualifiedName* attributeName = 0);
     MutationObserverInterestGroup(HashMap<MutationObserver*, MutationRecordDeliveryOptions>& observers, MutationRecordDeliveryOptions oldValueFlag);
 
     bool hasOldValue(MutationRecordDeliveryOptions options) { return options & m_oldValueFlag; }
diff --git a/Source/core/dom/NamedFlowCollection.cpp b/Source/core/dom/NamedFlowCollection.cpp
index 49a975c..b9ae4b3 100644
--- a/Source/core/dom/NamedFlowCollection.cpp
+++ b/Source/core/dom/NamedFlowCollection.cpp
@@ -41,7 +41,7 @@
 namespace WebCore {
 
 NamedFlowCollection::NamedFlowCollection(Document* document)
-    : ContextLifecycleObserver(document)
+    : DocumentLifecycleObserver(document)
 {
     ASSERT(RuntimeEnabledFeatures::cssRegionsEnabled());
 }
@@ -103,8 +103,7 @@
 
 Document* NamedFlowCollection::document() const
 {
-    ExecutionContext* context = ContextLifecycleObserver::executionContext();
-    return toDocument(context);
+    return lifecycleContext();
 }
 
 PassRefPtr<DOMNamedFlowCollection> NamedFlowCollection::createCSSOMSnapshot()
diff --git a/Source/core/dom/NamedFlowCollection.h b/Source/core/dom/NamedFlowCollection.h
index 8d8d32c..f9c4b9c 100644
--- a/Source/core/dom/NamedFlowCollection.h
+++ b/Source/core/dom/NamedFlowCollection.h
@@ -30,7 +30,7 @@
 #ifndef NamedFlowCollection_h
 #define NamedFlowCollection_h
 
-#include "core/dom/ContextLifecycleObserver.h"
+#include "core/dom/DocumentLifecycleObserver.h"
 #include "core/dom/NamedFlow.h"
 #include "wtf/Forward.h"
 #include "wtf/ListHashSet.h"
@@ -43,7 +43,7 @@
 class Document;
 class DOMNamedFlowCollection;
 
-class NamedFlowCollection : public RefCounted<NamedFlowCollection>, public ContextLifecycleObserver {
+class NamedFlowCollection : public RefCounted<NamedFlowCollection>, public DocumentLifecycleObserver {
 public:
     static PassRefPtr<NamedFlowCollection> create(Document* doc) { return adoptRef(new NamedFlowCollection(doc)); }
 
diff --git a/Source/core/dom/Node.cpp b/Source/core/dom/Node.cpp
index 9059929..89f80b5 100644
--- a/Source/core/dom/Node.cpp
+++ b/Source/core/dom/Node.cpp
@@ -48,6 +48,7 @@
 #include "core/dom/NodeRareData.h"
 #include "core/dom/NodeTraversal.h"
 #include "core/dom/ProcessingInstruction.h"
+#include "core/dom/Range.h"
 #include "core/dom/SelectorQuery.h"
 #include "core/dom/TagNodeList.h"
 #include "core/dom/TemplateContentDocumentFragment.h"
@@ -292,10 +293,8 @@
 
     RELEASE_ASSERT(!renderer());
 
-    if (!isContainerNode()) {
-        if (Document* document = documentInternal())
-            willBeDeletedFrom(document);
-    }
+    if (!isContainerNode())
+        willBeDeletedFromDocument();
 
     if (m_previous)
         m_previous->setNextSibling(0);
@@ -307,18 +306,19 @@
     InspectorCounters::decrementCounter(InspectorCounters::NodeCounter);
 }
 
-void Node::willBeDeletedFrom(Document* document)
+void Node::willBeDeletedFromDocument()
 {
+    Document* document = documentInternal();
+    if (!document)
+        return;
+
     if (hasEventTargetData()) {
-        if (document)
-            document->didRemoveEventTargetNode(this);
+        document->didRemoveEventTargetNode(this);
         clearEventTargetData();
     }
 
-    if (document) {
-        if (AXObjectCache* cache = document->existingAXObjectCache())
-            cache->remove(this);
-    }
+    if (AXObjectCache* cache = document->existingAXObjectCache())
+        cache->remove(this);
 }
 
 NodeRareData* Node::rareData() const
@@ -380,7 +380,7 @@
 
 PassRefPtr<NodeList> Node::childNodes()
 {
-    return ensureRareData().ensureNodeLists()->ensureChildNodeList(this);
+    return ensureRareData().ensureNodeLists().ensureChildNodeList(this);
 }
 
 Node *Node::lastDescendant() const
@@ -504,13 +504,13 @@
     while (node) {
         NodeType type = node->nodeType();
         if (type == ELEMENT_NODE)
-            toElement(node.get())->normalizeAttributes();
+            toElement(node)->normalizeAttributes();
 
         if (node == this)
             break;
 
         if (type == TEXT_NODE)
-            node = toText(node.get())->mergeNextSiblingNodesIfPossible();
+            node = toText(node)->mergeNextSiblingNodesIfPossible();
         else
             node = NodeTraversal::nextPostOrder(node.get());
     }
@@ -734,6 +734,11 @@
         markAncestorsWithChildNeedsStyleRecalc();
 }
 
+bool Node::inActiveDocument() const
+{
+    return inDocument() && document().isActive();
+}
+
 void Node::lazyAttach()
 {
     markAncestorsWithChildNeedsStyleRecalc();
@@ -1203,8 +1208,8 @@
         return 0;
 
     if (document().isHTMLDocument())
-        return ensureRareData().ensureNodeLists()->addCacheWithAtomicName<HTMLTagNodeList>(this, HTMLTagNodeListType, localName);
-    return ensureRareData().ensureNodeLists()->addCacheWithAtomicName<TagNodeList>(this, TagNodeListType, localName);
+        return ensureRareData().ensureNodeLists().addCacheWithAtomicName<HTMLTagNodeList>(this, HTMLTagNodeListType, localName);
+    return ensureRareData().ensureNodeLists().addCacheWithAtomicName<TagNodeList>(this, TagNodeListType, localName);
 }
 
 PassRefPtr<NodeList> Node::getElementsByTagNameNS(const AtomicString& namespaceURI, const AtomicString& localName)
@@ -1215,23 +1220,23 @@
     if (namespaceURI == starAtom)
         return getElementsByTagName(localName);
 
-    return ensureRareData().ensureNodeLists()->addCacheWithQualifiedName(this, namespaceURI.isEmpty() ? nullAtom : namespaceURI, localName);
+    return ensureRareData().ensureNodeLists().addCacheWithQualifiedName(this, namespaceURI.isEmpty() ? nullAtom : namespaceURI, localName);
 }
 
 PassRefPtr<NodeList> Node::getElementsByName(const String& elementName)
 {
-    return ensureRareData().ensureNodeLists()->addCacheWithAtomicName<NameNodeList>(this, NameNodeListType, elementName);
+    return ensureRareData().ensureNodeLists().addCacheWithAtomicName<NameNodeList>(this, NameNodeListType, elementName);
 }
 
 PassRefPtr<NodeList> Node::getElementsByClassName(const String& classNames)
 {
-    return ensureRareData().ensureNodeLists()->addCacheWithName<ClassNodeList>(this, ClassNodeListType, classNames);
+    return ensureRareData().ensureNodeLists().addCacheWithName<ClassNodeList>(this, ClassNodeListType, classNames);
 }
 
 PassRefPtr<RadioNodeList> Node::radioNodeList(const AtomicString& name)
 {
     ASSERT(hasTagName(formTag) || hasTagName(fieldsetTag));
-    return ensureRareData().ensureNodeLists()->addCacheWithAtomicName<RadioNodeList>(this, RadioNodeListType, name);
+    return ensureRareData().ensureNodeLists().addCacheWithAtomicName<RadioNodeList>(this, RadioNodeListType, name);
 }
 
 PassRefPtr<Element> Node::querySelector(const AtomicString& selectors, ExceptionState& es)
@@ -1241,7 +1246,7 @@
         return 0;
     }
 
-    SelectorQuery* selectorQuery = document().selectorQueryCache()->add(selectors, document(), es);
+    SelectorQuery* selectorQuery = document().selectorQueryCache().add(selectors, document(), es);
     if (!selectorQuery)
         return 0;
     return selectorQuery->queryFirst(this);
@@ -1254,7 +1259,7 @@
         return 0;
     }
 
-    SelectorQuery* selectorQuery = document().selectorQueryCache()->add(selectors, document(), es);
+    SelectorQuery* selectorQuery = document().selectorQueryCache().add(selectors, document(), es);
     if (!selectorQuery)
         return 0;
     return selectorQuery->queryAll(this);
@@ -1559,7 +1564,7 @@
         case ENTITY_NODE:
         case DOCUMENT_FRAGMENT_NODE: {
             RefPtr<ContainerNode> container = toContainerNode(this);
-            ChildListMutationScope mutation(this);
+            ChildListMutationScope mutation(*this);
             container->removeChildren();
             if (!text.isEmpty())
                 container->appendChild(document().createTextNode(text), es);
@@ -2160,7 +2165,7 @@
 void Node::registerMutationObserver(MutationObserver* observer, MutationObserverOptions options, const HashSet<AtomicString>& attributeFilter)
 {
     MutationObserverRegistration* registration = 0;
-    Vector<OwnPtr<MutationObserverRegistration> >& registry = ensureRareData().ensureMutationObserverData()->registry;
+    Vector<OwnPtr<MutationObserverRegistration> >& registry = ensureRareData().ensureMutationObserverData().registry;
     for (size_t i = 0; i < registry.size(); ++i) {
         if (registry[i]->observer() == observer) {
             registration = registry[i].get();
@@ -2197,7 +2202,7 @@
 
 void Node::registerTransientMutationObserver(MutationObserverRegistration* registration)
 {
-    ensureRareData().ensureMutationObserverData()->transientRegistry.add(registration);
+    ensureRareData().ensureMutationObserverData().transientRegistry.add(registration);
 }
 
 void Node::unregisterTransientMutationObserver(MutationObserverRegistration* registration)
@@ -2254,9 +2259,9 @@
 bool Node::dispatchEvent(PassRefPtr<Event> event)
 {
     if (event->isMouseEvent())
-        return EventDispatcher::dispatchEvent(this, MouseEventDispatchMediator::create(adoptRef(toMouseEvent(event.leakRef())), MouseEventDispatchMediator::SyntheticMouseEvent));
+        return EventDispatcher::dispatchEvent(this, MouseEventDispatchMediator::create(static_pointer_cast<MouseEvent>(event), MouseEventDispatchMediator::SyntheticMouseEvent));
     if (event->isTouchEvent())
-        return dispatchTouchEvent(adoptRef(toTouchEvent(event.leakRef())));
+        return dispatchTouchEvent(static_pointer_cast<TouchEvent>(event));
     return EventDispatcher::dispatchEvent(this, EventDispatchMediator::create(event));
 }
 
@@ -2345,7 +2350,7 @@
     if (eventType == EventTypeNames::keydown || eventType == EventTypeNames::keypress) {
         if (event->isKeyboardEvent()) {
             if (Frame* frame = document().frame())
-                frame->eventHandler()->defaultKeyboardEventHandler(toKeyboardEvent(event));
+                frame->eventHandler().defaultKeyboardEventHandler(toKeyboardEvent(event));
         }
     } else if (eventType == EventTypeNames::click) {
         int detail = event->isUIEvent() ? static_cast<UIEvent*>(event)->detail() : 0;
@@ -2357,7 +2362,7 @@
     } else if (eventType == EventTypeNames::textInput) {
         if (event->hasInterface(EventNames::TextEvent)) {
             if (Frame* frame = document().frame())
-                frame->eventHandler()->defaultTextInputEventHandler(toTextEvent(event));
+                frame->eventHandler().defaultTextInputEventHandler(toTextEvent(event));
         }
 #if OS(WIN)
     } else if (eventType == EventTypeNames::mousedown && event->isMouseEvent()) {
@@ -2372,7 +2377,7 @@
 
             if (renderer) {
                 if (Frame* frame = document().frame())
-                    frame->eventHandler()->startPanScrolling(renderer);
+                    frame->eventHandler().startPanScrolling(renderer);
             }
         }
 #endif
@@ -2385,9 +2390,10 @@
         while (startNode && !startNode->renderer())
             startNode = startNode->parentOrShadowHostNode();
 
-        if (startNode && startNode->renderer())
+        if (startNode && startNode->renderer()) {
             if (Frame* frame = document().frame())
-                frame->eventHandler()->defaultWheelEventHandler(startNode, wheelEvent);
+                frame->eventHandler().defaultWheelEventHandler(startNode, wheelEvent);
+        }
     } else if (event->type() == EventTypeNames::webkitEditableContentChanged) {
         dispatchInputEvent();
     }
diff --git a/Source/core/dom/Node.h b/Source/core/dom/Node.h
index 068334d..1fe0467 100644
--- a/Source/core/dom/Node.h
+++ b/Source/core/dom/Node.h
@@ -163,7 +163,6 @@
     static void dumpStatistics();
 
     virtual ~Node();
-    void willBeDeletedFrom(Document*);
 
     // DOM methods & attributes for Node
 
@@ -408,7 +407,6 @@
     void setV8CollectableDuringMinorGC(bool flag) { setFlag(flag, V8CollectableDuringMinorGCFlag); }
 
     void lazyAttach();
-    void lazyReattach();
 
     virtual void setFocus(bool flag);
     virtual void setActive(bool flag = true, bool pause = false);
@@ -482,6 +480,8 @@
 
     TreeScope& treeScope() const { return *m_treeScope; }
 
+    bool inActiveDocument() const;
+
     // Returns true if this node is associated with a document and is in its associated document's
     // node tree, false otherwise.
     bool inDocument() const
@@ -792,6 +792,8 @@
 
     virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const { }
 
+    void willBeDeletedFromDocument();
+
     bool hasRareData() const { return getFlag(HasRareDataFlag); }
 
     NodeRareData* rareData() const;
@@ -896,20 +898,15 @@
 
 inline void Node::lazyReattachIfAttached()
 {
-    if (confusingAndOftenMisusedAttached())
-        lazyReattach();
-}
-
-inline void Node::lazyReattach()
-{
     if (styleChangeType() == NeedsReattachStyleChange)
         return;
+    if (!inActiveDocument())
+        return;
 
     AttachContext context;
     context.performingReattach = true;
 
-    if (confusingAndOftenMisusedAttached())
-        detach(context);
+    detach(context);
     lazyAttach();
 }
 
@@ -932,8 +929,14 @@
 
 
 #define DEFINE_NODE_TYPE_CASTS(thisType, predicate) \
+    template<typename T> inline thisType* to##thisType(const RefPtr<T>& node) { return to##thisType(node.get()); } \
     DEFINE_TYPE_CASTS(thisType, Node, node, node->predicate, node.predicate)
 
+// This requires isClassName(const Node&).
+#define DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(thisType) \
+    template<typename T> inline thisType* to##thisType(const RefPtr<T>& node) { return to##thisType(node.get()); } \
+    DEFINE_TYPE_CASTS(thisType, Node, node, is##thisType(*node), is##thisType(node))
+
 } // namespace WebCore
 
 #ifndef NDEBUG
diff --git a/Source/core/dom/NodeRareData.h b/Source/core/dom/NodeRareData.h
index 120a15b..8d310c3 100644
--- a/Source/core/dom/NodeRareData.h
+++ b/Source/core/dom/NodeRareData.h
@@ -249,19 +249,19 @@
 
     void clearNodeLists() { m_nodeLists.clear(); }
     NodeListsNodeData* nodeLists() const { return m_nodeLists.get(); }
-    NodeListsNodeData* ensureNodeLists()
+    NodeListsNodeData& ensureNodeLists()
     {
         if (!m_nodeLists)
             m_nodeLists = NodeListsNodeData::create();
-        return m_nodeLists.get();
+        return *m_nodeLists;
     }
 
     NodeMutationObserverData* mutationObserverData() { return m_mutationObserverData.get(); }
-    NodeMutationObserverData* ensureMutationObserverData()
+    NodeMutationObserverData& ensureMutationObserverData()
     {
         if (!m_mutationObserverData)
             m_mutationObserverData = NodeMutationObserverData::create();
-        return m_mutationObserverData.get();
+        return *m_mutationObserverData;
     }
 
     unsigned connectedSubframeCount() const { return m_connectedFrameCount; }
diff --git a/Source/core/dom/Position.cpp b/Source/core/dom/Position.cpp
index 75d8070..4ceb136 100644
--- a/Source/core/dom/Position.cpp
+++ b/Source/core/dom/Position.cpp
@@ -161,7 +161,7 @@
 {
     switch (anchorType()) {
     case PositionIsOffsetInAnchor:
-        return m_anchorNode && m_anchorNode->isTextNode() ? toText(m_anchorNode.get()) : 0;
+        return m_anchorNode && m_anchorNode->isTextNode() ? toText(m_anchorNode) : 0;
     case PositionIsBeforeAnchor:
     case PositionIsAfterAnchor:
         return 0;
diff --git a/Source/core/dom/PresentationAttributeStyle.cpp b/Source/core/dom/PresentationAttributeStyle.cpp
index 8bc83cc..8adfd77 100644
--- a/Source/core/dom/PresentationAttributeStyle.cpp
+++ b/Source/core/dom/PresentationAttributeStyle.cpp
@@ -177,7 +177,7 @@
         style = cacheIterator->value->value;
         cacheCleaner.didHitPresentationAttributeCache();
     } else {
-        style = MutableStylePropertySet::create(element.isSVGElement() ? SVGAttributeMode : CSSAttributeMode);
+        style = MutableStylePropertySet::create(element.isSVGElement() ? SVGAttributeMode : HTMLAttributeMode);
         unsigned size = element.attributeCount();
         for (unsigned i = 0; i < size; ++i) {
             const Attribute* attribute = element.attributeItem(i);
diff --git a/Source/core/dom/Promise.idl b/Source/core/dom/Promise.idl
index 41f5d9f..77b3976 100644
--- a/Source/core/dom/Promise.idl
+++ b/Source/core/dom/Promise.idl
@@ -33,7 +33,6 @@
 [
    GlobalContext=Window&WorkerGlobalScope,
    CustomConstructor(PromiseInit init),
-   RuntimeEnabled=Promise
 ] interface Promise {
    [Custom] Promise then(optional AnyCallback fulfillCallback, optional AnyCallback rejectCallback);
    [Custom] Promise catch(optional AnyCallback rejectCallback);
diff --git a/Source/core/dom/QualifiedName.cpp b/Source/core/dom/QualifiedName.cpp
index b2e9369..21e97ae 100644
--- a/Source/core/dom/QualifiedName.cpp
+++ b/Source/core/dom/QualifiedName.cpp
@@ -45,7 +45,7 @@
     + XMLNames::XMLAttrsCount;
 
 struct QualifiedNameHashTraits : public HashTraits<QualifiedName::QualifiedNameImpl*> {
-    static const int minimumTableSize = WTF::HashTableCapacityForSize<staticQualifiedNamesCount>::value;
+    static const unsigned minimumTableSize = WTF::HashTableCapacityForSize<staticQualifiedNamesCount>::value;
 };
 
 typedef HashSet<QualifiedName::QualifiedNameImpl*, QualifiedNameHash, QualifiedNameHashTraits> QualifiedNameCache;
diff --git a/Source/core/dom/Range.cpp b/Source/core/dom/Range.cpp
index f7bb066..74a0ca9 100644
--- a/Source/core/dom/Range.cpp
+++ b/Source/core/dom/Range.cpp
@@ -304,7 +304,7 @@
         return false;
     }
 
-    if (!refNode->confusingAndOftenMisusedAttached() || refNode->document() != m_ownerDocument) {
+    if (!refNode->inActiveDocument() || refNode->document() != m_ownerDocument) {
         return false;
     }
 
@@ -332,7 +332,7 @@
         return 0;
     }
 
-    if (!refNode->confusingAndOftenMisusedAttached() || refNode->document() != m_ownerDocument) {
+    if (!refNode->inActiveDocument() || refNode->document() != m_ownerDocument) {
         es.throwUninformativeAndGenericDOMException(WrongDocumentError);
         return 0;
     }
@@ -367,12 +367,12 @@
         return NODE_BEFORE;
     }
 
-    if (!m_start.container() && refNode->confusingAndOftenMisusedAttached()) {
+    if (!m_start.container() && refNode->inActiveDocument()) {
         es.throwUninformativeAndGenericDOMException(InvalidStateError);
         return NODE_BEFORE;
     }
 
-    if (m_start.container() && !refNode->confusingAndOftenMisusedAttached()) {
+    if (m_start.container() && !refNode->inActiveDocument()) {
         // Firefox doesn't throw an exception for this case; it returns 0.
         return NODE_BEFORE;
     }
@@ -581,7 +581,7 @@
         return false;
     }
 
-    if (!refNode->confusingAndOftenMisusedAttached() || refNode->document() != m_ownerDocument) {
+    if (!refNode->inActiveDocument() || refNode->document() != m_ownerDocument) {
         // Firefox doesn't throw an exception for these cases; it returns false.
         return false;
     }
@@ -1025,7 +1025,7 @@
     RefPtr<Node> container;
     if (startIsText) {
         container = m_start.container();
-        RefPtr<Text> newText = toText(container.get())->splitText(m_start.offset(), es);
+        RefPtr<Text> newText = toText(container)->splitText(m_start.offset(), es);
         if (es.hadException())
             return;
 
@@ -1108,7 +1108,7 @@
 
     Node* element = m_start.container()->isElementNode() ? m_start.container() : m_start.container()->parentNode();
     if (!element || !element->isHTMLElement()) {
-        es.throwUninformativeAndGenericDOMException(NotSupportedError);
+        es.throwDOMException(NotSupportedError, ExceptionMessages::failedToExecute("createContextualFragment", "Range", "The range's container must be an HTML element."));
         return 0;
     }
 
@@ -1442,7 +1442,7 @@
     }
 
     while (Node* n = newParent->firstChild()) {
-        toContainerNode(newParent.get())->removeChild(n, es);
+        toContainerNode(newParent)->removeChild(n, es);
         if (es.hadException())
             return;
     }
diff --git a/Source/core/dom/RawDataDocumentParser.h b/Source/core/dom/RawDataDocumentParser.h
index b56a694..343842d 100644
--- a/Source/core/dom/RawDataDocumentParser.h
+++ b/Source/core/dom/RawDataDocumentParser.h
@@ -54,8 +54,6 @@
 
     virtual void insert(const SegmentedString&)
     {
-        // <https://bugs.webkit.org/show_bug.cgi?id=25397>: JS code can always call document.write, we need to handle it.
-        ASSERT_NOT_REACHED();
     }
 
     virtual void append(PassRefPtr<StringImpl>)
diff --git a/Source/core/dom/ScriptLoader.cpp b/Source/core/dom/ScriptLoader.cpp
index 7af7738..d90456f 100644
--- a/Source/core/dom/ScriptLoader.cpp
+++ b/Source/core/dom/ScriptLoader.cpp
@@ -308,7 +308,7 @@
 
     Frame* frame = contextDocument->frame();
 
-    bool shouldBypassMainWorldContentSecurityPolicy = (frame && frame->script()->shouldBypassMainWorldContentSecurityPolicy()) || elementDocument->contentSecurityPolicy()->allowScriptNonce(m_element->fastGetAttribute(HTMLNames::nonceAttr));
+    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;
@@ -331,7 +331,7 @@
         // Create a script from the script element node, using the script
         // block's source and the script block's type.
         // Note: This is where the script is compiled and actually executed.
-        frame->script()->executeScriptInMainWorld(sourceCode, corsCheck);
+        frame->script().executeScriptInMainWorld(sourceCode, corsCheck);
 
         if (isHTMLScriptLoader(m_element)) {
             ASSERT(contextDocument->currentScript() == m_element);
diff --git a/Source/core/dom/StyleEngine.cpp b/Source/core/dom/StyleEngine.cpp
index 25f0337..7c908b9 100644
--- a/Source/core/dom/StyleEngine.cpp
+++ b/Source/core/dom/StyleEngine.cpp
@@ -57,13 +57,14 @@
     , m_pendingStylesheets(0)
     , m_injectedStyleSheetCacheValid(false)
     , m_needsUpdateActiveStylesheetsOnStyleRecalc(false)
+    , m_documentStyleSheetCollection(document)
+    , m_needsDocumentStyleSheetsUpdate(true)
     , m_usesSiblingRules(false)
     , m_usesSiblingRulesOverride(false)
     , m_usesFirstLineRules(false)
     , m_usesFirstLetterRules(false)
     , m_usesRemUnits(false)
-    , m_documentStyleSheetCollection(document)
-    , m_needsDocumentStyleSheetsUpdate(true)
+    , m_maxDirectAdjacentSelectors(0)
 {
 }
 
@@ -159,12 +160,14 @@
     // Delay resetting the flags until after next style recalc since unapplying the style may not work without these set (this is true at least with before/after).
     m_usesSiblingRules = m_usesSiblingRules || features.usesSiblingRules();
     m_usesFirstLineRules = m_usesFirstLineRules || features.usesFirstLineRules();
+    m_maxDirectAdjacentSelectors = max(m_maxDirectAdjacentSelectors, features.maxDirectAdjacentSelectors());
 }
 
 void StyleEngine::resetCSSFeatureFlags(const RuleFeatureSet& features)
 {
     m_usesSiblingRules = features.usesSiblingRules();
     m_usesFirstLineRules = features.usesFirstLineRules();
+    m_maxDirectAdjacentSelectors = features.maxDirectAdjacentSelectors();
 }
 
 CSSStyleSheet* StyleEngine::pageUserSheet()
diff --git a/Source/core/dom/StyleEngine.h b/Source/core/dom/StyleEngine.h
index b7bfd78..0df22e4 100644
--- a/Source/core/dom/StyleEngine.h
+++ b/Source/core/dom/StyleEngine.h
@@ -94,6 +94,7 @@
 
     bool hasPendingSheets() const { return m_pendingStylesheets > 0; }
 
+    unsigned maxDirectAdjacentSelectors() const { return m_maxDirectAdjacentSelectors; }
     bool usesSiblingRules() const { return m_usesSiblingRules || m_usesSiblingRulesOverride; }
     void setUsesSiblingRulesOverride(bool b) { m_usesSiblingRulesOverride = b; }
     bool usesFirstLineRules() const { return m_usesFirstLineRules; }
@@ -155,6 +156,7 @@
     bool m_usesFirstLineRules;
     bool m_usesFirstLetterRules;
     bool m_usesRemUnits;
+    unsigned m_maxDirectAdjacentSelectors;
 };
 
 }
diff --git a/Source/core/dom/Text.cpp b/Source/core/dom/Text.cpp
index eab7ece..2d5d6d3 100644
--- a/Source/core/dom/Text.cpp
+++ b/Source/core/dom/Text.cpp
@@ -332,11 +332,11 @@
 
 void Text::updateTextRenderer(unsigned offsetOfReplacedData, unsigned lengthOfReplacedData, RecalcStyleBehavior recalcStyleBehavior)
 {
-    if (!confusingAndOftenMisusedAttached())
+    if (!inActiveDocument())
         return;
     RenderText* textRenderer = toRenderText(renderer());
     if (!textRenderer || !textRendererIsNeeded(NodeRenderingContext(this, textRenderer->style()))) {
-        lazyReattach();
+        lazyReattachIfAttached();
         // FIXME: Editing should be updated so this is not neccesary.
         if (recalcStyleBehavior == DeprecatedRecalcStyleImmediatlelyForEditing)
             document().updateStyleIfNeeded();
diff --git a/Source/core/dom/TextLinkColors.h b/Source/core/dom/TextLinkColors.h
index 6d2728c..a03a1b8 100644
--- a/Source/core/dom/TextLinkColors.h
+++ b/Source/core/dom/TextLinkColors.h
@@ -28,7 +28,7 @@
 #ifndef TextLinkColors_h
 #define TextLinkColors_h
 
-#include "core/platform/graphics/Color.h"
+#include "platform/graphics/Color.h"
 #include "wtf/Noncopyable.h"
 
 namespace WebCore {
diff --git a/Source/core/dom/TouchController.cpp b/Source/core/dom/TouchController.cpp
index ef6b65f..a24bc81 100644
--- a/Source/core/dom/TouchController.cpp
+++ b/Source/core/dom/TouchController.cpp
@@ -97,7 +97,7 @@
         scrollingCoordinator->touchEventTargetRectsDidChange(document);
     if (m_touchEventTargets->size())
         return;
-    for (const Frame* frame = page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
+    for (const Frame* frame = page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
         if (frame->document() && TouchController::from(frame->document())->hasTouchEventHandlers())
             return;
     }
diff --git a/Source/core/dom/TreeScope.cpp b/Source/core/dom/TreeScope.cpp
index 9fea036..8c11f4d 100644
--- a/Source/core/dom/TreeScope.cpp
+++ b/Source/core/dom/TreeScope.cpp
@@ -333,21 +333,20 @@
     return !rootNode()->isShadowRoot() || toShadowRoot(rootNode())->applyAuthorStyles();
 }
 
-void TreeScope::adoptIfNeeded(Node* node)
+void TreeScope::adoptIfNeeded(Node& node)
 {
     ASSERT(this);
-    ASSERT(node);
-    ASSERT(!node->isDocumentNode());
-    ASSERT_WITH_SECURITY_IMPLICATION(!node->m_deletionHasBegun);
-    TreeScopeAdopter adopter(node, this);
+    ASSERT(!node.isDocumentNode());
+    ASSERT_WITH_SECURITY_IMPLICATION(!node.m_deletionHasBegun);
+    TreeScopeAdopter adopter(node, *this);
     if (adopter.needsScopeChange())
         adopter.execute();
 }
 
 static Element* focusedFrameOwnerElement(Frame* focusedFrame, Frame* currentFrame)
 {
-    for (; focusedFrame; focusedFrame = focusedFrame->tree()->parent()) {
-        if (focusedFrame->tree()->parent() == currentFrame)
+    for (; focusedFrame; focusedFrame = focusedFrame->tree().parent()) {
+        if (focusedFrame->tree().parent() == currentFrame)
             return focusedFrame->ownerElement();
     }
     return 0;
@@ -487,7 +486,7 @@
     Element* result = 0;
     Node* root = rootNode();
     for (Element* element = ElementTraversal::firstWithin(root); element; element = ElementTraversal::next(element, root)) {
-        if (element->fastGetAttribute(accesskeyAttr) == key)
+        if (equalIgnoringCase(element->fastGetAttribute(accesskeyAttr), key))
             result = element;
         for (ShadowRoot* shadowRoot = element->youngestShadowRoot(); shadowRoot; shadowRoot = shadowRoot->olderShadowRoot()) {
             if (Element* shadowResult = shadowRoot->getElementByAccessKey(key))
diff --git a/Source/core/dom/TreeScope.h b/Source/core/dom/TreeScope.h
index 74798c7..664db15 100644
--- a/Source/core/dom/TreeScope.h
+++ b/Source/core/dom/TreeScope.h
@@ -90,7 +90,7 @@
     bool applyAuthorStyles() const;
 
     // Used by the basic DOM mutation methods (e.g., appendChild()).
-    void adoptIfNeeded(Node*);
+    void adoptIfNeeded(Node&);
 
     Node* rootNode() const { return m_rootNode; }
 
diff --git a/Source/core/dom/TreeScopeAdopter.cpp b/Source/core/dom/TreeScopeAdopter.cpp
index 309a0e5..6561b09 100644
--- a/Source/core/dom/TreeScopeAdopter.cpp
+++ b/Source/core/dom/TreeScopeAdopter.cpp
@@ -34,28 +34,28 @@
 
 namespace WebCore {
 
-void TreeScopeAdopter::moveTreeToNewScope(Node* root) const
+void TreeScopeAdopter::moveTreeToNewScope(Node& root) const
 {
     ASSERT(needsScopeChange());
 
-    m_oldScope->guardRef();
+    m_oldScope.guardRef();
 
     // If an element is moved from a document and then eventually back again the collection cache for
     // that element may contain stale data as changes made to it will have updated the DOMTreeVersion
     // of the document it was moved to. By increasing the DOMTreeVersion of the donating document here
     // we ensure that the collection cache will be invalidated as needed when the element is moved back.
-    Document* oldDocument = m_oldScope->documentScope();
+    Document* oldDocument = m_oldScope.documentScope();
     ASSERT(oldDocument);
-    Document* newDocument = m_newScope->documentScope();
+    Document* newDocument = m_newScope.documentScope();
     bool willMoveToNewDocument = oldDocument != newDocument;
     if (willMoveToNewDocument)
         oldDocument->incDOMTreeVersion();
 
-    for (Node* node = root; node; node = NodeTraversal::next(node, root)) {
-        updateTreeScope(node);
+    for (Node* node = &root; node; node = NodeTraversal::next(node, &root)) {
+        updateTreeScope(*node);
 
         if (willMoveToNewDocument)
-            moveNodeToNewDocument(node, oldDocument, newDocument);
+            moveNodeToNewDocument(*node, *oldDocument, newDocument);
         else if (node->hasRareData()) {
             NodeRareData* rareData = node->rareData();
             if (rareData->nodeLists())
@@ -68,25 +68,25 @@
         if (node->hasSyntheticAttrChildNodes()) {
             const Vector<RefPtr<Attr> >& attrs = toElement(node)->attrNodeList();
             for (unsigned i = 0; i < attrs.size(); ++i)
-                moveTreeToNewScope(attrs[i].get());
+                moveTreeToNewScope(*attrs[i]);
         }
 
         for (ShadowRoot* shadow = node->youngestShadowRoot(); shadow; shadow = shadow->olderShadowRoot()) {
-            shadow->setParentTreeScope(m_newScope);
+            shadow->setParentTreeScope(&m_newScope);
             if (willMoveToNewDocument)
-                moveTreeToNewDocument(shadow, oldDocument, newDocument);
+                moveTreeToNewDocument(*shadow, *oldDocument, newDocument);
         }
     }
 
-    m_oldScope->guardDeref();
+    m_oldScope.guardDeref();
 }
 
-void TreeScopeAdopter::moveTreeToNewDocument(Node* root, Document* oldDocument, Document* newDocument) const
+void TreeScopeAdopter::moveTreeToNewDocument(Node& root, Document& oldDocument, Document* newDocument) const
 {
-    for (Node* node = root; node; node = NodeTraversal::next(node, root)) {
-        moveNodeToNewDocument(node, oldDocument, newDocument);
+    for (Node* node = &root; node; node = NodeTraversal::next(node, &root)) {
+        moveNodeToNewDocument(*node, oldDocument, newDocument);
         for (ShadowRoot* shadow = node->youngestShadowRoot(); shadow; shadow = shadow->olderShadowRoot())
-            moveTreeToNewDocument(shadow, oldDocument, newDocument);
+            moveTreeToNewDocument(*shadow, oldDocument, newDocument);
     }
 }
 
@@ -102,37 +102,36 @@
 }
 #endif
 
-inline void TreeScopeAdopter::updateTreeScope(Node* node) const
+inline void TreeScopeAdopter::updateTreeScope(Node& node) const
 {
-    ASSERT(!node->isTreeScope());
-    ASSERT(node->treeScope() == m_oldScope);
-    m_newScope->guardRef();
-    m_oldScope->guardDeref();
-    node->setTreeScope(m_newScope);
+    ASSERT(!node.isTreeScope());
+    ASSERT(node.treeScope() == m_oldScope);
+    m_newScope.guardRef();
+    m_oldScope.guardDeref();
+    node.setTreeScope(&m_newScope);
 }
 
-inline void TreeScopeAdopter::moveNodeToNewDocument(Node* node, Document* oldDocument, Document* newDocument) const
+inline void TreeScopeAdopter::moveNodeToNewDocument(Node& node, Document& oldDocument, Document* newDocument) const
 {
-    ASSERT(!node->inDocument() || oldDocument != newDocument);
-    ASSERT(oldDocument);
+    ASSERT(!node.inDocument() || oldDocument != newDocument);
 
-    if (node->hasRareData()) {
-        NodeRareData* rareData = node->rareData();
+    if (node.hasRareData()) {
+        NodeRareData* rareData = node.rareData();
         if (rareData->nodeLists())
-            rareData->nodeLists()->adoptDocument(oldDocument, newDocument);
+            rareData->nodeLists()->adoptDocument(&oldDocument, newDocument);
     }
 
-    oldDocument->moveNodeIteratorsToNewDocument(node, newDocument);
+    oldDocument.moveNodeIteratorsToNewDocument(&node, newDocument);
 
-    if (node->isShadowRoot())
-        toShadowRoot(node)->setDocumentScope(newDocument);
+    if (node.isShadowRoot())
+        toShadowRoot(node).setDocumentScope(newDocument);
 
 #ifndef NDEBUG
     didMoveToNewDocumentWasCalled = false;
-    oldDocumentDidMoveToNewDocumentWasCalledWith = oldDocument;
+    oldDocumentDidMoveToNewDocumentWasCalledWith = &oldDocument;
 #endif
 
-    node->didMoveToNewDocument(*oldDocument);
+    node.didMoveToNewDocument(oldDocument);
     ASSERT(didMoveToNewDocumentWasCalled);
 }
 
diff --git a/Source/core/dom/TreeScopeAdopter.h b/Source/core/dom/TreeScopeAdopter.h
index a83d178..17742ba 100644
--- a/Source/core/dom/TreeScopeAdopter.h
+++ b/Source/core/dom/TreeScopeAdopter.h
@@ -33,7 +33,7 @@
 
 class TreeScopeAdopter {
 public:
-    explicit TreeScopeAdopter(Node* toAdopt, TreeScope* newScope);
+    TreeScopeAdopter(Node& toAdopt, TreeScope& newScope);
 
     void execute() const { moveTreeToNewScope(m_toAdopt); }
     bool needsScopeChange() const { return m_oldScope != m_newScope; }
@@ -45,23 +45,21 @@
 #endif
 
 private:
-    void updateTreeScope(Node*) const;
-    void moveTreeToNewScope(Node*) const;
-    void moveTreeToNewDocument(Node*, Document* oldDocument, Document* newDocument) const;
-    void moveNodeToNewDocument(Node*, Document* oldDocument, Document* newDocument) const;
+    void updateTreeScope(Node&) const;
+    void moveTreeToNewScope(Node&) const;
+    void moveTreeToNewDocument(Node&, Document& oldDocument, Document* newDocument) const;
+    void moveNodeToNewDocument(Node&, Document& oldDocument, Document* newDocument) const;
 
-    Node* m_toAdopt;
-    TreeScope* m_newScope;
-    TreeScope* m_oldScope;
+    Node& m_toAdopt;
+    TreeScope& m_newScope;
+    TreeScope& m_oldScope;
 };
 
-// FIXME: Should take |TreeScope&| instead of |TreeScope*|.
-inline TreeScopeAdopter::TreeScopeAdopter(Node* toAdopt, TreeScope* newScope)
+inline TreeScopeAdopter::TreeScopeAdopter(Node& toAdopt, TreeScope& newScope)
     : m_toAdopt(toAdopt)
     , m_newScope(newScope)
-    , m_oldScope(&toAdopt->treeScope())
+    , m_oldScope(toAdopt.treeScope())
 {
-    ASSERT(newScope);
 }
 
 }
diff --git a/Source/core/dom/ViewportDescription.cpp b/Source/core/dom/ViewportDescription.cpp
index 80a7e78..77f924e 100644
--- a/Source/core/dom/ViewportDescription.cpp
+++ b/Source/core/dom/ViewportDescription.cpp
@@ -28,11 +28,6 @@
 #include "config.h"
 #include "core/dom/ViewportDescription.h"
 
-#include "core/dom/Document.h"
-#include "core/page/Page.h"
-#include "core/page/Settings.h"
-#include "wtf/text/WTFString.h"
-
 using namespace std;
 
 namespace WebCore {
diff --git a/Source/core/dom/ViewportDescription.h b/Source/core/dom/ViewportDescription.h
index 8b51f94..96cccc0 100644
--- a/Source/core/dom/ViewportDescription.h
+++ b/Source/core/dom/ViewportDescription.h
@@ -31,12 +31,9 @@
 #include "core/page/PageScaleConstraints.h"
 #include "platform/Length.h"
 #include "platform/geometry/FloatSize.h"
-#include "wtf/Forward.h"
 
 namespace WebCore {
 
-class Document;
-
 struct ViewportDescription {
 
     enum Type {
diff --git a/Source/core/dom/custom/CustomElement.cpp b/Source/core/dom/custom/CustomElement.cpp
index a2a150c..39dd599 100644
--- a/Source/core/dom/custom/CustomElement.cpp
+++ b/Source/core/dom/custom/CustomElement.cpp
@@ -71,7 +71,9 @@
         DEFINE_STATIC_LOCAL(Vector<AtomicString>, reservedNames, ());
         if (reservedNames.isEmpty()) {
             reservedNames.append(MathMLNames::annotation_xmlTag.localName());
-            reservedNames.append(SVGNames::color_profileTag.localName());
+            // In principle, "color-profile" should exist in the SVGNames
+            // namespace, but we don't implement the color-profile element.
+            reservedNames.append("color-profile");
             reservedNames.append(SVGNames::font_faceTag.localName());
             reservedNames.append(SVGNames::font_face_srcTag.localName());
             reservedNames.append(SVGNames::font_face_uriTag.localName());
@@ -168,7 +170,7 @@
 {
     ASSERT(definition.get());
     DefinitionMap::ElementDefinitionHashMap::AddResult result = m_definitions.add(element, definition);
-    ASSERT(result.isNewEntry);
+    ASSERT_UNUSED(result, result.isNewEntry);
 }
 
 CustomElement::DefinitionMap& CustomElement::definitions()
diff --git a/Source/core/dom/custom/CustomElementDefinition.h b/Source/core/dom/custom/CustomElementDefinition.h
index 601f671..72e4121 100644
--- a/Source/core/dom/custom/CustomElementDefinition.h
+++ b/Source/core/dom/custom/CustomElementDefinition.h
@@ -39,12 +39,10 @@
 
 namespace WebCore {
 
-class CustomElementDefinition : public RefCounted<CustomElementDefinition> {
+class CustomElementDefinition FINAL : public RefCounted<CustomElementDefinition> {
 public:
     static PassRefPtr<CustomElementDefinition> create(const CustomElementDescriptor&, PassRefPtr<CustomElementLifecycleCallbacks>);
 
-    virtual ~CustomElementDefinition() { }
-
     const CustomElementDescriptor& descriptor() const { return m_descriptor; }
     CustomElementLifecycleCallbacks* callbacks() const { return m_callbacks.get(); }
 
diff --git a/Source/core/dom/custom/CustomElementObserver.cpp b/Source/core/dom/custom/CustomElementObserver.cpp
index 0710995..94247fc 100644
--- a/Source/core/dom/custom/CustomElementObserver.cpp
+++ b/Source/core/dom/custom/CustomElementObserver.cpp
@@ -58,13 +58,13 @@
 void CustomElementObserver::observe(Element* element)
 {
     ElementObserverMap::AddResult result = elementObservers().add(element, this);
-    ASSERT(result.isNewEntry);
+    ASSERT_UNUSED(result, result.isNewEntry);
 }
 
 void CustomElementObserver::unobserve(Element* element)
 {
     CustomElementObserver* observer = elementObservers().take(element);
-    ASSERT(observer == this);
+    ASSERT_UNUSED(observer, observer == this);
 }
 
 } // namespace WebCore
diff --git a/Source/core/dom/custom/CustomElementRegistry.h b/Source/core/dom/custom/CustomElementRegistry.h
index 11642dd..c6acc8e 100644
--- a/Source/core/dom/custom/CustomElementRegistry.h
+++ b/Source/core/dom/custom/CustomElementRegistry.h
@@ -47,13 +47,12 @@
 class Document;
 class ExceptionState;
 
-class CustomElementRegistry {
+class CustomElementRegistry FINAL {
     WTF_MAKE_NONCOPYABLE(CustomElementRegistry);
 protected:
     friend class CustomElementRegistrationContext;
 
     CustomElementRegistry() { }
-    virtual ~CustomElementRegistry() { }
 
     CustomElementDefinition* registerElement(Document*, CustomElementConstructorBuilder*, const AtomicString& name, CustomElement::NameSet validNames, ExceptionState&);
     CustomElementDefinition* find(const CustomElementDescriptor&) const;
diff --git a/Source/core/dom/custom/CustomElementUpgradeCandidateMap.cpp b/Source/core/dom/custom/CustomElementUpgradeCandidateMap.cpp
index c907831..df2033f 100644
--- a/Source/core/dom/custom/CustomElementUpgradeCandidateMap.cpp
+++ b/Source/core/dom/custom/CustomElementUpgradeCandidateMap.cpp
@@ -47,7 +47,7 @@
     observe(element);
 
     UpgradeCandidateMap::AddResult result = m_upgradeCandidates.add(element, descriptor);
-    ASSERT(result.isNewEntry);
+    ASSERT_UNUSED(result, result.isNewEntry);
 
     UnresolvedDefinitionMap::iterator it = m_unresolvedDefinitions.find(descriptor);
     if (it == m_unresolvedDefinitions.end())
diff --git a/Source/core/dom/shadow/ElementShadow.cpp b/Source/core/dom/shadow/ElementShadow.cpp
index 757e808..a75da1b 100644
--- a/Source/core/dom/shadow/ElementShadow.cpp
+++ b/Source/core/dom/shadow/ElementShadow.cpp
@@ -131,23 +131,23 @@
     removeAllShadowRoots();
 }
 
-ShadowRoot* ElementShadow::addShadowRoot(Element* shadowHost, ShadowRoot::ShadowRootType type)
+ShadowRoot* ElementShadow::addShadowRoot(Element& shadowHost, ShadowRoot::ShadowRootType type)
 {
-    RefPtr<ShadowRoot> shadowRoot = ShadowRoot::create(&shadowHost->document(), type);
+    RefPtr<ShadowRoot> shadowRoot = ShadowRoot::create(&shadowHost.document(), type);
 
-    shadowRoot->setParentOrShadowHostNode(shadowHost);
-    shadowRoot->setParentTreeScope(&shadowHost->treeScope());
+    shadowRoot->setParentOrShadowHostNode(&shadowHost);
+    shadowRoot->setParentTreeScope(&shadowHost.treeScope());
     m_shadowRoots.push(shadowRoot.get());
-    ChildNodeInsertionNotifier(shadowHost).notify(shadowRoot.get());
+    ChildNodeInsertionNotifier(shadowHost).notify(*shadowRoot);
     setNeedsDistributionRecalc();
-    shadowHost->lazyReattachIfAttached();
+    shadowHost.lazyReattachIfAttached();
 
     // addShadowRoot() affects apply-author-styles. However, we know that the youngest shadow root has not had any children yet.
     // The youngest shadow root's apply-author-styles is default (false). So we can just set m_applyAuthorStyles false.
     m_applyAuthorStyles = false;
 
-    shadowHost->didAddShadowRoot(*shadowRoot);
-    InspectorInstrumentation::didPushShadowRoot(shadowHost, shadowRoot.get());
+    shadowHost.didAddShadowRoot(*shadowRoot);
+    InspectorInstrumentation::didPushShadowRoot(&shadowHost, shadowRoot.get());
 
     return shadowRoot.get();
 }
@@ -156,20 +156,17 @@
 {
     // Dont protect this ref count.
     Element* shadowHost = host();
+    ASSERT(shadowHost);
 
     while (RefPtr<ShadowRoot> oldRoot = m_shadowRoots.head()) {
         InspectorInstrumentation::willPopShadowRoot(shadowHost, oldRoot.get());
         shadowHost->document().removeFocusedElementOfSubtree(oldRoot.get());
-
-        if (oldRoot->confusingAndOftenMisusedAttached())
-            oldRoot->detach();
-
         m_shadowRoots.removeHead();
         oldRoot->setParentOrShadowHostNode(0);
         oldRoot->setParentTreeScope(&shadowHost->document());
         oldRoot->setPrev(0);
         oldRoot->setNext(0);
-        ChildNodeRemovalNotifier(shadowHost).notify(oldRoot.get());
+        ChildNodeRemovalNotifier(*shadowHost).notify(*oldRoot);
     }
 }
 
@@ -189,10 +186,8 @@
     Node::AttachContext childrenContext(context);
     childrenContext.resolvedStyle = 0;
 
-    for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot()) {
-        if (root->confusingAndOftenMisusedAttached())
-            root->detach(childrenContext);
-    }
+    for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot())
+        root->detach(childrenContext);
 }
 
 void ElementShadow::removeAllEventListeners()
@@ -259,7 +254,7 @@
     for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot()) {
         HTMLShadowElement* firstActiveShadowInsertionPoint = 0;
 
-        const Vector<RefPtr<InsertionPoint> >& insertionPoints = root->childInsertionPoints();
+        const Vector<RefPtr<InsertionPoint> >& insertionPoints = root->descendantInsertionPoints();
         for (size_t i = 0; i < insertionPoints.size(); ++i) {
             InsertionPoint* point = insertionPoints[i].get();
             if (!point->isActive())
diff --git a/Source/core/dom/shadow/ElementShadow.h b/Source/core/dom/shadow/ElementShadow.h
index 1e915a3..a8e040e 100644
--- a/Source/core/dom/shadow/ElementShadow.h
+++ b/Source/core/dom/shadow/ElementShadow.h
@@ -51,7 +51,7 @@
     ShadowRoot* oldestShadowRoot() const { return m_shadowRoots.tail(); }
     ElementShadow* containingShadow() const;
 
-    ShadowRoot* addShadowRoot(Element* shadowHost, ShadowRoot::ShadowRootType);
+    ShadowRoot* addShadowRoot(Element& shadowHost, ShadowRoot::ShadowRootType);
 
     bool applyAuthorStyles() const { return m_applyAuthorStyles; }
     bool didAffectApplyAuthorStyles();
diff --git a/Source/core/dom/shadow/InsertionPoint.cpp b/Source/core/dom/shadow/InsertionPoint.cpp
index 673d040..3023d66 100644
--- a/Source/core/dom/shadow/InsertionPoint.cpp
+++ b/Source/core/dom/shadow/InsertionPoint.cpp
@@ -177,7 +177,7 @@
             rootOwner->setNeedsDistributionRecalc();
             if (isActive() && !m_registeredWithShadowRoot && insertionPoint->treeScope().rootNode() == root) {
                 m_registeredWithShadowRoot = true;
-                root->addInsertionPoint(this);
+                root->didAddInsertionPoint(this);
                 rootOwner->didAffectApplyAuthorStyles();
                 if (canAffectSelector())
                     rootOwner->willAffectSelector();
@@ -208,7 +208,7 @@
     if (m_registeredWithShadowRoot && insertionPoint->treeScope().rootNode() == root) {
         ASSERT(root);
         m_registeredWithShadowRoot = false;
-        root->removeInsertionPoint(this);
+        root->didRemoveInsertionPoint(this);
         if (rootOwner) {
             rootOwner->didAffectApplyAuthorStyles();
             if (canAffectSelector())
@@ -222,7 +222,7 @@
 void InsertionPoint::parseAttribute(const QualifiedName& name, const AtomicString& value)
 {
     if (name == reset_style_inheritanceAttr) {
-        if (!inDocument() || !confusingAndOftenMisusedAttached() || !isActive())
+        if (!inDocument() || !isActive())
             return;
         containingShadowRoot()->host()->setNeedsStyleRecalc();
     } else
diff --git a/Source/core/dom/shadow/ShadowRoot.cpp b/Source/core/dom/shadow/ShadowRoot.cpp
index b438adb..508585a 100644
--- a/Source/core/dom/shadow/ShadowRoot.cpp
+++ b/Source/core/dom/shadow/ShadowRoot.cpp
@@ -39,7 +39,7 @@
 #include "core/dom/shadow/InsertionPoint.h"
 #include "core/dom/shadow/ShadowRootRareData.h"
 #include "core/editing/markup.h"
-#include "core/platform/HistogramSupport.h"
+#include "public/platform/Platform.h"
 
 namespace WebCore {
 
@@ -73,7 +73,7 @@
 
     if (type == ShadowRoot::AuthorShadowRoot) {
         ShadowRootUsageOriginType usageType = document->url().protocolIsInHTTPFamily() ? ShadowRootUsageOriginWeb : ShadowRootUsageOriginNotWeb;
-        HistogramSupport::histogramEnumeration("WebCore.ShadowRoot.constructor", usageType, ShadowRootUsageOriginMax);
+        WebKit::Platform::current()->histogramEnumeration("WebCore.ShadowRoot.constructor", usageType, ShadowRootUsageOriginMax);
     }
 }
 
@@ -87,11 +87,11 @@
 
     documentInternal()->styleEngine()->didRemoveShadowRoot(this);
 
-    // We cannot let ContainerNode destructor call willBeDeletedFrom()
+    // We cannot let ContainerNode destructor call willBeDeletedFromDocument()
     // for this ShadowRoot instance because TreeScope destructor
     // clears Node::m_treeScope thus ContainerNode is no longer able
     // to access it Document reference after that.
-    willBeDeletedFrom(documentInternal());
+    willBeDeletedFromDocument();
 
     // We must remove all of our children first before the TreeScope destructor
     // runs so we don't go through TreeScopeAdopter for each child with a
@@ -145,7 +145,7 @@
         return;
     }
 
-    if (RefPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(markup, host(), AllowScriptingContent, es))
+    if (RefPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(markup, host(), AllowScriptingContent, "innerHTML", es))
         replaceChildrenWithFragment(this, fragment.release(), es);
 }
 
@@ -171,11 +171,6 @@
     StyleResolver* styleResolver = document().styleResolver();
     styleResolver->pushParentShadowRoot(*this);
 
-    if (!confusingAndOftenMisusedAttached()) {
-        attach();
-        return;
-    }
-
     // When we're set to lazyAttach we'll have a SubtreeStyleChange and we'll need
     // to promote the change to a Force for all our descendants so they get a
     // recalc and will attach.
@@ -201,6 +196,7 @@
     styleResolver->popParentShadowRoot(*this);
     clearNeedsStyleRecalc();
     clearChildNeedsStyleRecalc();
+    setAttached();
 }
 
 bool ShadowRoot::isActive() const
@@ -328,17 +324,17 @@
 
 bool ShadowRoot::containsShadowElements() const
 {
-    return m_shadowRootRareData ? m_shadowRootRareData->hasShadowElementChildren() : 0;
+    return m_shadowRootRareData ? m_shadowRootRareData->containsShadowElements() : 0;
 }
 
 bool ShadowRoot::containsContentElements() const
 {
-    return m_shadowRootRareData ? m_shadowRootRareData->hasContentElementChildren() : 0;
+    return m_shadowRootRareData ? m_shadowRootRareData->containsContentElements() : 0;
 }
 
 bool ShadowRoot::containsShadowRoots() const
 {
-    return m_shadowRootRareData ? m_shadowRootRareData->hasShadowRootChildren() : 0;
+    return m_shadowRootRareData ? m_shadowRootRareData->containsShadowRoots() : 0;
 }
 
 InsertionPoint* ShadowRoot::insertionPoint() const
@@ -353,21 +349,21 @@
     ensureShadowRootRareData()->setInsertionPoint(insertionPoint);
 }
 
-void ShadowRoot::addInsertionPoint(InsertionPoint* insertionPoint)
+void ShadowRoot::didAddInsertionPoint(InsertionPoint* insertionPoint)
 {
-    ensureShadowRootRareData()->addInsertionPoint(insertionPoint);
+    ensureShadowRootRareData()->didAddInsertionPoint(insertionPoint);
     invalidateChildInsertionPoints();
 }
 
-void ShadowRoot::removeInsertionPoint(InsertionPoint* insertionPoint)
+void ShadowRoot::didRemoveInsertionPoint(InsertionPoint* insertionPoint)
 {
-    m_shadowRootRareData->removeInsertionPoint(insertionPoint);
+    m_shadowRootRareData->didRemoveInsertionPoint(insertionPoint);
     invalidateChildInsertionPoints();
 }
 
 void ShadowRoot::addChildShadowRoot()
 {
-    ensureShadowRootRareData()->addChildShadowRoot();
+    ensureShadowRootRareData()->didAddChildShadowRoot();
 }
 
 void ShadowRoot::removeChildShadowRoot()
@@ -375,7 +371,7 @@
     // FIXME: Why isn't this an ASSERT?
     if (!m_shadowRootRareData)
         return;
-    m_shadowRootRareData->removeChildShadowRoot();
+    m_shadowRootRareData->didRemoveChildShadowRoot();
 }
 
 unsigned ShadowRoot::childShadowRootCount() const
@@ -386,15 +382,15 @@
 void ShadowRoot::invalidateChildInsertionPoints()
 {
     m_childInsertionPointsIsValid = false;
-    m_shadowRootRareData->clearChildInsertionPoints();
+    m_shadowRootRareData->clearDescendantInsertionPoints();
 }
 
-const Vector<RefPtr<InsertionPoint> >& ShadowRoot::childInsertionPoints()
+const Vector<RefPtr<InsertionPoint> >& ShadowRoot::descendantInsertionPoints()
 {
     DEFINE_STATIC_LOCAL(const Vector<RefPtr<InsertionPoint> >, emptyList, ());
 
     if (m_shadowRootRareData && m_childInsertionPointsIsValid)
-        return m_shadowRootRareData->childInsertionPoints();
+        return m_shadowRootRareData->descendantInsertionPoints();
 
     m_childInsertionPointsIsValid = true;
 
@@ -407,9 +403,9 @@
             insertionPoints.append(toInsertionPoint(element));
     }
 
-    ensureShadowRootRareData()->setChildInsertionPoints(insertionPoints);
+    ensureShadowRootRareData()->setDescendantInsertionPoints(insertionPoints);
 
-    return m_shadowRootRareData->childInsertionPoints();
+    return m_shadowRootRareData->descendantInsertionPoints();
 }
 
 StyleSheetList* ShadowRoot::styleSheets()
diff --git a/Source/core/dom/shadow/ShadowRoot.h b/Source/core/dom/shadow/ShadowRoot.h
index 738c7be..84ad90b 100644
--- a/Source/core/dom/shadow/ShadowRoot.h
+++ b/Source/core/dom/shadow/ShadowRoot.h
@@ -91,9 +91,9 @@
     InsertionPoint* insertionPoint() const;
     void setInsertionPoint(PassRefPtr<InsertionPoint>);
 
-    void addInsertionPoint(InsertionPoint*);
-    void removeInsertionPoint(InsertionPoint*);
-    const Vector<RefPtr<InsertionPoint> >& childInsertionPoints();
+    void didAddInsertionPoint(InsertionPoint*);
+    void didRemoveInsertionPoint(InsertionPoint*);
+    const Vector<RefPtr<InsertionPoint> >& descendantInsertionPoints();
 
     ShadowRootType type() const { return static_cast<ShadowRootType>(m_type); }
 
@@ -166,6 +166,12 @@
     return const_cast<ShadowRoot*>(toShadowRoot(static_cast<const Node*>(node)));
 }
 
+inline ShadowRoot& toShadowRoot(Node& node)
+{
+    ASSERT_WITH_SECURITY_IMPLICATION(node.isShadowRoot());
+    return static_cast<ShadowRoot&>(node);
+}
+
 inline const ShadowRoot& toShadowRoot(const Node& node)
 {
     ASSERT_WITH_SECURITY_IMPLICATION(node.isShadowRoot());
diff --git a/Source/core/dom/shadow/ShadowRoot.idl b/Source/core/dom/shadow/ShadowRoot.idl
index 502f939..fd06913 100644
--- a/Source/core/dom/shadow/ShadowRoot.idl
+++ b/Source/core/dom/shadow/ShadowRoot.idl
@@ -46,4 +46,5 @@
                              [Default=Undefined] optional long y);
 
     [RuntimeEnabled=ShadowDOM] readonly attribute StyleSheetList styleSheets;
+    [RuntimeEnabled=ShadowDOM] readonly attribute Element host;
 };
diff --git a/Source/core/dom/shadow/ShadowRootRareData.h b/Source/core/dom/shadow/ShadowRootRareData.h
index df74d2b..6ed6376 100644
--- a/Source/core/dom/shadow/ShadowRootRareData.h
+++ b/Source/core/dom/shadow/ShadowRootRareData.h
@@ -42,8 +42,8 @@
 class ShadowRootRareData {
 public:
     ShadowRootRareData()
-        : m_childShadowElementCount(0)
-        , m_childContentElementCount(0)
+        : m_descendantShadowElementCount(0)
+        , m_descendantContentElementCount(0)
         , m_childShadowRootCount(0)
     {
     }
@@ -51,55 +51,55 @@
     InsertionPoint* insertionPoint() const { return m_insertionPoint.get(); }
     void setInsertionPoint(PassRefPtr<InsertionPoint> insertionPoint) { m_insertionPoint = insertionPoint; }
 
-    void addInsertionPoint(InsertionPoint*);
-    void removeInsertionPoint(InsertionPoint*);
+    void didAddInsertionPoint(InsertionPoint*);
+    void didRemoveInsertionPoint(InsertionPoint*);
 
-    bool hasShadowElementChildren() const { return m_childShadowElementCount; }
-    bool hasContentElementChildren() const { return m_childContentElementCount; }
-    bool hasShadowRootChildren() const { return m_childShadowRootCount; }
+    bool containsShadowElements() const { return m_descendantShadowElementCount; }
+    bool containsContentElements() const { return m_descendantContentElementCount; }
+    bool containsShadowRoots() const { return m_childShadowRootCount; }
 
-    void addChildShadowRoot() { ++m_childShadowRootCount; }
-    void removeChildShadowRoot() { ASSERT(m_childShadowRootCount > 0); --m_childShadowRootCount; }
+    void didAddChildShadowRoot() { ++m_childShadowRootCount; }
+    void didRemoveChildShadowRoot() { ASSERT(m_childShadowRootCount > 0); --m_childShadowRootCount; }
 
     unsigned childShadowRootCount() const { return m_childShadowRootCount; }
 
-    const Vector<RefPtr<InsertionPoint> >& childInsertionPoints() { return m_childInsertionPoints; }
-    void setChildInsertionPoints(Vector<RefPtr<InsertionPoint> >& list) { m_childInsertionPoints.swap(list); }
-    void clearChildInsertionPoints() { m_childInsertionPoints.clear(); }
+    const Vector<RefPtr<InsertionPoint> >& descendantInsertionPoints() { return m_descendantInsertionPoints; }
+    void setDescendantInsertionPoints(Vector<RefPtr<InsertionPoint> >& list) { m_descendantInsertionPoints.swap(list); }
+    void clearDescendantInsertionPoints() { m_descendantInsertionPoints.clear(); }
 
     StyleSheetList* styleSheets() { return m_styleSheetList.get(); }
     void setStyleSheets(PassRefPtr<StyleSheetList> styleSheetList) { m_styleSheetList = styleSheetList; }
 
 private:
     RefPtr<InsertionPoint> m_insertionPoint;
-    unsigned m_childShadowElementCount;
-    unsigned m_childContentElementCount;
+    unsigned m_descendantShadowElementCount;
+    unsigned m_descendantContentElementCount;
     unsigned m_childShadowRootCount;
-    Vector<RefPtr<InsertionPoint> > m_childInsertionPoints;
+    Vector<RefPtr<InsertionPoint> > m_descendantInsertionPoints;
     RefPtr<StyleSheetList> m_styleSheetList;
 };
 
-inline void ShadowRootRareData::addInsertionPoint(InsertionPoint* point)
+inline void ShadowRootRareData::didAddInsertionPoint(InsertionPoint* point)
 {
     if (isHTMLShadowElement(point))
-        ++m_childShadowElementCount;
+        ++m_descendantShadowElementCount;
     else if (isHTMLContentElement(point))
-        ++m_childContentElementCount;
+        ++m_descendantContentElementCount;
     else
         ASSERT_NOT_REACHED();
 }
 
-inline void ShadowRootRareData::removeInsertionPoint(InsertionPoint* point)
+inline void ShadowRootRareData::didRemoveInsertionPoint(InsertionPoint* point)
 {
     if (isHTMLShadowElement(point))
-        --m_childShadowElementCount;
+        --m_descendantShadowElementCount;
     else if (isHTMLContentElement(point))
-        --m_childContentElementCount;
+        --m_descendantContentElementCount;
     else
         ASSERT_NOT_REACHED();
 
-    ASSERT(m_childContentElementCount >= 0);
-    ASSERT(m_childShadowElementCount >= 0);
+    ASSERT(m_descendantContentElementCount >= 0);
+    ASSERT(m_descendantShadowElementCount >= 0);
 }
 
 } // namespace WebCore