Merge from Chromium at DEPS revision 222756

This commit was generated by merge_to_master.py.

Change-Id: I085d892f6f1583a45f10eb394f195bbea5a334ef
diff --git a/Source/core/dom/Attr.cpp b/Source/core/dom/Attr.cpp
index bf990a3..0d20c05 100644
--- a/Source/core/dom/Attr.cpp
+++ b/Source/core/dom/Attr.cpp
@@ -37,9 +37,9 @@
 
 using namespace HTMLNames;
 
-Attr::Attr(Element* element, const QualifiedName& name)
-    : ContainerNode(element->document())
-    , m_element(element)
+Attr::Attr(Element& element, const QualifiedName& name)
+    : ContainerNode(&element.document())
+    , m_element(&element)
     , m_name(name)
     , m_ignoreChildrenChanged(0)
     , m_specified(true)
@@ -47,8 +47,8 @@
     ScriptWrappable::init(this);
 }
 
-Attr::Attr(Document* document, const QualifiedName& name, const AtomicString& standaloneValue)
-    : ContainerNode(document)
+Attr::Attr(Document& document, const QualifiedName& name, const AtomicString& standaloneValue)
+    : ContainerNode(&document)
     , m_element(0)
     , m_name(name)
     , m_standaloneValue(standaloneValue)
@@ -58,14 +58,14 @@
     ScriptWrappable::init(this);
 }
 
-PassRefPtr<Attr> Attr::create(Element* element, const QualifiedName& name)
+PassRefPtr<Attr> Attr::create(Element& element, const QualifiedName& name)
 {
     RefPtr<Attr> attr = adoptRef(new Attr(element, name));
     attr->createTextChild();
     return attr.release();
 }
 
-PassRefPtr<Attr> Attr::create(Document* document, const QualifiedName& name, const AtomicString& value)
+PassRefPtr<Attr> Attr::create(Document& document, const QualifiedName& name, const AtomicString& value)
 {
     RefPtr<Attr> attr = adoptRef(new Attr(document, name, value));
     attr->createTextChild();
@@ -80,12 +80,12 @@
 {
     ASSERT(refCount());
     if (!value().isEmpty()) {
-        RefPtr<Text> textNode = document()->createTextNode(value().string());
+        RefPtr<Text> textNode = document().createTextNode(value().string());
 
         // 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.get());
         setFirstChild(textNode.get());
         setLastChild(textNode.get());
     }
@@ -182,7 +182,7 @@
 
 bool Attr::isId() const
 {
-    return qualifiedName().matches(document()->idAttributeName());
+    return qualifiedName().matches(document().idAttributeName());
 }
 
 const AtomicString& Attr::value() const
diff --git a/Source/core/dom/Attr.h b/Source/core/dom/Attr.h
index 21b3685..bd9e7eb 100644
--- a/Source/core/dom/Attr.h
+++ b/Source/core/dom/Attr.h
@@ -42,8 +42,8 @@
 
 class Attr FINAL : public ContainerNode {
 public:
-    static PassRefPtr<Attr> create(Element*, const QualifiedName&);
-    static PassRefPtr<Attr> create(Document*, const QualifiedName&, const AtomicString& value);
+    static PassRefPtr<Attr> create(Element&, const QualifiedName&);
+    static PassRefPtr<Attr> create(Document&, const QualifiedName&, const AtomicString& value);
     virtual ~Attr();
 
     String name() const { return qualifiedName().toString(); }
@@ -70,8 +70,8 @@
     virtual void setPrefix(const AtomicString&, ExceptionState&) OVERRIDE;
 
 private:
-    Attr(Element*, const QualifiedName&);
-    Attr(Document*, const QualifiedName&, const AtomicString& value);
+    Attr(Element&, const QualifiedName&);
+    Attr(Document&, const QualifiedName&, const AtomicString& value);
 
     void createTextChild();
 
diff --git a/Source/core/dom/CDATASection.cpp b/Source/core/dom/CDATASection.cpp
index 5e19e27..ec61f09 100644
--- a/Source/core/dom/CDATASection.cpp
+++ b/Source/core/dom/CDATASection.cpp
@@ -26,13 +26,13 @@
 
 namespace WebCore {
 
-inline CDATASection::CDATASection(Document* document, const String& data)
+inline CDATASection::CDATASection(Document& document, const String& data)
     : Text(document, data, CreateText)
 {
     ScriptWrappable::init(this);
 }
 
-PassRefPtr<CDATASection> CDATASection::create(Document* document, const String& data)
+PassRefPtr<CDATASection> CDATASection::create(Document& document, const String& data)
 {
     return adoptRef(new CDATASection(document, data));
 }
diff --git a/Source/core/dom/CDATASection.h b/Source/core/dom/CDATASection.h
index 3adcd28..ed9075f 100644
--- a/Source/core/dom/CDATASection.h
+++ b/Source/core/dom/CDATASection.h
@@ -29,10 +29,10 @@
 
 class CDATASection FINAL : public Text {
 public:
-    static PassRefPtr<CDATASection> create(Document*, const String&);
+    static PassRefPtr<CDATASection> create(Document&, const String&);
 
 private:
-    CDATASection(Document*, const String&);
+    CDATASection(Document&, const String&);
 
     virtual String nodeName() const;
     virtual NodeType nodeType() const;
@@ -40,6 +40,18 @@
     virtual PassRefPtr<Text> cloneWithData(const String&) OVERRIDE;
 };
 
+inline CDATASection* toCDATASection(Node* node)
+{
+    ASSERT_WITH_SECURITY_IMPLICATION(!node || node->nodeType() == Node::CDATA_SECTION_NODE);
+    return static_cast<CDATASection*>(node);
+}
+
+inline const CDATASection* toCDATASection(const Node* node)
+{
+    ASSERT_WITH_SECURITY_IMPLICATION(!node || node->nodeType() == Node::CDATA_SECTION_NODE);
+    return static_cast<const CDATASection*>(node);
+}
+
 } // namespace WebCore
 
 #endif // CDATASection_h
diff --git a/Source/core/dom/CharacterData.cpp b/Source/core/dom/CharacterData.cpp
index 50b44c3..ecf9f6c 100644
--- a/Source/core/dom/CharacterData.cpp
+++ b/Source/core/dom/CharacterData.cpp
@@ -55,7 +55,7 @@
     unsigned oldLength = length();
 
     setDataAndUpdate(nonNullData, 0, oldLength, nonNullData.length());
-    document()->textRemoved(this, 0, oldLength);
+    document().textRemoved(this, 0, oldLength);
 }
 
 String CharacterData::substringData(unsigned offset, unsigned count, ExceptionState& es)
@@ -98,9 +98,9 @@
 
     ASSERT(!renderer() || isTextNode());
     if (isTextNode())
-        toText(this)->updateTextRenderer(oldLength, 0, DeprecatedAttachNow);
+        toText(this)->updateTextRenderer(oldLength, 0);
 
-    document()->incDOMTreeVersion();
+    document().incDOMTreeVersion();
 
     if (parentNode())
         parentNode()->childrenChanged();
@@ -108,16 +108,16 @@
     return characterLengthLimit;
 }
 
-void CharacterData::appendData(const String& data, AttachBehavior attachBehavior)
+void CharacterData::appendData(const String& data)
 {
     String newStr = m_data + data;
 
-    setDataAndUpdate(newStr, m_data.length(), 0, data.length(), attachBehavior);
+    setDataAndUpdate(newStr, m_data.length(), 0, data.length());
 
     // FIXME: Should we call textInserted here?
 }
 
-void CharacterData::insertData(unsigned offset, const String& data, ExceptionState& es, AttachBehavior attachBehavior)
+void CharacterData::insertData(unsigned offset, const String& data, ExceptionState& es, RecalcStyleBehavior recalcStyleBehavior)
 {
     if (offset > length()) {
         es.throwDOMException(IndexSizeError);
@@ -127,12 +127,12 @@
     String newStr = m_data;
     newStr.insert(data, offset);
 
-    setDataAndUpdate(newStr, offset, 0, data.length(), attachBehavior);
+    setDataAndUpdate(newStr, offset, 0, data.length(), recalcStyleBehavior);
 
-    document()->textInserted(this, offset, data.length());
+    document().textInserted(this, offset, data.length());
 }
 
-void CharacterData::deleteData(unsigned offset, unsigned count, ExceptionState& es, AttachBehavior attachBehavior)
+void CharacterData::deleteData(unsigned offset, unsigned count, ExceptionState& es, RecalcStyleBehavior recalcStyleBehavior)
 {
     if (offset > length()) {
         es.throwDOMException(IndexSizeError);
@@ -148,12 +148,12 @@
     String newStr = m_data;
     newStr.remove(offset, realCount);
 
-    setDataAndUpdate(newStr, offset, count, 0, attachBehavior);
+    setDataAndUpdate(newStr, offset, count, 0, recalcStyleBehavior);
 
-    document()->textRemoved(this, offset, realCount);
+    document().textRemoved(this, offset, realCount);
 }
 
-void CharacterData::replaceData(unsigned offset, unsigned count, const String& data, ExceptionState& es, AttachBehavior attachBehavior)
+void CharacterData::replaceData(unsigned offset, unsigned count, const String& data, ExceptionState& es)
 {
     if (offset > length()) {
         es.throwDOMException(IndexSizeError);
@@ -170,11 +170,11 @@
     newStr.remove(offset, realCount);
     newStr.insert(data, offset);
 
-    setDataAndUpdate(newStr, offset, count, data.length(), attachBehavior);
+    setDataAndUpdate(newStr, offset, count, data.length());
 
     // update the markers for spell checking and grammar checking
-    document()->textRemoved(this, offset, realCount);
-    document()->textInserted(this, offset, data.length());
+    document().textRemoved(this, offset, realCount);
+    document().textInserted(this, offset, data.length());
 }
 
 String CharacterData::nodeValue() const
@@ -192,22 +192,22 @@
     setData(nodeValue);
 }
 
-void CharacterData::setDataAndUpdate(const String& newData, unsigned offsetOfReplacedData, unsigned oldLength, unsigned newLength, AttachBehavior attachBehavior)
+void CharacterData::setDataAndUpdate(const String& newData, unsigned offsetOfReplacedData, unsigned oldLength, unsigned newLength, RecalcStyleBehavior recalcStyleBehavior)
 {
     String oldData = m_data;
     m_data = newData;
 
     ASSERT(!renderer() || isTextNode());
     if (isTextNode())
-        toText(this)->updateTextRenderer(offsetOfReplacedData, oldLength, attachBehavior);
+        toText(this)->updateTextRenderer(offsetOfReplacedData, oldLength, recalcStyleBehavior);
 
     if (nodeType() == PROCESSING_INSTRUCTION_NODE)
         toProcessingInstruction(this)->checkStyleSheet();
 
-    if (document()->frame())
-        document()->frame()->selection()->textWasReplaced(this, offsetOfReplacedData, oldLength, newLength);
+    if (document().frame())
+        document().frame()->selection().textWasReplaced(this, offsetOfReplacedData, oldLength, newLength);
 
-    document()->incDOMTreeVersion();
+    document().incDOMTreeVersion();
     didModifyData(oldData);
 }
 
@@ -220,11 +220,11 @@
         parentNode()->childrenChanged();
 
     if (!isInShadowTree()) {
-        if (document()->hasListenerType(Document::DOMCHARACTERDATAMODIFIED_LISTENER))
+        if (document().hasListenerType(Document::DOMCHARACTERDATAMODIFIED_LISTENER))
             dispatchScopedEvent(MutationEvent::create(eventNames().DOMCharacterDataModifiedEvent, true, 0, oldData, m_data));
         dispatchSubtreeModifiedEvent();
     }
-    InspectorInstrumentation::characterDataModified(document(), this);
+    InspectorInstrumentation::characterDataModified(&document(), this);
 }
 
 int CharacterData::maxCharacterOffset() const
diff --git a/Source/core/dom/CharacterData.h b/Source/core/dom/CharacterData.h
index 473456e..8c50a3f 100644
--- a/Source/core/dom/CharacterData.h
+++ b/Source/core/dom/CharacterData.h
@@ -37,10 +37,12 @@
     void setData(const String&);
     unsigned length() const { return m_data.length(); }
     String substringData(unsigned offset, unsigned count, ExceptionState&);
-    void appendData(const String&, AttachBehavior = AttachLazily);
-    void insertData(unsigned offset, const String&, ExceptionState&, AttachBehavior = AttachLazily);
-    void deleteData(unsigned offset, unsigned count, ExceptionState&, AttachBehavior = AttachLazily);
-    void replaceData(unsigned offset, unsigned count, const String&, ExceptionState&, AttachBehavior = AttachLazily);
+    void appendData(const String&);
+    void replaceData(unsigned offset, unsigned count, const String&, ExceptionState&);
+
+    enum RecalcStyleBehavior { DoNotRecalcStyle, DeprecatedRecalcStyleImmediatlelyForEditing };
+    void insertData(unsigned offset, const String&, ExceptionState&, RecalcStyleBehavior = DoNotRecalcStyle);
+    void deleteData(unsigned offset, unsigned count, ExceptionState&, RecalcStyleBehavior = DoNotRecalcStyle);
 
     bool containsOnlyWhitespace() const;
 
@@ -51,8 +53,8 @@
     unsigned parserAppendData(const String& string, unsigned offset, unsigned lengthLimit);
 
 protected:
-    CharacterData(TreeScope* treeScope, const String& text, ConstructionType type)
-        : Node(treeScope, type)
+    CharacterData(TreeScope& treeScope, const String& text, ConstructionType type)
+        : Node(&treeScope, type)
         , m_data(!text.isNull() ? text : emptyString())
     {
         ASSERT(type == CreateOther || type == CreateText || type == CreateEditingText);
@@ -74,9 +76,21 @@
     virtual bool isCharacterDataNode() const OVERRIDE FINAL { return true; }
     virtual int maxCharacterOffset() const OVERRIDE FINAL;
     virtual bool offsetInCharacters() const OVERRIDE FINAL;
-    void setDataAndUpdate(const String&, unsigned offsetOfReplacedData, unsigned oldLength, unsigned newLength, AttachBehavior = AttachLazily);
+    void setDataAndUpdate(const String&, unsigned offsetOfReplacedData, unsigned oldLength, unsigned newLength, RecalcStyleBehavior = DoNotRecalcStyle);
 };
 
+inline CharacterData* toCharacterData(Node* node)
+{
+    ASSERT_WITH_SECURITY_IMPLICATION(!node || node->isCharacterDataNode());
+    return static_cast<CharacterData*>(node);
+}
+
+inline const CharacterData* toCharacterData(const Node* node)
+{
+    ASSERT_WITH_SECURITY_IMPLICATION(!node || node->isCharacterDataNode());
+    return static_cast<const CharacterData*>(node);
+}
+
 } // namespace WebCore
 
 #endif // CharacterData_h
diff --git a/Source/core/dom/ChildListMutationScope.h b/Source/core/dom/ChildListMutationScope.h
index 78c63c3..442df97 100644
--- a/Source/core/dom/ChildListMutationScope.h
+++ b/Source/core/dom/ChildListMutationScope.h
@@ -77,7 +77,7 @@
 public:
     explicit ChildListMutationScope(Node* target)
     {
-        if (target->document()->hasMutationObserversOfType(MutationObserver::ChildList))
+        if (target->document().hasMutationObserversOfType(MutationObserver::ChildList))
             m_accumulator = ChildListMutationAccumulator::getOrCreate(target);
     }
 
diff --git a/Source/core/dom/ClassNodeList.cpp b/Source/core/dom/ClassNodeList.cpp
index f70f671..8b36218 100644
--- a/Source/core/dom/ClassNodeList.cpp
+++ b/Source/core/dom/ClassNodeList.cpp
@@ -37,7 +37,7 @@
 
 ClassNodeList::ClassNodeList(PassRefPtr<Node> rootNode, const String& classNames)
     : LiveNodeList(rootNode, ClassNodeListType, InvalidateOnClassAttrChange)
-    , m_classNames(classNames, document()->inQuirksMode())
+    , m_classNames(classNames, document().inQuirksMode())
     , m_originalClassNames(classNames)
 {
 }
diff --git a/Source/core/dom/Comment.cpp b/Source/core/dom/Comment.cpp
index 5b8374f..186008a 100644
--- a/Source/core/dom/Comment.cpp
+++ b/Source/core/dom/Comment.cpp
@@ -26,13 +26,13 @@
 
 namespace WebCore {
 
-inline Comment::Comment(Document* document, const String& text)
+inline Comment::Comment(Document& document, const String& text)
     : CharacterData(document, text, CreateOther)
 {
     ScriptWrappable::init(this);
 }
 
-PassRefPtr<Comment> Comment::create(Document* document, const String& text)
+PassRefPtr<Comment> Comment::create(Document& document, const String& text)
 {
     return adoptRef(new Comment(document, text));
 }
diff --git a/Source/core/dom/Comment.h b/Source/core/dom/Comment.h
index affc488..6b4a449 100644
--- a/Source/core/dom/Comment.h
+++ b/Source/core/dom/Comment.h
@@ -31,10 +31,10 @@
 
 class Comment FINAL : public CharacterData {
 public:
-    static PassRefPtr<Comment> create(Document*, const String&);
+    static PassRefPtr<Comment> create(Document&, const String&);
 
 private:
-    Comment(Document*, const String&);
+    Comment(Document&, const String&);
 
     virtual String nodeName() const;
     virtual NodeType nodeType() const;
@@ -42,6 +42,18 @@
     virtual bool childTypeAllowed(NodeType) const;
 };
 
+inline Comment* toComment(Node* node)
+{
+    ASSERT_WITH_SECURITY_IMPLICATION(!node || node->nodeType() == Node::COMMENT_NODE);
+    return static_cast<Comment*>(node);
+}
+
+inline const Comment* toComment(const Node* node)
+{
+    ASSERT_WITH_SECURITY_IMPLICATION(!node || node->nodeType() == Node::COMMENT_NODE);
+    return static_cast<const Comment*>(node);
+}
+
 } // namespace WebCore
 
 #endif // Comment_h
diff --git a/Source/core/dom/ContainerNode.cpp b/Source/core/dom/ContainerNode.cpp
index 94c37e5..de26f39 100644
--- a/Source/core/dom/ContainerNode.cpp
+++ b/Source/core/dom/ContainerNode.cpp
@@ -39,6 +39,7 @@
 #include "core/rendering/InlineTextBox.h"
 #include "core/rendering/RenderText.h"
 #include "core/rendering/RenderTheme.h"
+#include "core/rendering/RenderView.h"
 #include "core/rendering/RenderWidget.h"
 #include "wtf/Vector.h"
 
@@ -50,30 +51,12 @@
 static void dispatchChildRemovalEvents(Node*);
 static void updateTreeAfterInsertion(ContainerNode*, Node*);
 
-typedef pair<NodeCallback, RefPtr<Node> > CallbackInfo;
-typedef Vector<CallbackInfo> NodeCallbackQueue;
-
-static NodeCallbackQueue* s_postAttachCallbackQueue;
-
-static size_t s_attachDepth;
-
 ChildNodesLazySnapshot* ChildNodesLazySnapshot::latestSnapshot = 0;
 
 #ifndef NDEBUG
 unsigned NoEventDispatchAssertion::s_count = 0;
 #endif
 
-static inline void attachAfterInsertion(Node* node, AttachBehavior attachBehavior = AttachLazily)
-{
-    if (node->attached() || !node->parentNode() || !node->parentNode()->attached())
-        return;
-
-    if (attachBehavior == AttachLazily)
-        node->lazyAttach();
-    else
-        node->attach();
-}
-
 static void collectChildrenAndRemoveFromOldParent(Node* node, NodeVector& nodes, ExceptionState& es)
 {
     if (node->nodeType() != Node::DOCUMENT_FRAGMENT_NODE) {
@@ -101,7 +84,7 @@
     NodeVector children;
     getChildNodes(oldParent, children);
 
-    if (oldParent->document()->hasMutationObserversOfType(MutationObserver::ChildList)) {
+    if (oldParent->document().hasMutationObserversOfType(MutationObserver::ChildList)) {
         ChildListMutationScope mutation(oldParent);
         for (unsigned i = 0; i < children.size(); ++i)
             mutation.willRemoveChild(children[i].get());
@@ -116,12 +99,12 @@
         if (children[i]->attached())
             children[i]->detach();
         // FIXME: We need a no mutation event version of adoptNode.
-        RefPtr<Node> child = document()->adoptNode(children[i].release(), ASSERT_NO_EXCEPTION);
+        RefPtr<Node> child = document().adoptNode(children[i].release(), ASSERT_NO_EXCEPTION);
         // FIXME: Together with adoptNode above, the tree scope might get updated recursively twice
         // (if the document changed or oldParent was in a shadow tree, AND *this is in a shadow tree).
         // Can we do better?
-        treeScope()->adoptIfNeeded(child.get());
-        parserAppendChild(child.get(), DeprecatedAttachNow);
+        treeScope().adoptIfNeeded(child.get());
+        parserAppendChild(child.get());
     }
 }
 
@@ -146,8 +129,8 @@
 
 static inline bool isInTemplateContent(const Node* node)
 {
-    Document* document = node->document();
-    return document && document == document->templateDocument();
+    Document& document = node->document();
+    return &document == document.templateDocument();
 }
 
 static inline bool containsConsideringHostElements(const Node* newChild, const Node* newParent)
@@ -263,7 +246,7 @@
     if (!checkAcceptChildGuaranteedNodeTypes(this, newChild.get(), es))
         return;
 
-    InspectorInstrumentation::willInsertDOMNode(document(), this);
+    InspectorInstrumentation::willInsertDOMNode(&document(), this);
 
     ChildListMutationScope mutation(this);
     for (NodeVector::const_iterator it = targets.begin(); it != targets.end(); ++it) {
@@ -278,7 +261,7 @@
         if (child->parentNode())
             break;
 
-        treeScope()->adoptIfNeeded(child);
+        treeScope().adoptIfNeeded(child);
 
         insertBeforeCommon(next.get(), child);
 
@@ -314,7 +297,7 @@
     newChild->setNextSibling(nextChild);
 }
 
-void ContainerNode::parserInsertBefore(PassRefPtr<Node> newChild, Node* nextChild, AttachBehavior attachBehavior)
+void ContainerNode::parserInsertBefore(PassRefPtr<Node> newChild, Node* nextChild)
 {
     ASSERT(newChild);
     ASSERT(nextChild);
@@ -325,8 +308,8 @@
     if (nextChild->previousSibling() == newChild || nextChild == newChild) // nothing to do
         return;
 
-    if (document() != newChild->document())
-        document()->adoptNode(newChild.get(), ASSERT_NO_EXCEPTION);
+    if (&document() != &newChild->document())
+        document().adoptNode(newChild.get(), ASSERT_NO_EXCEPTION);
 
     insertBeforeCommon(nextChild, newChild.get());
 
@@ -337,8 +320,6 @@
     childrenChanged(true, newChild->previousSibling(), nextChild, 1);
 
     ChildNodeInsertionNotifier(this).notify(newChild.get());
-
-    attachAfterInsertion(newChild.get(), attachBehavior);
 }
 
 void ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionState& es)
@@ -393,7 +374,7 @@
     if (!checkReplaceChild(this, newChild.get(), oldChild, es))
         return;
 
-    InspectorInstrumentation::willInsertDOMNode(document(), this);
+    InspectorInstrumentation::willInsertDOMNode(&document(), this);
 
     // Add the new child(ren)
     for (NodeVector::const_iterator it = targets.begin(); it != targets.end(); ++it) {
@@ -408,7 +389,7 @@
         if (child->parentNode())
             break;
 
-        treeScope()->adoptIfNeeded(child);
+        treeScope().adoptIfNeeded(child);
 
         // Add child before "next".
         {
@@ -431,7 +412,7 @@
     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();
 }
 
@@ -440,7 +421,7 @@
     NodeVector children;
     getChildNodes(container, children);
 
-    container->document()->nodeChildrenWillBeRemoved(container);
+    container->document().nodeChildrenWillBeRemoved(container);
 
     ChildListMutationScope mutation(container);
     for (NodeVector::const_iterator it = children.begin(); it != children.end(); it++) {
@@ -476,9 +457,9 @@
 
     RefPtr<Node> child = oldChild;
 
-    document()->removeFocusedElementOfSubtree(child.get());
+    document().removeFocusedElementOfSubtree(child.get());
 
-    if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(document()))
+    if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(&document()))
         fullscreen->removeFullScreenElementOfSubtree(child.get());
 
     // Events fired when blurring currently focused node might have moved this
@@ -532,7 +513,7 @@
     oldChild->setNextSibling(0);
     oldChild->setParentOrShadowHostNode(0);
 
-    document()->adoptIfNeeded(oldChild);
+    document().adoptIfNeeded(oldChild);
 }
 
 void ContainerNode::parserRemoveChild(Node* oldChild)
@@ -565,7 +546,7 @@
     // The container node can be removed from event handlers.
     RefPtr<ContainerNode> protect(this);
 
-    if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(document()))
+    if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(&document()))
         fullscreen->removeFullScreenElementOfSubtree(this, true);
 
     // Do any prep work needed before actually starting to detach
@@ -576,7 +557,7 @@
     // children will be removed.
     // This must be later than willRemvoeChildren, which might change focus
     // state of a child.
-    document()->removeFocusedElementOfSubtree(this, true);
+    document().removeFocusedElementOfSubtree(this, true);
 
     NodeVector removedChildren;
     {
@@ -626,7 +607,7 @@
     if (!checkAcceptChildGuaranteedNodeTypes(this, newChild.get(), es))
         return;
 
-    InspectorInstrumentation::willInsertDOMNode(document(), this);
+    InspectorInstrumentation::willInsertDOMNode(&document(), this);
 
     // Now actually add the child(ren)
     ChildListMutationScope mutation(this);
@@ -639,7 +620,7 @@
         if (child->parentNode())
             break;
 
-        treeScope()->adoptIfNeeded(child);
+        treeScope().adoptIfNeeded(child);
 
         // Append child to the end of the list
         {
@@ -653,22 +634,22 @@
     dispatchSubtreeModifiedEvent();
 }
 
-void ContainerNode::parserAppendChild(PassRefPtr<Node> newChild, AttachBehavior attachBehavior)
+void ContainerNode::parserAppendChild(PassRefPtr<Node> newChild)
 {
     ASSERT(newChild);
     ASSERT(!newChild->parentNode()); // Use appendChild if you need to handle reparenting (and want DOM mutation events).
     ASSERT(!newChild->isDocumentFragment());
     ASSERT(!hasTagName(HTMLNames::templateTag));
 
-    if (document() != newChild->document())
-        document()->adoptNode(newChild.get(), ASSERT_NO_EXCEPTION);
+    if (&document() != &newChild->document())
+        document().adoptNode(newChild.get(), ASSERT_NO_EXCEPTION);
 
     Node* last = m_lastChild;
     {
         NoEventDispatchAssertion assertNoEventDispatch;
         // FIXME: This method should take a PassRefPtr.
         appendChildToContainer(newChild.get(), this);
-        treeScope()->adoptIfNeeded(newChild.get());
+        treeScope().adoptIfNeeded(newChild.get());
     }
 
     newChild->updateAncestorConnectedSubframeCountForInsertion();
@@ -677,47 +658,6 @@
 
     childrenChanged(true, last, 0, 1);
     ChildNodeInsertionNotifier(this).notify(newChild.get());
-
-    attachAfterInsertion(newChild.get(), attachBehavior);
-}
-
-void ContainerNode::suspendPostAttachCallbacks()
-{
-    ++s_attachDepth;
-}
-
-void ContainerNode::resumePostAttachCallbacks()
-{
-    if (s_attachDepth == 1) {
-        RefPtr<ContainerNode> protect(this);
-
-        if (s_postAttachCallbackQueue)
-            dispatchPostAttachCallbacks();
-    }
-    --s_attachDepth;
-}
-
-void ContainerNode::queuePostAttachCallback(NodeCallback callback, Node* node)
-{
-    if (!s_postAttachCallbackQueue)
-        s_postAttachCallbackQueue = new NodeCallbackQueue;
-    s_postAttachCallbackQueue->append(CallbackInfo(callback, node));
-}
-
-bool ContainerNode::postAttachCallbacksAreSuspended()
-{
-    return s_attachDepth;
-}
-
-void ContainerNode::dispatchPostAttachCallbacks()
-{
-    // We recalculate size() each time through the loop because a callback
-    // can add more callbacks to the end of the queue.
-    for (size_t i = 0; i < s_postAttachCallbackQueue->size(); ++i) {
-        const CallbackInfo& info = (*s_postAttachCallbackQueue)[i];
-        info.first(info.second.get());
-    }
-    s_postAttachCallbackQueue->clear();
 }
 
 void ContainerNode::attach(const AttachContext& context)
@@ -736,9 +676,9 @@
 
 void ContainerNode::childrenChanged(bool changedByParser, Node*, Node*, int childCountDelta)
 {
-    document()->incDOMTreeVersion();
+    document().incDOMTreeVersion();
     if (!changedByParser && childCountDelta)
-        document()->updateRangesAfterChildrenChanged(this);
+        document().updateRangesAfterChildrenChanged(this);
     invalidateNodeListCachesInAncestors();
 }
 
@@ -805,8 +745,8 @@
 
     // If the target doesn't have any children or siblings that could be used to calculate the scroll position, we must be
     // at the end of the document. Scroll to the bottom. FIXME: who said anything about scrolling?
-    if (!o && document()->view()) {
-        point = FloatPoint(0, document()->view()->contentsHeight());
+    if (!o && document().view()) {
+        point = FloatPoint(0, document().view()->contentsHeight());
         return true;
     }
     return false;
@@ -992,7 +932,7 @@
     ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
 
     RefPtr<Node> c = child;
-    RefPtr<Document> document = child->document();
+    RefPtr<Document> document = &child->document();
 
     if (c->parentNode() && document->hasListenerType(Document::DOMNODEINSERTED_LISTENER))
         c->dispatchScopedEvent(MutationEvent::create(eventNames().DOMNodeInsertedEvent, true, c->parentNode()));
@@ -1007,16 +947,16 @@
 static void dispatchChildRemovalEvents(Node* child)
 {
     if (child->isInShadowTree()) {
-        InspectorInstrumentation::willRemoveDOMNode(child->document(), child);
+        InspectorInstrumentation::willRemoveDOMNode(&child->document(), child);
         return;
     }
 
     ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
 
-    InspectorInstrumentation::willRemoveDOMNode(child->document(), child);
+    InspectorInstrumentation::willRemoveDOMNode(&child->document(), child);
 
     RefPtr<Node> c = child;
-    RefPtr<Document> document = child->document();
+    RefPtr<Document> document = &child->document();
 
     // dispatch pre-removal mutation events
     if (c->parentNode() && document->hasListenerType(Document::DOMNODEREMOVED_LISTENER))
@@ -1040,9 +980,6 @@
 
     ChildNodeInsertionNotifier(parent).notify(child);
 
-    // FIXME: Decide if it's safe to go through ::insertedInto while aleady attached() and then move this first.
-    attachAfterInsertion(child);
-
     dispatchChildInsertionEvents(child);
 }
 
diff --git a/Source/core/dom/ContainerNode.h b/Source/core/dom/ContainerNode.h
index 7ed7733..80b9c88 100644
--- a/Source/core/dom/ContainerNode.h
+++ b/Source/core/dom/ContainerNode.h
@@ -35,8 +35,6 @@
 class FloatPoint;
 class HTMLCollection;
 
-typedef void (*NodeCallback)(Node*);
-
 namespace Private {
     template<class GenericNode, class GenericNodeContainer>
     void addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, GenericNodeContainer*);
@@ -79,7 +77,6 @@
 };
 
 class ContainerNode : public Node {
-    friend class PostAttachCallbackDisabler;
 public:
     virtual ~ContainerNode();
 
@@ -107,9 +104,9 @@
     // These methods are only used during parsing.
     // They don't send DOM mutation events or handle reparenting.
     // However, arbitrary code may be run by beforeload handlers.
-    void parserAppendChild(PassRefPtr<Node>, AttachBehavior = AttachLazily);
+    void parserAppendChild(PassRefPtr<Node>);
     void parserRemoveChild(Node*);
-    void parserInsertBefore(PassRefPtr<Node> newChild, Node* refChild, AttachBehavior = AttachLazily);
+    void parserInsertBefore(PassRefPtr<Node> newChild, Node* refChild);
 
     void removeChildren();
     void takeAllChildrenFrom(ContainerNode*);
@@ -132,14 +129,11 @@
 
     void disconnectDescendantFrames();
 
-    virtual bool childShouldCreateRenderer(const NodeRenderingContext&) const { return true; }
+    virtual bool childShouldCreateRenderer(const Node& child) const { return true; }
 
 protected:
     ContainerNode(TreeScope*, ConstructionType = CreateContainer);
 
-    static void queuePostAttachCallback(NodeCallback, Node*);
-    static bool postAttachCallbacksAreSuspended();
-
     template<class GenericNode, class GenericNodeContainer>
     friend void appendChildToContainer(GenericNode* child, GenericNodeContainer*);
 
@@ -157,11 +151,6 @@
     void attachChildren(const AttachContext& = AttachContext());
     void detachChildren(const AttachContext& = AttachContext());
 
-    static void dispatchPostAttachCallbacks();
-
-    void suspendPostAttachCallbacks();
-    void resumePostAttachCallbacks();
-
     bool getUpperLeftCorner(FloatPoint&) const;
     bool getLowerRightCorner(FloatPoint&) const;
 
@@ -331,24 +320,6 @@
     ChildNodesLazySnapshot* m_nextSnapshot;
 };
 
-class PostAttachCallbackDisabler {
-public:
-    PostAttachCallbackDisabler(ContainerNode* node)
-        : m_node(node)
-    {
-        ASSERT(m_node);
-        m_node->suspendPostAttachCallbacks();
-    }
-
-    ~PostAttachCallbackDisabler()
-    {
-        m_node->resumePostAttachCallbacks();
-    }
-
-private:
-    ContainerNode* m_node;
-};
-
 } // namespace WebCore
 
 #endif // ContainerNode_h
diff --git a/Source/core/dom/ContainerNodeAlgorithms.cpp b/Source/core/dom/ContainerNodeAlgorithms.cpp
index 9f4eeac..ab67eef 100644
--- a/Source/core/dom/ContainerNodeAlgorithms.cpp
+++ b/Source/core/dom/ContainerNodeAlgorithms.cpp
@@ -90,8 +90,8 @@
     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()) {
         ShadowRootVector roots(shadow);
diff --git a/Source/core/dom/ContainerNodeAlgorithms.h b/Source/core/dom/ContainerNodeAlgorithms.h
index ebd5263..d8910cf 100644
--- a/Source/core/dom/ContainerNodeAlgorithms.h
+++ b/Source/core/dom/ContainerNodeAlgorithms.h
@@ -213,9 +213,9 @@
 {
     ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
 
-    InspectorInstrumentation::didInsertDOMNode(node->document(), node);
+    InspectorInstrumentation::didInsertDOMNode(&node->document(), node);
 
-    RefPtr<Document> protectDocument(node->document());
+    RefPtr<Document> protectDocument(&node->document());
     RefPtr<Node> protectNode(node);
 
     if (m_insertionPoint->inDocument())
@@ -223,10 +223,20 @@
     else if (node->isContainerNode())
         notifyNodeInsertedIntoTree(toContainerNode(node));
 
-    for (size_t i = 0; i < m_postInsertionNotificationTargets.size(); ++i)
-        m_postInsertionNotificationTargets[i]->didNotifySubtreeInsertions(m_insertionPoint);
-}
+    // Script runs in didNotifySubtreeInsertions so we should lazy attach before
+    // to ensure that triggering a style recalc in script attaches all nodes that
+    // were inserted.
+    // FIXME: We should merge the lazy attach logic into the tree traversal in
+    // notifyNodeInsertedIntoDocument.
+    if (!node->attached() && node->parentNode() && node->parentNode()->attached())
+        node->lazyAttach();
 
+    for (size_t i = 0; i < m_postInsertionNotificationTargets.size(); ++i) {
+        Node* node = m_postInsertionNotificationTargets[i].get();
+        if (node->inDocument())
+            node->didNotifySubtreeInsertionsToDocument();
+    }
+}
 
 inline void ChildNodeRemovalNotifier::notifyNodeRemovedFromDocument(Node* node)
 {
@@ -250,7 +260,7 @@
 {
     if (node->inDocument()) {
         notifyNodeRemovedFromDocument(node);
-        node->document()->notifyRemovePendingSheetIfNeeded();
+        node->document().notifyRemovePendingSheetIfNeeded();
     } else if (node->isContainerNode())
         notifyNodeRemovedFromTree(toContainerNode(node));
 }
diff --git a/Source/core/dom/CustomElement.cpp b/Source/core/dom/CustomElement.cpp
index 0529882..ddb8db2 100644
--- a/Source/core/dom/CustomElement.cpp
+++ b/Source/core/dom/CustomElement.cpp
@@ -132,20 +132,20 @@
     CustomElementCallbackScheduler::scheduleAttributeChangedCallback(definitionFor(element)->callbacks(), element, name, oldValue, newValue);
 }
 
-void CustomElement::didEnterDocument(Element* element, Document* document)
+void CustomElement::didEnterDocument(Element* element, const Document& document)
 {
     ASSERT(element->customElementState() == Element::Upgraded);
-    if (!document->defaultView())
+    if (!document.defaultView())
         return;
-    CustomElementCallbackScheduler::scheduleEnteredDocumentCallback(definitionFor(element)->callbacks(), element);
+    CustomElementCallbackScheduler::scheduleEnteredViewCallback(definitionFor(element)->callbacks(), element);
 }
 
-void CustomElement::didLeaveDocument(Element* element, Document* document)
+void CustomElement::didLeaveDocument(Element* element, const Document& document)
 {
     ASSERT(element->customElementState() == Element::Upgraded);
-    if (!document->defaultView())
+    if (!document.defaultView())
         return;
-    CustomElementCallbackScheduler::scheduleLeftDocumentCallback(definitionFor(element)->callbacks(), element);
+    CustomElementCallbackScheduler::scheduleLeftViewCallback(definitionFor(element)->callbacks(), element);
 }
 
 void CustomElement::wasDestroyed(Element* element)
diff --git a/Source/core/dom/CustomElement.h b/Source/core/dom/CustomElement.h
index 07ba3c0..3e66512 100644
--- a/Source/core/dom/CustomElement.h
+++ b/Source/core/dom/CustomElement.h
@@ -64,8 +64,8 @@
 
     static void didFinishParsingChildren(Element*);
     static void attributeDidChange(Element*, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue);
-    static void didEnterDocument(Element*, Document*);
-    static void didLeaveDocument(Element*, Document*);
+    static void didEnterDocument(Element*, const Document&);
+    static void didLeaveDocument(Element*, const Document&);
     static void wasDestroyed(Element*);
 
 private:
diff --git a/Source/core/dom/CustomElementCallbackInvocation.cpp b/Source/core/dom/CustomElementCallbackInvocation.cpp
index 4974dc0..5729833 100644
--- a/Source/core/dom/CustomElementCallbackInvocation.cpp
+++ b/Source/core/dom/CustomElementCallbackInvocation.cpp
@@ -50,14 +50,14 @@
 
 void CreatedInvocation::dispatch(Element* element)
 {
-    if (element->inDocument() && element->document()->defaultView())
-        CustomElementCallbackScheduler::scheduleEnteredDocumentCallback(callbacks(), element);
+    if (element->inDocument() && element->document().defaultView())
+        CustomElementCallbackScheduler::scheduleEnteredViewCallback(callbacks(), element);
     callbacks()->created(element);
 }
 
-class EnteredLeftDocumentInvocation : public CustomElementCallbackInvocation {
+class EnteredLeftViewInvocation : public CustomElementCallbackInvocation {
 public:
-    EnteredLeftDocumentInvocation(PassRefPtr<CustomElementLifecycleCallbacks>, CustomElementLifecycleCallbacks::CallbackType which);
+    EnteredLeftViewInvocation(PassRefPtr<CustomElementLifecycleCallbacks>, CustomElementLifecycleCallbacks::CallbackType which);
 
 private:
     virtual void dispatch(Element*) OVERRIDE;
@@ -65,21 +65,21 @@
     CustomElementLifecycleCallbacks::CallbackType m_which;
 };
 
-EnteredLeftDocumentInvocation::EnteredLeftDocumentInvocation(PassRefPtr<CustomElementLifecycleCallbacks> callbacks, CustomElementLifecycleCallbacks::CallbackType which)
+EnteredLeftViewInvocation::EnteredLeftViewInvocation(PassRefPtr<CustomElementLifecycleCallbacks> callbacks, CustomElementLifecycleCallbacks::CallbackType which)
     : CustomElementCallbackInvocation(callbacks)
     , m_which(which)
 {
-    ASSERT(m_which == CustomElementLifecycleCallbacks::EnteredDocument || m_which == CustomElementLifecycleCallbacks::LeftDocument);
+    ASSERT(m_which == CustomElementLifecycleCallbacks::EnteredView || m_which == CustomElementLifecycleCallbacks::LeftView);
 }
 
-void EnteredLeftDocumentInvocation::dispatch(Element* element)
+void EnteredLeftViewInvocation::dispatch(Element* element)
 {
     switch (m_which) {
-    case CustomElementLifecycleCallbacks::EnteredDocument:
-        callbacks()->enteredDocument(element);
+    case CustomElementLifecycleCallbacks::EnteredView:
+        callbacks()->enteredView(element);
         break;
-    case CustomElementLifecycleCallbacks::LeftDocument:
-        callbacks()->leftDocument(element);
+    case CustomElementLifecycleCallbacks::LeftView:
+        callbacks()->leftView(element);
         break;
     default:
         ASSERT_NOT_REACHED();
@@ -117,9 +117,9 @@
     case CustomElementLifecycleCallbacks::Created:
         return adoptPtr(new CreatedInvocation(callbacks));
 
-    case CustomElementLifecycleCallbacks::EnteredDocument:
-    case CustomElementLifecycleCallbacks::LeftDocument:
-        return adoptPtr(new EnteredLeftDocumentInvocation(callbacks, which));
+    case CustomElementLifecycleCallbacks::EnteredView:
+    case CustomElementLifecycleCallbacks::LeftView:
+        return adoptPtr(new EnteredLeftViewInvocation(callbacks, which));
 
     default:
         ASSERT_NOT_REACHED();
diff --git a/Source/core/dom/CustomElementCallbackScheduler.cpp b/Source/core/dom/CustomElementCallbackScheduler.cpp
index 79252ba..31c8252 100644
--- a/Source/core/dom/CustomElementCallbackScheduler.cpp
+++ b/Source/core/dom/CustomElementCallbackScheduler.cpp
@@ -56,22 +56,22 @@
     queue->append(CustomElementCallbackInvocation::createInvocation(callbacks, CustomElementLifecycleCallbacks::Created));
 }
 
-void CustomElementCallbackScheduler::scheduleEnteredDocumentCallback(PassRefPtr<CustomElementLifecycleCallbacks> callbacks, PassRefPtr<Element> element)
+void CustomElementCallbackScheduler::scheduleEnteredViewCallback(PassRefPtr<CustomElementLifecycleCallbacks> callbacks, PassRefPtr<Element> element)
 {
-    if (!callbacks->hasEnteredDocumentCallback())
+    if (!callbacks->hasEnteredViewCallback())
         return;
 
     CustomElementCallbackQueue* queue = CustomElementCallbackDispatcher::instance().schedule(element);
-    queue->append(CustomElementCallbackInvocation::createInvocation(callbacks, CustomElementLifecycleCallbacks::EnteredDocument));
+    queue->append(CustomElementCallbackInvocation::createInvocation(callbacks, CustomElementLifecycleCallbacks::EnteredView));
 }
 
-void CustomElementCallbackScheduler::scheduleLeftDocumentCallback(PassRefPtr<CustomElementLifecycleCallbacks> callbacks, PassRefPtr<Element> element)
+void CustomElementCallbackScheduler::scheduleLeftViewCallback(PassRefPtr<CustomElementLifecycleCallbacks> callbacks, PassRefPtr<Element> element)
 {
-    if (!callbacks->hasLeftDocumentCallback())
+    if (!callbacks->hasLeftViewCallback())
         return;
 
     CustomElementCallbackQueue* queue = CustomElementCallbackDispatcher::instance().schedule(element);
-    queue->append(CustomElementCallbackInvocation::createInvocation(callbacks, CustomElementLifecycleCallbacks::LeftDocument));
+    queue->append(CustomElementCallbackInvocation::createInvocation(callbacks, CustomElementLifecycleCallbacks::LeftView));
 }
 
 } // namespace WebCore
diff --git a/Source/core/dom/CustomElementCallbackScheduler.h b/Source/core/dom/CustomElementCallbackScheduler.h
index 3f5194e..42542e5 100644
--- a/Source/core/dom/CustomElementCallbackScheduler.h
+++ b/Source/core/dom/CustomElementCallbackScheduler.h
@@ -43,8 +43,8 @@
 public:
     static void scheduleAttributeChangedCallback(PassRefPtr<CustomElementLifecycleCallbacks>, PassRefPtr<Element>, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue);
     static void scheduleCreatedCallback(PassRefPtr<CustomElementLifecycleCallbacks>, PassRefPtr<Element>);
-    static void scheduleEnteredDocumentCallback(PassRefPtr<CustomElementLifecycleCallbacks>, PassRefPtr<Element>);
-    static void scheduleLeftDocumentCallback(PassRefPtr<CustomElementLifecycleCallbacks>, PassRefPtr<Element>);
+    static void scheduleEnteredViewCallback(PassRefPtr<CustomElementLifecycleCallbacks>, PassRefPtr<Element>);
+    static void scheduleLeftViewCallback(PassRefPtr<CustomElementLifecycleCallbacks>, PassRefPtr<Element>);
 
 private:
     CustomElementCallbackScheduler();
diff --git a/Source/core/dom/CustomElementException.cpp b/Source/core/dom/CustomElementException.cpp
index b5752a8..73b1717 100644
--- a/Source/core/dom/CustomElementException.cpp
+++ b/Source/core/dom/CustomElementException.cpp
@@ -64,22 +64,18 @@
         es.throwDOMException(NotSupportedError);
         return;
 
+    case ExtendsIsInvalidName:
+        es.throwDOMException(InvalidCharacterError, preamble(type) + ": the tag name specified in 'extends' is not a valid tag name.");
+        return;
+
+    case ExtendsIsCustomElementName:
+        es.throwDOMException(InvalidCharacterError, preamble(type) + ": the tag name specified in 'extends' is a custom element name. Use inheritance instead.");
+        return;
+
     case InvalidName:
         es.throwDOMException(InvalidCharacterError, preamble(type) + ": '" + type + "' is not a valid name.");
         return;
 
-    case NotYetImplemented:
-        es.throwDOMException(InvalidStateError);
-        return;
-
-    case PrototypeDoesNotExtendHTMLElementSVGElementNamespace:
-        es.throwDOMException(NamespaceError, preamble(type) + "the prototype does not extend an HTML or SVG element.");
-        return;
-
-    case PrototypeDoesNotExtendHTMLElementSVGElementPrototype:
-        es.throwDOMException(InvalidStateError, preamble(type) + "the prototype does not extend an HTML or SVG element.");
-        return;
-
     case PrototypeInUse:
         es.throwDOMException(NotSupportedError, preamble(type) + "prototype is already in-use as an interface prototype object.");
         return;
diff --git a/Source/core/dom/CustomElementException.h b/Source/core/dom/CustomElementException.h
index 622ef22..30bdb3b 100644
--- a/Source/core/dom/CustomElementException.h
+++ b/Source/core/dom/CustomElementException.h
@@ -46,10 +46,9 @@
         ContextDestroyedCheckingPrototype,
         ContextDestroyedCreatingCallbacks,
         ContextDestroyedRegisteringDefinition,
+        ExtendsIsInvalidName,
+        ExtendsIsCustomElementName,
         InvalidName,
-        NotYetImplemented,
-        PrototypeDoesNotExtendHTMLElementSVGElementNamespace,
-        PrototypeDoesNotExtendHTMLElementSVGElementPrototype,
         PrototypeInUse,
         PrototypeNotAnObject,
         TypeAlreadyRegistered
diff --git a/Source/core/dom/CustomElementLifecycleCallbacks.h b/Source/core/dom/CustomElementLifecycleCallbacks.h
index e48628d..eb2f32f 100644
--- a/Source/core/dom/CustomElementLifecycleCallbacks.h
+++ b/Source/core/dom/CustomElementLifecycleCallbacks.h
@@ -45,11 +45,11 @@
     bool hasCreatedCallback() const { return m_which & Created; }
     virtual void created(Element*) = 0;
 
-    bool hasEnteredDocumentCallback() const { return m_which & EnteredDocument; }
-    virtual void enteredDocument(Element*) = 0;
+    bool hasEnteredViewCallback() const { return m_which & EnteredView; }
+    virtual void enteredView(Element*) = 0;
 
-    bool hasLeftDocumentCallback() const { return m_which & LeftDocument; }
-    virtual void leftDocument(Element*) = 0;
+    bool hasLeftViewCallback() const { return m_which & LeftView; }
+    virtual void leftView(Element*) = 0;
 
     bool hasAttributeChangedCallback() const { return m_which & AttributeChanged; }
     virtual void attributeChanged(Element*, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue) = 0;
@@ -57,8 +57,8 @@
     enum CallbackType {
         None             = 0,
         Created          = 1 << 0,
-        EnteredDocument  = 1 << 1,
-        LeftDocument     = 1 << 2,
+        EnteredView      = 1 << 1,
+        LeftView         = 1 << 2,
         AttributeChanged = 1 << 3
     };
 
diff --git a/Source/core/dom/CustomElementRegistrationContext.cpp b/Source/core/dom/CustomElementRegistrationContext.cpp
index bedaf5e..6c4133f 100644
--- a/Source/core/dom/CustomElementRegistrationContext.cpp
+++ b/Source/core/dom/CustomElementRegistrationContext.cpp
@@ -58,13 +58,10 @@
         didResolveElement(definition, *it);
 }
 
-PassRefPtr<Element> CustomElementRegistrationContext::createCustomTagElement(Document* document, const QualifiedName& tagName, CreationMode mode)
+PassRefPtr<Element> CustomElementRegistrationContext::createCustomTagElement(Document& document, const QualifiedName& tagName, CreationMode mode)
 {
     ASSERT(CustomElement::isValidName(tagName.localName()));
 
-    if (!document)
-        return 0;
-
     RefPtr<Element> element;
 
     if (HTMLNames::xhtmlNamespaceURI == tagName.namespaceURI()) {
@@ -73,7 +70,7 @@
         element = SVGUnknownElement::create(tagName, document);
     } else {
         // XML elements are not custom elements, so return early.
-        return Element::create(tagName, document);
+        return Element::create(tagName, &document);
     }
 
     element->setCustomElementState(mode == CreatedByParser ? Element::WaitingForParser : Element::WaitingForUpgrade);
@@ -146,7 +143,7 @@
 
     element->setCustomElementState(mode == CreatedByParser ? Element::WaitingForParser : Element::WaitingForUpgrade);
 
-    if (CustomElementRegistrationContext* context = element->document()->registrationContext())
+    if (CustomElementRegistrationContext* context = element->document().registrationContext())
         context->didGiveTypeExtension(element, type);
 }
 
diff --git a/Source/core/dom/CustomElementRegistrationContext.h b/Source/core/dom/CustomElementRegistrationContext.h
index 7b8449f..7d23d72 100644
--- a/Source/core/dom/CustomElementRegistrationContext.h
+++ b/Source/core/dom/CustomElementRegistrationContext.h
@@ -62,7 +62,7 @@
         NotCreatedByParser
     };
 
-    PassRefPtr<Element> createCustomTagElement(Document*, const QualifiedName&, CreationMode = NotCreatedByParser);
+    PassRefPtr<Element> createCustomTagElement(Document&, const QualifiedName&, CreationMode = NotCreatedByParser);
     static void setIsAttributeAndTypeExtension(Element*, const AtomicString& type);
     static void setTypeExtension(Element*, const AtomicString& type, CreationMode = NotCreatedByParser);
 
diff --git a/Source/core/dom/CustomElementRegistry.cpp b/Source/core/dom/CustomElementRegistry.cpp
index b734c82..00d6d71 100644
--- a/Source/core/dom/CustomElementRegistry.cpp
+++ b/Source/core/dom/CustomElementRegistry.cpp
@@ -78,16 +78,13 @@
         return 0;
     }
 
-    if (!constructorBuilder->validateOptions(type, es))
+    QualifiedName tagName = nullQName();
+    if (!constructorBuilder->validateOptions(type, tagName, es))
         return 0;
 
-    QualifiedName tagName = nullQName();
-    if (!constructorBuilder->findTagName(type, tagName)) {
-        CustomElementException::throwException(CustomElementException::PrototypeDoesNotExtendHTMLElementSVGElementNamespace, type, es);
-        return 0;
-    }
     ASSERT(tagName.namespaceURI() == HTMLNames::xhtmlNamespaceURI || tagName.namespaceURI() == SVGNames::svgNamespaceURI);
 
+    // FIXME: This should be done earlier in validateOptions.
     if (m_registeredTypeNames.contains(type)) {
         CustomElementException::throwException(CustomElementException::TypeAlreadyRegistered, type, es);
         return 0;
diff --git a/Source/core/dom/DOMImplementation.cpp b/Source/core/dom/DOMImplementation.cpp
index 3b888bc..3215a6a 100644
--- a/Source/core/dom/DOMImplementation.cpp
+++ b/Source/core/dom/DOMImplementation.cpp
@@ -32,6 +32,7 @@
 #include "core/css/MediaList.h"
 #include "core/css/StyleSheetContents.h"
 #include "core/dom/ContextFeatures.h"
+#include "core/dom/CustomElementRegistrationContext.h"
 #include "core/dom/DocumentInit.h"
 #include "core/dom/DocumentType.h"
 #include "core/dom/Element.h"
@@ -196,12 +197,14 @@
     const String& qualifiedName, DocumentType* doctype, ExceptionState& es)
 {
     RefPtr<Document> doc;
-    if (namespaceURI == SVGNames::svgNamespaceURI)
-        doc = SVGDocument::create();
-    else if (namespaceURI == HTMLNames::xhtmlNamespaceURI)
-        doc = Document::createXHTML(DocumentInit().withRegistrationContext(m_document->registrationContext()));
-    else
-        doc = Document::create();
+    DocumentInit init = DocumentInit::fromContext(m_document->contextDocument());
+    if (namespaceURI == SVGNames::svgNamespaceURI) {
+        doc = SVGDocument::create(init);
+    } else if (namespaceURI == HTMLNames::xhtmlNamespaceURI) {
+        doc = Document::createXHTML(init.withRegistrationContext(m_document->registrationContext()));
+    } else {
+        doc = Document::create(init);
+    }
 
     doc->setSecurityOrigin(m_document->securityOrigin());
     doc->setContextFeatures(m_document->contextFeatures());
@@ -304,7 +307,9 @@
 
 PassRefPtr<HTMLDocument> DOMImplementation::createHTMLDocument(const String& title)
 {
-    RefPtr<HTMLDocument> d = HTMLDocument::create(DocumentInit().withRegistrationContext(m_document->registrationContext()));
+    DocumentInit init = DocumentInit::fromContext(m_document->contextDocument())
+        .withRegistrationContext(m_document->registrationContext());
+    RefPtr<HTMLDocument> d = HTMLDocument::create(init);
     d->open();
     d->write("<!doctype html><html><body></body></html>");
     if (!title.isNull())
diff --git a/Source/core/dom/DOMSettableTokenList.cpp b/Source/core/dom/DOMSettableTokenList.cpp
new file mode 100644
index 0000000..10692ca
--- /dev/null
+++ b/Source/core/dom/DOMSettableTokenList.cpp
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/dom/DOMSettableTokenList.h"
+
+#include "bindings/v8/ExceptionState.h"
+
+namespace WebCore {
+
+DOMSettableTokenList::DOMSettableTokenList()
+    : m_value()
+    , m_tokens()
+{
+    ScriptWrappable::init(this);
+}
+
+DOMSettableTokenList::~DOMSettableTokenList()
+{
+}
+
+const AtomicString DOMSettableTokenList::item(unsigned index) const
+{
+    if (index >= length())
+        return AtomicString();
+    return m_tokens[index];
+}
+
+bool DOMSettableTokenList::containsInternal(const AtomicString& token) const
+{
+    return m_tokens.contains(token);
+}
+
+void DOMSettableTokenList::add(const Vector<String>& tokens, ExceptionState& es)
+{
+    DOMTokenList::add(tokens, es);
+
+    for (size_t i = 0; i < tokens.size(); ++i) {
+        if (m_tokens.isNull())
+            m_tokens.set(tokens[i], false);
+        else
+            m_tokens.add(tokens[i]);
+    }
+}
+
+void DOMSettableTokenList::addInternal(const AtomicString& token)
+{
+    DOMTokenList::addInternal(token);
+    if (m_tokens.isNull())
+        m_tokens.set(token, false);
+    else
+        m_tokens.add(token);
+}
+
+void DOMSettableTokenList::remove(const Vector<String>& tokens, ExceptionState& es)
+{
+    DOMTokenList::remove(tokens, es);
+    for (size_t i = 0; i < tokens.size(); ++i)
+        m_tokens.remove(tokens[i]);
+}
+
+void DOMSettableTokenList::removeInternal(const AtomicString& token)
+{
+    DOMTokenList::removeInternal(token);
+    m_tokens.remove(token);
+}
+
+void DOMSettableTokenList::setValue(const AtomicString& value)
+{
+    m_value = value;
+    m_tokens.set(value, false);
+}
+
+} // namespace WebCore
diff --git a/Source/core/dom/DOMSettableTokenList.h b/Source/core/dom/DOMSettableTokenList.h
new file mode 100644
index 0000000..234b505
--- /dev/null
+++ b/Source/core/dom/DOMSettableTokenList.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DOMSettableTokenList_h
+#define DOMSettableTokenList_h
+
+#include "core/dom/DOMTokenList.h"
+#include "core/dom/SpaceSplitString.h"
+#include "wtf/RefCounted.h"
+#include "wtf/text/AtomicString.h"
+
+namespace WebCore {
+
+class ExceptionState;
+
+class DOMSettableTokenList : public DOMTokenList, public RefCounted<DOMSettableTokenList> {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    static PassRefPtr<DOMSettableTokenList> create()
+    {
+        return adoptRef(new DOMSettableTokenList());
+    }
+    virtual ~DOMSettableTokenList();
+
+    virtual void ref() OVERRIDE { RefCounted<DOMSettableTokenList>::ref(); }
+    virtual void deref() OVERRIDE { RefCounted<DOMSettableTokenList>::deref(); }
+
+    virtual unsigned length() const OVERRIDE { return m_tokens.size(); }
+    virtual const AtomicString item(unsigned index) const OVERRIDE;
+
+    virtual void add(const Vector<String>&, ExceptionState&) OVERRIDE;
+    virtual void remove(const Vector<String>&, ExceptionState&) OVERRIDE;
+
+    virtual AtomicString value() const OVERRIDE { return m_value; }
+    virtual void setValue(const AtomicString&) OVERRIDE;
+
+    const SpaceSplitString& tokens() const { return m_tokens; }
+
+protected:
+    DOMSettableTokenList();
+
+private:
+    virtual void addInternal(const AtomicString&) OVERRIDE;
+    virtual bool containsInternal(const AtomicString&) const OVERRIDE;
+    virtual void removeInternal(const AtomicString&) OVERRIDE;
+
+    AtomicString m_value;
+    SpaceSplitString m_tokens;
+};
+
+} // namespace WebCore
+
+#endif // DOMSettableTokenList_h
diff --git a/Source/core/dom/DOMSettableTokenList.idl b/Source/core/dom/DOMSettableTokenList.idl
new file mode 100644
index 0000000..18142d0
--- /dev/null
+++ b/Source/core/dom/DOMSettableTokenList.idl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+interface DOMSettableTokenList : DOMTokenList {
+    [TreatReturnedNullStringAs=Null, ImplementedAs=item] getter DOMString(unsigned long index);
+    attribute DOMString value;
+};
+
diff --git a/Source/core/dom/DOMTokenList.cpp b/Source/core/dom/DOMTokenList.cpp
new file mode 100644
index 0000000..9b48609
--- /dev/null
+++ b/Source/core/dom/DOMTokenList.cpp
@@ -0,0 +1,240 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/dom/DOMTokenList.h"
+
+#include "bindings/v8/ExceptionState.h"
+#include "core/dom/ExceptionCode.h"
+#include "core/html/parser/HTMLParserIdioms.h"
+#include "wtf/text/StringBuilder.h"
+
+namespace WebCore {
+
+bool DOMTokenList::validateToken(const AtomicString& token, ExceptionState& es)
+{
+    if (token.isEmpty()) {
+        es.throwDOMException(SyntaxError);
+        return false;
+    }
+
+    unsigned length = token.length();
+    for (unsigned i = 0; i < length; ++i) {
+        if (isHTMLSpace(token[i])) {
+            es.throwDOMException(InvalidCharacterError);
+            return false;
+        }
+    }
+
+    return true;
+}
+
+bool DOMTokenList::validateTokens(const Vector<String>& tokens, ExceptionState& es)
+{
+    for (size_t i = 0; i < tokens.size(); ++i) {
+        if (!validateToken(tokens[i], es))
+            return false;
+    }
+
+    return true;
+}
+
+bool DOMTokenList::contains(const AtomicString& token, ExceptionState& es) const
+{
+    if (!validateToken(token, es))
+        return false;
+    return containsInternal(token);
+}
+
+void DOMTokenList::add(const AtomicString& token, ExceptionState& es)
+{
+    Vector<String> tokens;
+    tokens.append(token.string());
+    add(tokens, es);
+}
+
+void DOMTokenList::add(const Vector<String>& tokens, ExceptionState& es)
+{
+    Vector<String> filteredTokens;
+    for (size_t i = 0; i < tokens.size(); ++i) {
+        if (!validateToken(tokens[i], es))
+            return;
+        if (!containsInternal(tokens[i]))
+            filteredTokens.append(tokens[i]);
+    }
+
+    if (filteredTokens.isEmpty())
+        return;
+
+    setValue(addTokens(value(), filteredTokens));
+}
+
+void DOMTokenList::remove(const AtomicString& token, ExceptionState& es)
+{
+    Vector<String> tokens;
+    tokens.append(token.string());
+    remove(tokens, es);
+}
+
+void DOMTokenList::remove(const Vector<String>& tokens, ExceptionState& es)
+{
+    if (!validateTokens(tokens, es))
+        return;
+
+    // Check using containsInternal first since it is a lot faster than going
+    // through the string character by character.
+    bool found = false;
+    for (size_t i = 0; i < tokens.size(); ++i) {
+        if (containsInternal(tokens[i])) {
+            found = true;
+            break;
+        }
+    }
+
+    if (found)
+        setValue(removeTokens(value(), tokens));
+}
+
+bool DOMTokenList::toggle(const AtomicString& token, ExceptionState& es)
+{
+    if (!validateToken(token, es))
+        return false;
+
+    if (containsInternal(token)) {
+        removeInternal(token);
+        return false;
+    }
+    addInternal(token);
+    return true;
+}
+
+bool DOMTokenList::toggle(const AtomicString& token, bool force, ExceptionState& es)
+{
+    if (!validateToken(token, es))
+        return false;
+
+    if (force)
+        addInternal(token);
+    else
+        removeInternal(token);
+
+    return force;
+}
+
+void DOMTokenList::addInternal(const AtomicString& token)
+{
+    if (!containsInternal(token))
+        setValue(addToken(value(), token));
+}
+
+void DOMTokenList::removeInternal(const AtomicString& token)
+{
+    // Check using contains first since it uses AtomicString comparisons instead
+    // of character by character testing.
+    if (!containsInternal(token))
+        return;
+    setValue(removeToken(value(), token));
+}
+
+String DOMTokenList::addToken(const AtomicString& input, const AtomicString& token)
+{
+    Vector<String> tokens;
+    tokens.append(token.string());
+    return addTokens(input, tokens);
+}
+
+String DOMTokenList::addTokens(const AtomicString& input, const Vector<String>& tokens)
+{
+    bool needsSpace = false;
+
+    StringBuilder builder;
+    if (!input.isEmpty()) {
+        builder.append(input);
+        needsSpace = !isHTMLSpace(input[input.length() - 1]);
+    }
+
+    for (size_t i = 0; i < tokens.size(); ++i) {
+        if (needsSpace)
+            builder.append(' ');
+        builder.append(tokens[i]);
+        needsSpace = true;
+    }
+
+    return builder.toString();
+}
+
+String DOMTokenList::removeToken(const AtomicString& input, const AtomicString& token)
+{
+    Vector<String> tokens;
+    tokens.append(token.string());
+    return removeTokens(input, tokens);
+}
+
+String DOMTokenList::removeTokens(const AtomicString& input, const Vector<String>& tokens)
+{
+    // Algorithm defined at http://www.whatwg.org/specs/web-apps/current-work/multipage/common-microsyntaxes.html#remove-a-token-from-a-string
+    // New spec is at http://dom.spec.whatwg.org/#remove-a-token-from-a-string
+
+    unsigned inputLength = input.length();
+    StringBuilder output; // 3
+    output.reserveCapacity(inputLength);
+    unsigned position = 0; // 4
+
+    // Step 5
+    while (position < inputLength) {
+        if (isHTMLSpace(input[position])) { // 6
+            output.append(input[position++]); // 6.1, 6.2
+            continue; // 6.3
+        }
+
+        // Step 7
+        StringBuilder tokenBuilder;
+        while (position < inputLength && isNotHTMLSpace(input[position]))
+            tokenBuilder.append(input[position++]);
+
+        // Step 8
+        String token = tokenBuilder.toString();
+        if (tokens.contains(token)) {
+            // Step 8.1
+            while (position < inputLength && isHTMLSpace(input[position]))
+                ++position;
+
+            // Step 8.2
+            size_t j = output.length();
+            while (j > 0 && isHTMLSpace(output[j - 1]))
+                --j;
+            output.resize(j);
+
+            // Step 8.3
+            if (position < inputLength && !output.isEmpty())
+                output.append(' ');
+        } else {
+            output.append(token); // Step 9
+        }
+    }
+
+    return output.toString();
+}
+
+} // namespace WebCore
diff --git a/Source/core/dom/DOMTokenList.h b/Source/core/dom/DOMTokenList.h
new file mode 100644
index 0000000..d758214
--- /dev/null
+++ b/Source/core/dom/DOMTokenList.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DOMTokenList_h
+#define DOMTokenList_h
+
+#include "bindings/v8/ScriptWrappable.h"
+#include "wtf/Vector.h"
+#include "wtf/text/AtomicString.h"
+
+namespace WebCore {
+
+class Element;
+class ExceptionState;
+
+class DOMTokenList : public ScriptWrappable {
+    WTF_MAKE_NONCOPYABLE(DOMTokenList); WTF_MAKE_FAST_ALLOCATED;
+public:
+    DOMTokenList()
+    {
+        ScriptWrappable::init(this);
+    }
+    virtual ~DOMTokenList() { };
+
+    virtual void ref() = 0;
+    virtual void deref() = 0;
+
+    virtual unsigned length() const = 0;
+    virtual const AtomicString item(unsigned index) const = 0;
+
+    bool contains(const AtomicString&, ExceptionState&) const;
+    virtual void add(const Vector<String>&, ExceptionState&);
+    void add(const AtomicString&, ExceptionState&);
+    virtual void remove(const Vector<String>&, ExceptionState&);
+    void remove(const AtomicString&, ExceptionState&);
+    bool toggle(const AtomicString&, ExceptionState&);
+    bool toggle(const AtomicString&, bool force, ExceptionState&);
+
+    AtomicString toString() const { return value(); }
+
+    virtual Element* element() { return 0; }
+
+protected:
+    virtual AtomicString value() const = 0;
+    virtual void setValue(const AtomicString&) = 0;
+
+    virtual void addInternal(const AtomicString&);
+    virtual bool containsInternal(const AtomicString&) const = 0;
+    virtual void removeInternal(const AtomicString&);
+
+    static bool validateToken(const AtomicString&, ExceptionState&);
+    static bool validateTokens(const Vector<String>&, ExceptionState&);
+    static String addToken(const AtomicString&, const AtomicString&);
+    static String addTokens(const AtomicString&, const Vector<String>&);
+    static String removeToken(const AtomicString&, const AtomicString&);
+    static String removeTokens(const AtomicString&, const Vector<String>&);
+};
+
+} // namespace WebCore
+
+#endif // DOMTokenList_h
diff --git a/Source/core/dom/DOMTokenList.idl b/Source/core/dom/DOMTokenList.idl
new file mode 100644
index 0000000..3f16677
--- /dev/null
+++ b/Source/core/dom/DOMTokenList.idl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2010, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+[
+    GenerateIsReachable=element
+] interface DOMTokenList {
+    readonly attribute unsigned long length;
+    [TreatReturnedNullStringAs=Null] getter DOMString item(unsigned long index);
+    [RaisesException] boolean contains(DOMString token);
+    [RaisesException, CustomElementCallbacks=Enable] void add(DOMString... tokens);
+    [RaisesException, CustomElementCallbacks=Enable] void remove(DOMString... tokens);
+    [RaisesException, CustomElementCallbacks=Enable] boolean toggle(DOMString token, optional boolean force);
+    [NotEnumerable] DOMString toString();
+};
+
diff --git a/Source/core/dom/DecodedDataDocumentParser.cpp b/Source/core/dom/DecodedDataDocumentParser.cpp
index 53c846b..06ce4e7 100644
--- a/Source/core/dom/DecodedDataDocumentParser.cpp
+++ b/Source/core/dom/DecodedDataDocumentParser.cpp
@@ -27,7 +27,7 @@
 #include "core/dom/DecodedDataDocumentParser.h"
 
 #include "core/dom/Document.h"
-#include "core/loader/TextResourceDecoder.h"
+#include "core/fetch/TextResourceDecoder.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/Document.cpp b/Source/core/dom/Document.cpp
index bc0bd80..d04d081 100644
--- a/Source/core/dom/Document.cpp
+++ b/Source/core/dom/Document.cpp
@@ -43,6 +43,8 @@
 #include "bindings/v8/ScriptController.h"
 #include "core/accessibility/AXObjectCache.h"
 #include "core/animation/DocumentTimeline.h"
+#include "core/css/CSSDefaultStyleSheets.h"
+#include "core/css/CSSFontSelector.h"
 #include "core/css/CSSStyleDeclaration.h"
 #include "core/css/CSSStyleSheet.h"
 #include "core/css/FontLoader.h"
@@ -50,6 +52,7 @@
 #include "core/css/StylePropertySet.h"
 #include "core/css/StyleSheetContents.h"
 #include "core/css/StyleSheetList.h"
+#include "core/css/resolver/FontBuilder.h"
 #include "core/css/resolver/StyleResolver.h"
 #include "core/dom/Attr.h"
 #include "core/dom/BeforeUnloadEvent.h"
@@ -77,11 +80,13 @@
 #include "core/dom/NodeFilter.h"
 #include "core/dom/NodeIterator.h"
 #include "core/dom/NodeRareData.h"
+#include "core/dom/NodeRenderStyle.h"
 #include "core/dom/NodeRenderingTraversal.h"
 #include "core/dom/NodeTraversal.h"
 #include "core/dom/NodeWithIndex.h"
 #include "core/dom/PageTransitionEvent.h"
 #include "core/dom/PopStateEvent.h"
+#include "core/dom/PostAttachCallbacks.h"
 #include "core/dom/ProcessingInstruction.h"
 #include "core/dom/QualifiedName.h"
 #include "core/dom/RequestAnimationFrameCallback.h"
@@ -100,6 +105,7 @@
 #include "core/editing/Editor.h"
 #include "core/editing/FrameSelection.h"
 #include "core/fetch/ResourceFetcher.h"
+#include "core/fetch/TextResourceDecoder.h"
 #include "core/html/FormController.h"
 #include "core/html/HTMLAllCollection.h"
 #include "core/html/HTMLAnchorElement.h"
@@ -131,7 +137,6 @@
 #include "core/loader/FrameLoaderClient.h"
 #include "core/loader/ImageLoader.h"
 #include "core/loader/Prerenderer.h"
-#include "core/loader/TextResourceDecoder.h"
 #include "core/loader/appcache/ApplicationCacheHost.h"
 #include "core/page/Chrome.h"
 #include "core/page/ChromeClient.h"
@@ -153,6 +158,7 @@
 #include "core/platform/DateComponents.h"
 #include "core/platform/HistogramSupport.h"
 #include "core/platform/Language.h"
+#include "core/platform/ScrollbarTheme.h"
 #include "core/platform/Timer.h"
 #include "core/platform/chromium/TraceEvent.h"
 #include "core/platform/network/HTTPParsers.h"
@@ -298,7 +304,7 @@
     ASSERT(element->rendererIsEditable());
 
     Element* root = element->rootEditableElement();
-    Frame* frame = element->document()->frame();
+    Frame* frame = element->document().frame();
     if (!frame || !root)
         return false;
 
@@ -380,6 +386,7 @@
     , m_lastStyleResolverAccessTime(0)
     , m_didCalculateStyleResolver(false)
     , m_ignorePendingStylesheets(false)
+    , m_evaluateMediaQueriesOnStyleRecalc(false)
     , m_needsNotifyRemoveAllPendingStylesheet(false)
     , m_hasNodesWithPlaceholderStyle(false)
     , m_pendingSheetLayout(NoLayoutWithPendingSheets)
@@ -398,7 +405,7 @@
     , m_domTreeVersion(++s_globalTreeVersion)
     , m_listenerTypes(0)
     , m_mutationObserverTypes(0)
-    , m_styleSheetCollections(StyleSheetCollections::create(this))
+    , m_styleSheetCollections(StyleSheetCollections::create(*this))
     , m_visitedLinkState(VisitedLinkState::create(this))
     , m_visuallyOrdered(false)
     , m_readyState(Complete)
@@ -428,9 +435,11 @@
     , m_isViewSource(false)
     , m_sawElementsInKnownNamespaces(false)
     , m_isSrcdocDocument(false)
+    , m_isMobileDocument(false)
     , m_renderer(0)
     , m_eventQueue(DocumentEventQueue::create(this))
     , m_weakFactory(this)
+    , m_contextDocument(initializer.contextDocument())
     , m_idAttributeName(idAttr)
     , m_hasFullscreenElementStack(false)
     , m_loadEventDelayCount(0)
@@ -441,7 +450,6 @@
     , m_didAllowNavigationViaBeforeUnloadConfirmationPanel(false)
     , m_writeRecursionIsTooDeep(false)
     , m_writeRecursionDepth(0)
-    , m_wheelEventHandlerCount(0)
     , m_lastHandledUserGestureTimestamp(0)
     , m_prerenderer(Prerenderer::create(this))
     , m_textAutosizer(TextAutosizer::create(this))
@@ -503,7 +511,7 @@
     do {
         if (!(owner->hasAttribute(attribute) || owner->hasAttribute(prefixedAttribute)))
             return false;
-    } while ((owner = owner->document()->ownerElement()));
+    } while ((owner = owner->document().ownerElement()));
     return true;
 }
 
@@ -668,7 +676,7 @@
     if (m_docType) {
         this->adoptIfNeeded(m_docType.get());
         if (m_docType->publicId().startsWith("-//wapforum//dtd xhtml mobile 1.", /* caseSensitive */ false))
-            processViewport("width=device-width, height=device-height", ViewportArguments::XHTMLMobileProfile);
+            m_isMobileDocument = true;
     }
     // Doctype affects the interpretation of the stylesheets.
     clearStyleResolver();
@@ -721,7 +729,7 @@
     RefPtr<Element> element;
 
     if (CustomElement::isValidName(localName) && registrationContext())
-        element = registrationContext()->createCustomTagElement(this, QualifiedName(nullAtom, localName, xhtmlNamespaceURI));
+        element = registrationContext()->createCustomTagElement(*this, QualifiedName(nullAtom, localName, xhtmlNamespaceURI));
     else
         element = createElement(localName, es);
 
@@ -745,7 +753,7 @@
 
     RefPtr<Element> element;
     if (CustomElement::isValidName(qName.localName()) && registrationContext())
-        element = registrationContext()->createCustomTagElement(this, qName);
+        element = registrationContext()->createCustomTagElement(*this, qName);
     else
         element = createElementNS(namespaceURI, qualifiedName, es);
 
@@ -795,12 +803,12 @@
 
 PassRefPtr<Text> Document::createTextNode(const String& data)
 {
-    return Text::create(this, data);
+    return Text::create(*this, data);
 }
 
 PassRefPtr<Comment> Document::createComment(const String& data)
 {
-    return Comment::create(this, data);
+    return Comment::create(*this, data);
 }
 
 PassRefPtr<CDATASection> Document::createCDATASection(const String& data, ExceptionState& es)
@@ -813,7 +821,7 @@
         es.throwDOMException(InvalidCharacterError, "String cannot contain ']]>' since that is the end delimiter of a CData section.");
         return 0;
     }
-    return CDATASection::create(this, data);
+    return CDATASection::create(*this, data);
 }
 
 PassRefPtr<ProcessingInstruction> Document::createProcessingInstruction(const String& target, const String& data, ExceptionState& es)
@@ -826,12 +834,12 @@
         es.throwDOMException(NotSupportedError);
         return 0;
     }
-    return ProcessingInstruction::create(this, target, data);
+    return ProcessingInstruction::create(*this, target, data);
 }
 
 PassRefPtr<Text> Document::createEditingTextNode(const String& text)
 {
-    return Text::createEditingText(this, text);
+    return Text::createEditingText(*this, text);
 }
 
 PassRefPtr<CSSStyleDeclaration> Document::createCSSStyleDeclaration()
@@ -881,14 +889,14 @@
         return newElement.release();
     }
     case ATTRIBUTE_NODE:
-        return Attr::create(this, QualifiedName(nullAtom, toAttr(importedNode)->name(), nullAtom), toAttr(importedNode)->value());
+        return Attr::create(*this, QualifiedName(nullAtom, toAttr(importedNode)->name(), nullAtom), toAttr(importedNode)->value());
     case DOCUMENT_FRAGMENT_NODE: {
         if (importedNode->isShadowRoot()) {
             // ShadowRoot nodes should not be explicitly importable.
             // Either they are imported along with their host node, or created implicitly.
             break;
         }
-        DocumentFragment* oldFragment = static_cast<DocumentFragment*>(importedNode);
+        DocumentFragment* oldFragment = toDocumentFragment(importedNode);
         RefPtr<DocumentFragment> newFragment = createDocumentFragment();
         if (deep) {
             for (Node* oldChild = oldFragment->firstChild(); oldChild; oldChild = oldChild->nextSibling()) {
@@ -1009,7 +1017,7 @@
     if (e)
         m_sawElementsInKnownNamespaces = true;
     else
-        e = Element::create(qName, document());
+        e = Element::create(qName, &document());
 
     // <image> uses imgTag so we need a special rule.
     ASSERT((qName.matches(imageTag) && e->tagQName().matches(imgTag) && e->tagQName().prefix() == qName.prefix()) || qName == e->tagQName());
@@ -1223,7 +1231,7 @@
     if (shadowAncestorNode != node) {
         unsigned offset = shadowAncestorNode->nodeIndex();
         ContainerNode* container = shadowAncestorNode->parentNode();
-        return Range::create(this, container, offset, container, offset);
+        return Range::create(*this, container, offset, container, offset);
     }
 
     RenderObject* renderer = node->renderer();
@@ -1234,7 +1242,7 @@
         return 0;
 
     Position rangeCompliantPosition = positionWithAffinity.position().parentAnchoredEquivalent();
-    return Range::create(this, rangeCompliantPosition, rangeCompliantPosition);
+    return Range::create(*this, rangeCompliantPosition, rangeCompliantPosition);
 }
 
 /*
@@ -1456,7 +1464,7 @@
 
 PassRefPtr<Range> Document::createRange()
 {
-    return Range::create(this);
+    return Range::create(*this);
 }
 
 PassRefPtr<NodeIterator> Document::createNodeIterator(Node* root, ExceptionState& es)
@@ -1543,7 +1551,7 @@
     if (shouldDisplaySeamlesslyWithParent()) {
         // When we're seamless, our parent document manages our style recalcs.
         ownerElement()->setNeedsStyleRecalc();
-        ownerElement()->document()->scheduleStyleRecalc();
+        ownerElement()->document().scheduleStyleRecalc();
         return;
     }
 
@@ -1601,7 +1609,79 @@
         root->recalcDistribution();
 }
 
-void Document::recalcStyle(StyleChange change)
+void Document::setStyleDependentState(RenderStyle* documentStyle)
+{
+    const Pagination& pagination = view()->pagination();
+    if (pagination.mode != Pagination::Unpaginated) {
+        Pagination::setStylesForPaginationMode(pagination.mode, documentStyle);
+        documentStyle->setColumnGap(pagination.gap);
+        if (renderView()->hasColumns())
+            renderView()->updateColumnInfoFromStyle(documentStyle);
+    }
+
+    // Seamless iframes want to inherit their font from their parent iframe, so early return before setting the font.
+    if (shouldDisplaySeamlesslyWithParent())
+        return;
+
+    FontBuilder fontBuilder;
+    fontBuilder.initForStyleResolve(*this, documentStyle, isSVGDocument());
+    RefPtr<CSSFontSelector> selector = m_styleResolver ? m_styleResolver->fontSelector() : 0;
+    fontBuilder.createFontForDocument(selector, documentStyle);
+}
+
+void Document::inheritHtmlAndBodyElementStyles(StyleRecalcChange change)
+{
+    RenderView* renderView = this->renderView();
+
+    if (!documentElement() || !frame() || !view())
+        return;
+
+    RefPtr<RenderStyle> documentElementStyle = documentElement()->renderStyle();
+    if (!documentElementStyle || documentElement()->needsStyleRecalc() || change == Force)
+        documentElementStyle = styleResolver()->styleForElement(documentElement());
+
+    RefPtr<RenderStyle> bodyStyle = 0;
+    if (body()) {
+        bodyStyle = body()->renderStyle();
+        if (!bodyStyle || body()->needsStyleRecalc() || documentElement()->needsStyleRecalc() || change == Force)
+            bodyStyle = styleResolver()->styleForElement(body(), documentElementStyle.get());
+    }
+
+    WritingMode rootWritingMode = documentElementStyle->writingMode();
+    bool isHorizontalWritingMode = documentElementStyle->isHorizontalWritingMode();
+    TextDirection rootDirection = documentElementStyle->direction();
+
+    if (!writingModeSetOnDocumentElement() && body()) {
+        rootWritingMode = bodyStyle->writingMode();
+        isHorizontalWritingMode = bodyStyle->isHorizontalWritingMode();
+    }
+
+    if (!directionSetOnDocumentElement() && body())
+        rootDirection = bodyStyle->direction();
+
+    RefPtr<RenderStyle> documentStyle = renderView->style();
+    if (documentStyle->writingMode() != rootWritingMode || documentStyle->direction() != rootDirection) {
+        RefPtr<RenderStyle> newStyle = RenderStyle::clone(documentStyle.get());
+        newStyle->setWritingMode(rootWritingMode);
+        newStyle->setDirection(rootDirection);
+        renderView->setStyle(newStyle);
+        setStyleDependentState(newStyle.get());
+    }
+
+    if (body()) {
+        if (RenderStyle* style = body()->renderStyle()) {
+            if (style->direction() != rootDirection || style->writingMode() != rootWritingMode)
+                body()->setNeedsStyleRecalc();
+        }
+    }
+
+    if (RenderStyle* style = documentElement()->renderStyle()) {
+        if (style->direction() != rootDirection || style->writingMode() != rootWritingMode)
+            documentElement()->setNeedsStyleRecalc();
+    }
+}
+
+void Document::recalcStyle(StyleRecalcChange change)
 {
     // we should not enter style recalc while painting
     ASSERT(!view() || !view()->isPainting());
@@ -1614,6 +1694,11 @@
     TRACE_EVENT0("webkit", "Document::recalcStyle");
     TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "RecalcStyle");
 
+    if (m_evaluateMediaQueriesOnStyleRecalc) {
+        m_evaluateMediaQueriesOnStyleRecalc = false;
+        evaluateMediaQueryList();
+    }
+
     updateDistributionIfNeeded();
 
     // FIXME: We should update style on our ancestor chain before proceeding (especially for seamless),
@@ -1633,7 +1718,7 @@
 
     m_inStyleRecalc = true;
     {
-        PostAttachCallbackDisabler disabler(this);
+        PostAttachCallbacks::SuspendScope suspendPostAttachCallbacks;
         WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates;
 
         RefPtr<FrameView> frameView = view();
@@ -1648,17 +1733,16 @@
         if (styleChangeType() >= SubtreeStyleChange)
             change = Force;
 
-        // Recalculating the root style (on the document) is not needed in the common case.
         if ((change == Force) || (shouldDisplaySeamlesslyWithParent() && (change >= Inherit))) {
-            // style selector may set this again during recalc
             m_hasNodesWithPlaceholderStyle = false;
-
-            RefPtr<RenderStyle> documentStyle = StyleResolver::styleForDocument(this, m_styleResolver ? m_styleResolver->fontSelector() : 0);
-            StyleChange ch = Node::diff(documentStyle.get(), renderer()->style(), this);
-            if (ch != NoChange)
+            RefPtr<RenderStyle> documentStyle = StyleResolver::styleForDocument(*this, m_styleResolver ? m_styleResolver->fontSelector() : 0);
+            StyleRecalcChange localChange = RenderStyle::compare(documentStyle.get(), renderer()->style());
+            if (localChange != NoChange)
                 renderer()->setStyle(documentStyle.release());
         }
 
+        inheritHtmlAndBodyElementStyles(change);
+
         for (Node* n = firstChild(); n; n = n->nextSibling()) {
             if (!n->isElementNode())
                 continue;
@@ -1683,8 +1767,10 @@
         m_inStyleRecalc = false;
 
         // Pseudo element removal and similar may only work with these flags still set. Reset them after the style recalc.
-        if (m_styleResolver)
+        if (m_styleResolver) {
             m_styleSheetCollections->resetCSSFeatureFlags(m_styleResolver->ruleFeatureSet());
+            m_styleResolver->clearStyleSharingList();
+        }
 
         if (frameView) {
             frameView->resumeScheduledEvents();
@@ -1740,7 +1826,7 @@
     }
 
     if (Element* oe = ownerElement())
-        oe->document()->updateLayout();
+        oe->document().updateLayout();
 
     updateStyleIfNeeded();
 
@@ -1748,6 +1834,9 @@
     if (frameView && renderer() && (frameView->layoutPending() || renderer()->needsLayout()))
         frameView->layout();
 
+    if (frameView)
+        frameView->partialLayout().reset();
+
     setNeedsFocusedElementCheck();
 }
 
@@ -1760,6 +1849,31 @@
     m_didPostCheckFocusedElementTask = true;
 }
 
+void Document::recalcStyleForLayoutIgnoringPendingStylesheets()
+{
+    TemporaryChange<bool> ignorePendingStylesheets(m_ignorePendingStylesheets, m_ignorePendingStylesheets);
+    if (!haveStylesheetsLoaded()) {
+        m_ignorePendingStylesheets = true;
+        // FIXME: We are willing to attempt to suppress painting with outdated style info only once.
+        // Our assumption is that it would be dangerous to try to stop it a second time, after page
+        // content has already been loaded and displayed with accurate style information. (Our
+        // suppression involves blanking the whole page at the moment. If it were more refined, we
+        // might be able to do something better.) It's worth noting though that this entire method
+        // is a hack, since what we really want to do is suspend JS instead of doing a layout with
+        // inaccurate information.
+        HTMLElement* bodyElement = body();
+        if (bodyElement && !bodyElement->renderer() && m_pendingSheetLayout == NoLayoutWithPendingSheets) {
+            m_pendingSheetLayout = DidLayoutWithPendingSheets;
+            styleResolverChanged(RecalcStyleImmediately);
+        } else if (m_hasNodesWithPlaceholderStyle) {
+            // If new nodes have been added or style recalc has been done with style sheets still
+            // pending, some nodes may not have had their real style calculated yet. Normally this
+            // gets cleaned when style sheets arrive but here we need up-to-date style immediately.
+            recalcStyle(Force);
+        }
+    }
+}
+
 // FIXME: This is a bad idea and needs to be removed eventually.
 // Other browsers load stylesheets before they continue parsing the web page.
 // Since we don't, we can run JavaScript code that needs answers before the
@@ -1768,35 +1882,45 @@
 // to instead suspend JavaScript execution.
 void Document::updateLayoutIgnorePendingStylesheets()
 {
-    bool oldIgnore = m_ignorePendingStylesheets;
+    recalcStyleForLayoutIgnoringPendingStylesheets();
+    updateLayout();
+}
 
-    if (!haveStylesheetsLoaded()) {
-        m_ignorePendingStylesheets = true;
-        // FIXME: We are willing to attempt to suppress painting with outdated style info only once.  Our assumption is that it would be
-        // dangerous to try to stop it a second time, after page content has already been loaded and displayed
-        // with accurate style information.  (Our suppression involves blanking the whole page at the
-        // moment.  If it were more refined, we might be able to do something better.)
-        // It's worth noting though that this entire method is a hack, since what we really want to do is
-        // suspend JS instead of doing a layout with inaccurate information.
-        HTMLElement* bodyElement = body();
-        if (bodyElement && !bodyElement->renderer() && m_pendingSheetLayout == NoLayoutWithPendingSheets) {
-            m_pendingSheetLayout = DidLayoutWithPendingSheets;
-            styleResolverChanged(RecalcStyleImmediately);
-        } else if (m_hasNodesWithPlaceholderStyle)
-            // If new nodes have been added or style recalc has been done with style sheets still pending, some nodes
-            // may not have had their real style calculated yet. Normally this gets cleaned when style sheets arrive
-            // but here we need up-to-date style immediately.
-            recalcStyle(Force);
+void Document::partialUpdateLayoutIgnorePendingStylesheets(Node* stopLayoutAtNode)
+{
+    // Non-overlay scrollbars can cause a second layout that is dependent
+    // on a first layout. This is disabled for partial layout for now.
+    if (!RuntimeEnabledFeatures::partialLayoutEnabled() || !ScrollbarTheme::theme()->usesOverlayScrollbars()) {
+        updateLayoutIgnorePendingStylesheets();
+        return;
+    }
+
+    TemporaryChange<bool> ignorePendingStylesheets(m_ignorePendingStylesheets, m_ignorePendingStylesheets);
+    recalcStyleForLayoutIgnoringPendingStylesheets();
+
+    if (stopLayoutAtNode) {
+        RenderObject* renderer = stopLayoutAtNode->renderer();
+        bool canPartialLayout = renderer;
+        while (renderer) {
+            if (!renderer->supportsPartialLayout()) {
+                canPartialLayout = false;
+                break;
+            }
+            renderer = renderer->parent();
+        }
+        if (canPartialLayout && view())
+            view()->partialLayout().setStopAtRenderer(stopLayoutAtNode->renderer());
     }
 
     updateLayout();
 
-    m_ignorePendingStylesheets = oldIgnore;
+    if (view())
+        view()->partialLayout().reset();
 }
 
 PassRefPtr<RenderStyle> Document::styleForElementIgnoringPendingStylesheets(Element* element)
 {
-    ASSERT_ARG(element, element->document() == this);
+    ASSERT_ARG(element, &element->document() == this);
     TemporaryChange<bool> ignoreStyleSheets(m_ignorePendingStylesheets, true);
     return styleResolver()->styleForElement(element, element->parentNode() ? element->parentNode()->computedStyle() : 0);
 }
@@ -1865,7 +1989,7 @@
     bool matchAuthorAndUserStyles = true;
     if (Settings* docSettings = settings())
         matchAuthorAndUserStyles = docSettings->authorAndUserStylesEnabled();
-    m_styleResolver = adoptPtr(new StyleResolver(this, matchAuthorAndUserStyles));
+    m_styleResolver = adoptPtr(new StyleResolver(*this, matchAuthorAndUserStyles));
     m_styleSheetCollections->combineCSSFeatureFlags(m_styleResolver->ruleFeatureSet());
 }
 
@@ -1932,6 +2056,8 @@
 
     unscheduleStyleRecalc();
 
+    clearStyleResolver();
+
     if (render)
         render->destroy();
 
@@ -2038,9 +2164,9 @@
 
 PassRefPtr<DocumentParser> Document::createParser()
 {
-    if (isHTMLDocument() || (RuntimeEnabledFeatures::parseSVGAsHTMLEnabled() && isSVGDocument())) {
+    if (isHTMLDocument()) {
         bool reportErrors = InspectorInstrumentation::collectingHTMLParseErrors(this->page());
-        return HTMLDocumentParser::create(this, reportErrors);
+        return HTMLDocumentParser::create(toHTMLDocument(this), reportErrors);
     }
     // FIXME: this should probably pass the frame instead
     return XMLDocumentParser::create(this, view());
@@ -2181,10 +2307,10 @@
     if (!de)
         return 0;
 
-    for (Node* e = de->firstChild(); e; e = e->nextSibling())
-        if (e->hasTagName(headTag))
-            return static_cast<HTMLHeadElement*>(e);
-
+    for (Node* node = de->firstChild(); node; node = node->nextSibling()) {
+        if (node->hasTagName(headTag))
+            return toHTMLHeadElement(node);
+    }
     return 0;
 }
 
@@ -2713,7 +2839,7 @@
 {
     m_needsNotifyRemoveAllPendingStylesheet = false;
 
-    styleResolverChanged(RecalcStyleImmediately, AnalyzedStyleUpdate);
+    styleResolverChanged(RecalcStyleDeferred, AnalyzedStyleUpdate);
     executeScriptsWaitingForResourcesIfNeeded();
 
     if (m_gotoAnchorNeededAfterStylesheetsLoad && view())
@@ -2915,19 +3041,70 @@
         String valueString = buffer.substring(valueBegin, valueEnd - valueBegin);
         callback(keyString, valueString, this, data);
     }
-    if (error)
-        reportViewportWarning(this, InvalidKeyValuePairSeparatorError, String(), String());
+    if (error) {
+        String message = "Error parsing a meta element's content: ';' is not a valid key-value pair separator. Please use ',' instead.";
+        addConsoleMessage(RenderingMessageSource, WarningMessageLevel, message);
+    }
 }
 
 void Document::processViewport(const String& features, ViewportArguments::Type origin)
 {
     ASSERT(!features.isNull());
 
-    if (origin < m_viewportArguments.type)
+    if (!page() || !shouldOverrideLegacyViewport(origin))
         return;
 
-    m_viewportArguments = ViewportArguments(origin);
-    processArguments(features, (void*)&m_viewportArguments, &setViewportFeature);
+    ViewportArguments newArgumentsFromLegacyTag(origin);
+    processArguments(features, (void*)&newArgumentsFromLegacyTag, &setViewportFeature);
+
+    if (newArgumentsFromLegacyTag.minZoom == ViewportArguments::ValueAuto)
+        newArgumentsFromLegacyTag.minZoom = 0.25;
+
+    if (newArgumentsFromLegacyTag.maxZoom == ViewportArguments::ValueAuto) {
+        newArgumentsFromLegacyTag.maxZoom = 5;
+        newArgumentsFromLegacyTag.minZoom = std::min(newArgumentsFromLegacyTag.minZoom, float(5));
+    }
+
+    const Settings& settings = document().page()->settings();
+
+    if (newArgumentsFromLegacyTag.maxWidth.isAuto()) {
+        if (newArgumentsFromLegacyTag.zoom == ViewportArguments::ValueAuto) {
+            newArgumentsFromLegacyTag.minWidth = Length(ExtendToZoom);
+            newArgumentsFromLegacyTag.maxWidth = Length(settings.layoutFallbackWidth(), Fixed);
+        } else if (newArgumentsFromLegacyTag.maxHeight.isAuto()) {
+            newArgumentsFromLegacyTag.minWidth = Length(ExtendToZoom);
+            newArgumentsFromLegacyTag.maxWidth = Length(ExtendToZoom);
+        }
+    }
+
+    if (settings.viewportMetaZeroValuesQuirk()
+        && newArgumentsFromLegacyTag.type == ViewportArguments::ViewportMeta
+        && newArgumentsFromLegacyTag.maxWidth.type() == ViewportPercentageWidth
+        && !static_cast<int>(newArgumentsFromLegacyTag.zoom)) {
+        newArgumentsFromLegacyTag.zoom = 1.0;
+    }
+
+    setViewportArguments(newArgumentsFromLegacyTag);
+}
+
+void Document::setViewportArguments(const ViewportArguments& viewportArguments)
+{
+    if (viewportArguments.isLegacyViewportType()) {
+        m_legacyViewportArguments = viewportArguments;
+
+        // When no author style for @viewport is present, and a meta tag for defining
+        // the viewport is, apply the meta tag viewport instead of the UA styles.
+        if (m_viewportArguments.type == ViewportArguments::AuthorStyleSheet)
+            return;
+        m_viewportArguments = viewportArguments;
+    } else {
+        // If the legacy viewport tag has higher priority than the cascaded @viewport
+        // descriptors, use the values from the legacy tag.
+        if (!shouldOverrideLegacyViewport(viewportArguments.type))
+            m_viewportArguments = m_legacyViewportArguments;
+        else
+            m_viewportArguments = viewportArguments;
+    }
 
     updateViewportArguments();
 }
@@ -3137,34 +3314,21 @@
 
     bool needsRecalc = m_styleSheetCollections->updateActiveStyleSheets(updateMode);
 
-    if (updateType >= RecalcStyleDeferred) {
-        setNeedsStyleRecalc();
-        return;
-    }
-
     if (didLayoutWithPendingStylesheets() && !m_styleSheetCollections->hasPendingSheets()) {
+        // We need to manually repaint because we avoid doing all repaints in layout or style
+        // recalc while sheets are still loading to avoid FOUC.
         m_pendingSheetLayout = IgnoreLayoutWithPendingSheets;
-        if (renderer())
-            renderView()->repaintViewAndCompositedLayers();
+        renderView()->repaintViewAndCompositedLayers();
     }
 
     if (!needsRecalc)
         return;
 
-    // This recalcStyle initiates a new recalc cycle. We need to bracket it to
-    // make sure animations get the correct update time
-    {
-        AnimationUpdateBlock animationUpdateBlock(m_frame ? m_frame->animation() : 0);
-        recalcStyle(Force);
-    }
+    m_evaluateMediaQueriesOnStyleRecalc = true;
+    setNeedsStyleRecalc();
 
-    if (renderer()) {
-        renderer()->setNeedsLayoutAndPrefWidthsRecalc();
-        if (view())
-            view()->scheduleRelayout();
-    }
-
-    evaluateMediaQueryList();
+    if (updateType == RecalcStyleImmediately)
+        updateStyleIfNeeded();
 }
 
 void Document::notifySeamlessChildDocumentsOfStylesheetUpdate() const
@@ -3177,7 +3341,7 @@
     for (Frame* child = frame()->tree()->firstChild(); child; child = child->tree()->nextSibling()) {
         Document* childDocument = child->document();
         if (childDocument->shouldDisplaySeamlesslyWithParent()) {
-            ASSERT(childDocument->seamlessParentIFrame()->document() == this);
+            ASSERT(&childDocument->seamlessParentIFrame()->document() == this);
             childDocument->seamlessParentUpdatedStylesheets();
         }
     }
@@ -3203,7 +3367,7 @@
     if (!m_focusedElement)
         return;
 
-    Element* focusedElement = node->treeScope()->adjustedFocusedElement();
+    Element* focusedElement = node->treeScope().adjustedFocusedElement();
     if (!focusedElement)
         return;
 
@@ -3270,7 +3434,7 @@
     RefPtr<Element> newFocusedElement = prpNewFocusedElement;
 
     // Make sure newFocusedNode is actually in this document
-    if (newFocusedElement && (newFocusedElement->document() != this))
+    if (newFocusedElement && (&newFocusedElement->document() != this))
         return true;
 
     if (m_focusedElement == newFocusedElement)
@@ -3396,7 +3560,7 @@
 SetFocusedElementDone:
     updateStyleIfNeeded();
     if (Frame* frame = this->frame())
-        frame->selection()->didChangeFocus();
+        frame->selection().didChangeFocus();
     return !focusChangeBlocked;
 }
 
@@ -3479,7 +3643,7 @@
     if (Frame* frame = this->frame()) {
         for (Node* n = container->firstChild(); n; n = n->nextSibling()) {
             frame->eventHandler()->nodeWillBeRemoved(n);
-            frame->selection()->nodeWillBeRemoved(n);
+            frame->selection().nodeWillBeRemoved(n);
             frame->page()->dragCaretController().nodeWillBeRemoved(n);
         }
     }
@@ -3499,7 +3663,7 @@
 
     if (Frame* frame = this->frame()) {
         frame->eventHandler()->nodeWillBeRemoved(n);
-        frame->selection()->nodeWillBeRemoved(n);
+        frame->selection().nodeWillBeRemoved(n);
         frame->page()->dragCaretController().nodeWillBeRemoved(n);
     }
 }
@@ -3549,6 +3713,9 @@
             (*it)->textNodeSplit(oldNode);
     }
 
+    if (m_frame)
+        m_frame->selection().textNodeSplit(*oldNode);
+
     // FIXME: This should update markers for spelling and grammar checking.
 }
 
@@ -4132,14 +4299,23 @@
 
 Document* Document::topDocument() const
 {
-    Document* doc = const_cast<Document *>(this);
+    Document* doc = const_cast<Document*>(this);
     Element* element;
     while ((element = doc->ownerElement()))
-        doc = element->document();
+        doc = &element->document();
 
     return doc;
 }
 
+WeakPtr<Document> Document::contextDocument()
+{
+    if (m_contextDocument)
+        return m_contextDocument;
+    if (m_frame)
+        return m_weakFactory.createWeakPtr();
+    return WeakPtr<Document>(0);
+}
+
 PassRefPtr<Attr> Document::createAttribute(const String& name, ExceptionState& es)
 {
     return createAttributeNS(String(), name, es, true);
@@ -4158,7 +4334,7 @@
         return 0;
     }
 
-    return Attr::create(this, qName, emptyString());
+    return Attr::create(*this, qName, emptyString());
 }
 
 const SVGDocumentExtensions* Document::svgExtensions()
@@ -4353,7 +4529,7 @@
         return;
 
     m_useSecureKeyboardEntryWhenActive = usesSecureKeyboard;
-    m_frame->selection()->updateSecureKeyboardEntryIfActive();
+    m_frame->selection().updateSecureKeyboardEntryIfActive();
 }
 
 bool Document::useSecureKeyboardEntryWhenActive() const
@@ -4377,7 +4553,7 @@
 
 void Document::initSecurityContext()
 {
-    initSecurityContext(DocumentInit(m_url, m_frame, m_import));
+    initSecurityContext(DocumentInit(m_url, m_frame, contextDocument(), m_import));
 }
 
 void Document::initSecurityContext(const DocumentInit& initializer)
@@ -4421,7 +4597,7 @@
         }
     }
 
-    Document* parentDocument = ownerElement() ? ownerElement()->document() : 0;
+    Document* parentDocument = ownerElement() ? &ownerElement()->document() : 0;
     if (parentDocument && initializer.shouldTreatURLAsSrcdocDocument()) {
         m_isSrcdocDocument = true;
         setBaseURLOverride(parentDocument->baseURL());
@@ -4479,12 +4655,26 @@
         return false;
     if (!m_frame->script()->canExecuteScripts(NotAboutToExecuteScript))
         return false;
-    if (node && node->document() != this && !node->document()->allowInlineEventHandlers(node, listener, contextURL, contextLine))
+    if (node && &node->document() != this && !node->document().allowInlineEventHandlers(node, listener, contextURL, contextLine))
         return false;
 
     return true;
 }
 
+bool Document::allowExecutingScripts(Node* node)
+{
+    // FIXME: Eventually we'd like to evaluate scripts which are inserted into a
+    // viewless document but this'll do for now.
+    // See http://bugs.webkit.org/show_bug.cgi?id=5727
+    if (!frame() && !import())
+        return false;
+    if (!node->document().frame() && !node->document().import())
+        return false;
+    if (!contextDocument().get()->frame()->script()->canExecuteScripts(AboutToExecuteScript))
+        return false;
+    return true;
+}
+
 void Document::didUpdateSecurityOrigin()
 {
     if (!m_frame)
@@ -4558,7 +4748,7 @@
 {
     RefPtr<HTMLCanvasElement>& element = m_cssCanvasElements.add(name, 0).iterator->value;
     if (!element) {
-        element = HTMLCanvasElement::create(this);
+        element = HTMLCanvasElement::create(*this);
         element->setAccelerationDisabled(true);
     }
     return element.get();
@@ -4790,7 +4980,7 @@
 {
     if (m_topLayerElements.isEmpty())
         return 0;
-    return static_cast<HTMLDialogElement*>(m_topLayerElements.last().get());
+    return toHTMLDialogElement(m_topLayerElements.last().get());
 }
 
 void Document::webkitExitPointerLock()
@@ -4798,7 +4988,7 @@
     if (!page())
         return;
     if (Element* target = page()->pointerLockController().element()) {
-        if (target->document() != this)
+        if (&target->document() != this)
             return;
     }
     page()->pointerLockController().requestPointerUnlock();
@@ -4809,7 +4999,7 @@
     if (!page() || page()->pointerLockController().lockPending())
         return 0;
     if (Element* element = page()->pointerLockController().element()) {
-        if (element->document() == this)
+        if (&element->document() == this)
             return element;
     }
     return 0;
@@ -4866,44 +5056,6 @@
     return Touch::create(frame, target, identifier, screenX, screenY, pageX, pageY, radiusX, radiusY, rotationAngle, force);
 }
 
-static void wheelEventHandlerCountChanged(Document* document)
-{
-    Page* page = document->page();
-    if (!page)
-        return;
-
-    ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator();
-    if (!scrollingCoordinator)
-        return;
-
-    FrameView* frameView = document->view();
-    if (!frameView)
-        return;
-
-    scrollingCoordinator->frameViewWheelEventHandlerCountChanged(frameView);
-}
-
-void Document::didAddWheelEventHandler()
-{
-    ++m_wheelEventHandlerCount;
-    Frame* mainFrame = page() ? page()->mainFrame() : 0;
-    if (mainFrame)
-        mainFrame->notifyChromeClientWheelEventHandlerCountChanged();
-
-    wheelEventHandlerCountChanged(this);
-}
-
-void Document::didRemoveWheelEventHandler()
-{
-    ASSERT(m_wheelEventHandlerCount > 0);
-    --m_wheelEventHandlerCount;
-    Frame* mainFrame = page() ? page()->mainFrame() : 0;
-    if (mainFrame)
-        mainFrame->notifyChromeClientWheelEventHandlerCountChanged();
-
-    wheelEventHandlerCountChanged(this);
-}
-
 void Document::didAddTouchEventHandler(Node* handler)
 {
     if (!m_touchEventTargets.get())
@@ -5090,9 +5242,9 @@
     ASSERT(!request.readOnly());
 
     Element* innerElementInDocument = innerElement;
-    while (innerElementInDocument && innerElementInDocument->document() != this) {
-        innerElementInDocument->document()->updateHoverActiveState(request, innerElementInDocument, event);
-        innerElementInDocument = innerElementInDocument->document()->ownerElement();
+    while (innerElementInDocument && &innerElementInDocument->document() != this) {
+        innerElementInDocument->document().updateHoverActiveState(request, innerElementInDocument, event);
+        innerElementInDocument = innerElementInDocument->document().ownerElement();
     }
 
     Element* oldActiveElement = activeElement();
@@ -5246,19 +5398,22 @@
     return *(result.iterator->value);
 }
 
-Document* Document::ensureTemplateDocument()
+Document& Document::ensureTemplateDocument()
 {
     if (const Document* document = templateDocument())
-        return const_cast<Document*>(document);
+        return *const_cast<Document*>(document);
 
-    if (isHTMLDocument())
-        m_templateDocument = HTMLDocument::create(DocumentInit(blankURL()).withRegistrationContext(registrationContext()));
-    else
+    if (isHTMLDocument()) {
+        DocumentInit init = DocumentInit::fromContext(contextDocument(), blankURL())
+            .withRegistrationContext(registrationContext());
+        m_templateDocument = HTMLDocument::create(init);
+    } else {
         m_templateDocument = Document::create(DocumentInit(blankURL()));
+    }
 
     m_templateDocument->setTemplateDocumentHost(this); // balanced in dtor.
 
-    return m_templateDocument.get();
+    return *m_templateDocument.get();
 }
 
 PassRefPtr<FontLoader> Document::fontloader()
diff --git a/Source/core/dom/Document.h b/Source/core/dom/Document.h
index b5fc9e6..1d0be02 100644
--- a/Source/core/dom/Document.h
+++ b/Source/core/dom/Document.h
@@ -289,11 +289,13 @@
     DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitvisibilitychange);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(securitypolicyviolation);
 
-    void setViewportArguments(const ViewportArguments& viewportArguments) { m_viewportArguments = viewportArguments; }
+    bool shouldOverrideLegacyViewport(ViewportArguments::Type);
+    void setViewportArguments(const ViewportArguments&);
     const ViewportArguments& viewportArguments() const { return m_viewportArguments; }
 #ifndef NDEBUG
     bool didDispatchViewportPropertiesChanged() const { return m_didDispatchViewportPropertiesChanged; }
 #endif
+    bool hasLegacyViewportTag() const { return m_legacyViewportArguments.isLegacyViewportType(); }
 
     void setReferrerPolicy(ReferrerPolicy referrerPolicy) { m_referrerPolicy = referrerPolicy; }
     ReferrerPolicy referrerPolicy() const { return m_referrerPolicy; }
@@ -417,6 +419,7 @@
     bool isFrameSet() const;
 
     bool isSrcdocDocument() const { return m_isSrcdocDocument; }
+    bool isMobileDocument() const { return m_isMobileDocument; }
 
     StyleResolver* styleResolverIfExists() const { return m_styleResolver.get(); }
 
@@ -484,11 +487,14 @@
     PassRefPtr<CSSStyleDeclaration> createCSSStyleDeclaration();
     PassRefPtr<Text> createEditingTextNode(const String&);
 
-    void recalcStyle(StyleChange = NoChange);
+    void setStyleDependentState(RenderStyle* documentStyle);
+    void inheritHtmlAndBodyElementStyles(StyleRecalcChange);
+    void recalcStyle(StyleRecalcChange);
     void updateStyleIfNeeded();
     void updateStyleForNodeIfNeeded(Node*);
     void updateLayout();
     void updateLayoutIgnorePendingStylesheets();
+    void partialUpdateLayoutIgnorePendingStylesheets(Node*);
     PassRefPtr<RenderStyle> styleForElementIgnoringPendingStylesheets(Element*);
     PassRefPtr<RenderStyle> styleForPage(int pageIndex);
 
@@ -838,6 +844,7 @@
 
     Document* parentDocument() const;
     Document* topDocument() const;
+    WeakPtr<Document> contextDocument();
 
     ScriptRunner* scriptRunner() { return m_scriptRunner.get(); }
 
@@ -921,6 +928,7 @@
     void initContentSecurityPolicy(const ContentSecurityPolicyResponseHeaders&);
 
     bool allowInlineEventHandlers(Node*, EventListener*, const String& contextURL, const WTF::OrdinalNumber& contextLine);
+    bool allowExecutingScripts(Node*);
 
     void statePopped(PassRefPtr<SerializedScriptValue>);
 
@@ -978,10 +986,6 @@
 
     void initDNSPrefetch();
 
-    unsigned wheelEventHandlerCount() const { return m_wheelEventHandlerCount; }
-    void didAddWheelEventHandler();
-    void didRemoveWheelEventHandler();
-
     double lastHandledUserGestureTimestamp() const { return m_lastHandledUserGestureTimestamp; }
     void resetLastHandledUserGestureTimestamp();
 
@@ -1048,7 +1052,7 @@
     HTMLDialogElement* activeModalDialog() const;
 
     const Document* templateDocument() const;
-    Document* ensureTemplateDocument();
+    Document& ensureTemplateDocument();
     void setTemplateDocumentHost(Document* templateDocumentHost) { m_templateDocumentHost = templateDocumentHost; }
     Document* templateDocumentHost() { return m_templateDocumentHost; }
 
@@ -1119,6 +1123,8 @@
 
     void seamlessParentUpdatedStylesheets();
 
+    void recalcStyleForLayoutIgnoringPendingStylesheets();
+
     PassRefPtr<NodeList> handleZeroPadding(const HitTestRequest&, HitTestResult&) const;
 
     void loadEventDelayTimerFired(Timer<Document>*);
@@ -1161,6 +1167,7 @@
     // But sometimes you need to ignore pending stylesheet count to
     // force an immediate layout when requested by JS.
     bool m_ignorePendingStylesheets;
+    bool m_evaluateMediaQueriesOnStyleRecalc;
 
     // If we do ignore the pending stylesheet count, then we need to add a boolean
     // to track that this happened so that we can do a full repaint when the stylesheets
@@ -1308,11 +1315,13 @@
     bool m_isViewSource;
     bool m_sawElementsInKnownNamespaces;
     bool m_isSrcdocDocument;
+    bool m_isMobileDocument;
 
     RenderObject* m_renderer;
     RefPtr<DocumentEventQueue> m_eventQueue;
 
     WeakPtrFactory<Document> m_weakFactory;
+    WeakPtr<Document> m_contextDocument;
 
     QualifiedName m_idAttributeName;
 
@@ -1324,6 +1333,7 @@
     Timer<Document> m_loadEventDelayTimer;
 
     ViewportArguments m_viewportArguments;
+    ViewportArguments m_legacyViewportArguments;
 
     ReferrerPolicy m_referrerPolicy;
 
@@ -1337,7 +1347,6 @@
     bool m_writeRecursionIsTooDeep;
     unsigned m_writeRecursionDepth;
 
-    unsigned m_wheelEventHandlerCount;
     OwnPtr<TouchEventTargetSet> m_touchEventTargets;
 
     double m_lastHandledUserGestureTimestamp;
@@ -1397,6 +1406,14 @@
     return m_templateDocument.get();
 }
 
+inline bool Document::shouldOverrideLegacyViewport(ViewportArguments::Type origin)
+{
+    // The different (legacy) meta tags have different priorities based on the type
+    // regardless of which order they appear in the DOM. The priority is given by the
+    // ViewportArguments::Type enum.
+    return origin >= m_legacyViewportArguments.type;
+}
+
 inline Document* toDocument(ScriptExecutionContext* scriptExecutionContext)
 {
     ASSERT_WITH_SECURITY_IMPLICATION(!scriptExecutionContext || scriptExecutionContext->isDocument());
diff --git a/Source/core/dom/Document.idl b/Source/core/dom/Document.idl
index bea2b66..f2fba14 100644
--- a/Source/core/dom/Document.idl
+++ b/Source/core/dom/Document.idl
@@ -165,9 +165,9 @@
     void webkitExitPointerLock();
     readonly attribute Element webkitPointerLockElement;
 
-    [EnabledAtRuntime=cssRegions] WebKitNamedFlowCollection webkitGetNamedFlows();
+    [EnabledAtRuntime=CSSRegions] WebKitNamedFlowCollection webkitGetNamedFlows();
 
-    [EnabledAtRuntime=fontLoadEvents] readonly attribute FontLoader fontloader;
+    [EnabledAtRuntime=FontLoadEvents] readonly attribute FontLoader fontloader;
 
     // Event handler DOM attributes
     [NotEnumerable] attribute EventHandler onabort;
@@ -238,17 +238,17 @@
     [NotEnumerable] attribute EventHandler onsearch;
     [NotEnumerable] attribute EventHandler onselectstart;
     [NotEnumerable] attribute EventHandler onselectionchange;
-    [NotEnumerable,EnabledAtRuntime=touch] attribute EventHandler ontouchstart;
-    [NotEnumerable,EnabledAtRuntime=touch] attribute EventHandler ontouchmove;
-    [NotEnumerable,EnabledAtRuntime=touch] attribute EventHandler ontouchend;
-    [NotEnumerable,EnabledAtRuntime=touch] attribute EventHandler ontouchcancel;
+    [NotEnumerable, EnabledAtRuntime=Touch] attribute EventHandler ontouchstart;
+    [NotEnumerable, EnabledAtRuntime=Touch] attribute EventHandler ontouchmove;
+    [NotEnumerable, EnabledAtRuntime=Touch] attribute EventHandler ontouchend;
+    [NotEnumerable, EnabledAtRuntime=Touch] attribute EventHandler ontouchcancel;
     [NotEnumerable] attribute EventHandler onwebkitfullscreenchange;
     [NotEnumerable] attribute EventHandler onwebkitfullscreenerror;
     [NotEnumerable] attribute EventHandler onwebkitpointerlockchange;
     [NotEnumerable] attribute EventHandler onwebkitpointerlockerror;
-    [NotEnumerable, EnabledAtRuntime=experimentalContentSecurityPolicyFeatures] attribute EventHandler onsecuritypolicyviolation;
+    [NotEnumerable, EnabledAtRuntime=ExperimentalContentSecurityPolicyFeatures] attribute EventHandler onsecuritypolicyviolation;
 
-    [EnabledAtRuntime=touch] Touch createTouch([Default=Undefined] optional Window window,
+    [EnabledAtRuntime=Touch] Touch createTouch([Default=Undefined] optional Window window,
                                                [Default=Undefined] optional EventTarget target,
                                                [Default=Undefined] optional long identifier,
                                                [Default=Undefined] optional long pageX,
@@ -259,10 +259,10 @@
                                                [Default=Undefined] optional long webkitRadiusY,
                                                [Default=Undefined] optional float webkitRotationAngle,
                                                [Default=Undefined] optional float webkitForce);
-    [EnabledAtRuntime=touch, Custom, RaisesException] TouchList createTouchList();
+    [EnabledAtRuntime=Touch, Custom, RaisesException] TouchList createTouchList();
 
-    [DeprecateAs=PrefixedDocumentRegister, EnabledAtRuntime=customElements, ImplementedAs=registerElement, CallWith=ScriptState, CustomElementCallbacks=Enable, RaisesException] CustomElementConstructor webkitRegister(DOMString name, optional Dictionary options);
-    [EnabledAtRuntime=customElements, ImplementedAs=registerElement, CallWith=ScriptState, CustomElementCallbacks=Enable, RaisesException] CustomElementConstructor register(DOMString name, optional Dictionary options);
+    [DeprecateAs=PrefixedDocumentRegister, EnabledAtRuntime=CustomElements, ImplementedAs=registerElement, CallWith=ScriptState, CustomElementCallbacks=Enable, RaisesException] CustomElementConstructor webkitRegister(DOMString name, optional Dictionary options);
+    [EnabledAtRuntime=CustomElements, ImplementedAs=registerElement, CallWith=ScriptState, CustomElementCallbacks=Enable, RaisesException] CustomElementConstructor register(DOMString name, optional Dictionary options);
     [CustomElementCallbacks=Enable, PerWorldBindings, ActivityLog=AccessForIsolatedWorlds, RaisesException] Element createElement(DOMString localName, [TreatNullAs=NullString] DOMString typeExtension);
     [CustomElementCallbacks=Enable, PerWorldBindings, ActivityLog=AccessForIsolatedWorlds, RaisesException] Element createElementNS([TreatNullAs=NullString] DOMString namespaceURI, DOMString qualifiedName,
                             [TreatNullAs=NullString] DOMString typeExtension);
@@ -272,7 +272,7 @@
     readonly attribute boolean webkitHidden;
 
     // Security Policy API: http://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html#script-interfaces
-    [EnabledAtRuntime=experimentalContentSecurityPolicyFeatures] readonly attribute SecurityPolicy securityPolicy;
+    [EnabledAtRuntime=ExperimentalContentSecurityPolicyFeatures] readonly attribute SecurityPolicy securityPolicy;
 
     readonly attribute HTMLScriptElement currentScript;
 };
diff --git a/Source/core/dom/DocumentEventQueue.cpp b/Source/core/dom/DocumentEventQueue.cpp
index 8768c1e..eba99c1 100644
--- a/Source/core/dom/DocumentEventQueue.cpp
+++ b/Source/core/dom/DocumentEventQueue.cpp
@@ -80,12 +80,11 @@
 
 void DocumentEventQueue::enqueueOrDispatchScrollEvent(PassRefPtr<Node> target, ScrollEventTargetType targetType)
 {
-    if (!target->document()->hasListenerType(Document::SCROLL_LISTENER))
+    if (!target->document().hasListenerType(Document::SCROLL_LISTENER))
         return;
 
     // Per the W3C CSSOM View Module, scroll events fired at the document should bubble, others should not.
-    bool canBubble = targetType == ScrollEventDocumentTarget;
-    RefPtr<Event> scrollEvent = Event::create(eventNames().scrollEvent, canBubble, false /* non cancelleable */);
+    RefPtr<Event> scrollEvent = targetType == ScrollEventDocumentTarget ? Event::createBubble(eventNames().scrollEvent) : Event::create(eventNames().scrollEvent);
 
     if (!m_nodesWithQueuedScrollEvents.add(target.get()).isNewEntry)
         return;
diff --git a/Source/core/dom/DocumentFragment.cpp b/Source/core/dom/DocumentFragment.cpp
index 6f052be..141d571 100644
--- a/Source/core/dom/DocumentFragment.cpp
+++ b/Source/core/dom/DocumentFragment.cpp
@@ -35,10 +35,9 @@
     ScriptWrappable::init(this);
 }
 
-PassRefPtr<DocumentFragment> DocumentFragment::create(Document* document)
+PassRefPtr<DocumentFragment> DocumentFragment::create(Document& document)
 {
-    ASSERT(document);
-    return adoptRef(new DocumentFragment(document, Node::CreateDocumentFragment));
+    return adoptRef(new DocumentFragment(&document, Node::CreateDocumentFragment));
 }
 
 String DocumentFragment::nodeName() const
diff --git a/Source/core/dom/DocumentFragment.h b/Source/core/dom/DocumentFragment.h
index 82e7f6e..ed8a76a 100644
--- a/Source/core/dom/DocumentFragment.h
+++ b/Source/core/dom/DocumentFragment.h
@@ -33,7 +33,7 @@
 
 class DocumentFragment : public ContainerNode {
 public:
-    static PassRefPtr<DocumentFragment> create(Document*);
+    static PassRefPtr<DocumentFragment> create(Document&);
 
     void parseHTML(const String&, Element* contextElement, ParserContentPolicy = AllowScriptingContent);
     bool parseXML(const String&, Element* contextElement, ParserContentPolicy = AllowScriptingContent);
@@ -51,6 +51,18 @@
     virtual bool childTypeAllowed(NodeType) const;
 };
 
-} //namespace
+inline DocumentFragment* toDocumentFragment(Node* node)
+{
+    ASSERT_WITH_SECURITY_IMPLICATION(!node || node->nodeType() == Node::DOCUMENT_FRAGMENT_NODE);
+    return static_cast<DocumentFragment*>(node);
+}
+
+inline const DocumentFragment* toDocumentFragment(const Node* node)
+{
+    ASSERT_WITH_SECURITY_IMPLICATION(!node || node->nodeType() == Node::DOCUMENT_FRAGMENT_NODE);
+    return static_cast<const DocumentFragment*>(node);
+}
+
+} // namespace WebCore
 
 #endif
diff --git a/Source/core/dom/DocumentFullscreen.idl b/Source/core/dom/DocumentFullscreen.idl
index 854492e..3081eac 100644
--- a/Source/core/dom/DocumentFullscreen.idl
+++ b/Source/core/dom/DocumentFullscreen.idl
@@ -20,13 +20,13 @@
  */
 partial interface Document {
     // Mozilla version
-    [EnabledAtRuntime=fullscreen] readonly attribute boolean webkitIsFullScreen;
-    [EnabledAtRuntime=fullscreen] readonly attribute boolean webkitFullScreenKeyboardInputAllowed;
-    [EnabledAtRuntime=fullscreen] readonly attribute Element webkitCurrentFullScreenElement;
-    [EnabledAtRuntime=fullscreen] void webkitCancelFullScreen();
+    [EnabledAtRuntime=Fullscreen] readonly attribute boolean webkitIsFullScreen;
+    [EnabledAtRuntime=Fullscreen] readonly attribute boolean webkitFullScreenKeyboardInputAllowed;
+    [EnabledAtRuntime=Fullscreen] readonly attribute Element webkitCurrentFullScreenElement;
+    [EnabledAtRuntime=Fullscreen] void webkitCancelFullScreen();
 
     // W3C version
-    [EnabledAtRuntime=fullscreen] readonly attribute boolean webkitFullscreenEnabled;
-    [EnabledAtRuntime=fullscreen] readonly attribute Element webkitFullscreenElement;
-    [EnabledAtRuntime=fullscreen] void webkitExitFullscreen();
+    [EnabledAtRuntime=Fullscreen] readonly attribute boolean webkitFullscreenEnabled;
+    [EnabledAtRuntime=Fullscreen] readonly attribute Element webkitFullscreenElement;
+    [EnabledAtRuntime=Fullscreen] void webkitExitFullscreen();
 };
diff --git a/Source/core/dom/DocumentInit.cpp b/Source/core/dom/DocumentInit.cpp
index caa4f8f..ba30041 100644
--- a/Source/core/dom/DocumentInit.cpp
+++ b/Source/core/dom/DocumentInit.cpp
@@ -29,12 +29,34 @@
 #include "core/dom/DocumentInit.h"
 
 #include "RuntimeEnabledFeatures.h"
+#include "core/dom/CustomElementRegistrationContext.h"
 #include "core/dom/Document.h"
 #include "core/html/HTMLImportsController.h"
 #include "core/page/Frame.h"
 
 namespace WebCore {
 
+DocumentInit::DocumentInit(const KURL& url, Frame* frame, WeakPtr<Document> contextDocument, HTMLImport* import)
+    : m_url(url)
+    , m_frame(frame)
+    , m_contextDocument(contextDocument)
+    , m_import(import)
+{
+}
+
+DocumentInit::DocumentInit(const DocumentInit& other)
+    : m_url(other.m_url)
+    , m_frame(other.m_frame)
+    , m_contextDocument(other.m_contextDocument)
+    , m_import(other.m_import)
+    , m_registrationContext(other.m_registrationContext)
+{
+}
+
+DocumentInit::~DocumentInit()
+{
+}
+
 bool DocumentInit::shouldSetURL() const
 {
     Frame* frame = frameForSecurityContext();
@@ -100,5 +122,15 @@
     return CustomElementRegistrationContext::create();
 }
 
+WeakPtr<Document> DocumentInit::contextDocument() const
+{
+    return m_contextDocument;
+}
+
+DocumentInit DocumentInit::fromContext(WeakPtr<Document> contextDocument, const KURL& url)
+{
+    return DocumentInit(url, 0, contextDocument, 0);
+}
+
 } // namespace WebCore
 
diff --git a/Source/core/dom/DocumentInit.h b/Source/core/dom/DocumentInit.h
index 73ce2be..b647e4e 100644
--- a/Source/core/dom/DocumentInit.h
+++ b/Source/core/dom/DocumentInit.h
@@ -28,14 +28,15 @@
 #ifndef DocumentInit_h
 #define DocumentInit_h
 
-#include "core/dom/CustomElementRegistrationContext.h"
 #include "core/dom/SecurityContext.h"
 #include "weborigin/KURL.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefPtr.h"
+#include "wtf/WeakPtr.h"
 
 namespace WebCore {
 
+class CustomElementRegistrationContext;
 class Document;
 class Frame;
 class HTMLImport;
@@ -43,11 +44,9 @@
 
 class DocumentInit {
 public:
-    explicit DocumentInit(const KURL& url = KURL(), Frame* frame = 0, HTMLImport* import = 0)
-        : m_url(url)
-        , m_frame(frame)
-        , m_import(import)
-    { }
+    explicit DocumentInit(const KURL& = KURL(), Frame* = 0, WeakPtr<Document> = WeakPtr<Document>(), HTMLImport* = 0);
+    DocumentInit(const DocumentInit&);
+    ~DocumentInit();
 
     const KURL& url() const { return m_url; }
     Frame* frame() const { return m_frame; }
@@ -63,12 +62,16 @@
 
     DocumentInit& withRegistrationContext(CustomElementRegistrationContext*);
     PassRefPtr<CustomElementRegistrationContext> registrationContext(Document*) const;
+    WeakPtr<Document> contextDocument() const;
+
+    static DocumentInit fromContext(WeakPtr<Document> contextDocument, const KURL& = KURL());
 
 private:
     Frame* frameForSecurityContext() const;
 
     KURL m_url;
     Frame* m_frame;
+    WeakPtr<Document> m_contextDocument;
     HTMLImport* m_import;
     RefPtr<CustomElementRegistrationContext> m_registrationContext;
 };
diff --git a/Source/core/dom/DocumentMarkerController.cpp b/Source/core/dom/DocumentMarkerController.cpp
index 168772b..0682b64 100644
--- a/Source/core/dom/DocumentMarkerController.cpp
+++ b/Source/core/dom/DocumentMarkerController.cpp
@@ -346,20 +346,6 @@
     return result;
 }
 
-// FIXME: Should be removed after all relevant patches are landed
-Vector<DocumentMarker> DocumentMarkerController::markersForNode(Node* node)
-{
-    Vector<DocumentMarker> result;
-    MarkerList* list = m_markers.get(node);
-    if (!list)
-        return result;
-
-    for (size_t i = 0; i < list->size(); ++i)
-        result.append(list->at(i));
-
-    return result;
-}
-
 Vector<DocumentMarker*> DocumentMarkerController::markers()
 {
     Vector<DocumentMarker*> result;
diff --git a/Source/core/dom/DocumentMarkerController.h b/Source/core/dom/DocumentMarkerController.h
index 59fca3e..0b14aaa 100644
--- a/Source/core/dom/DocumentMarkerController.h
+++ b/Source/core/dom/DocumentMarkerController.h
@@ -76,7 +76,6 @@
     DocumentMarker* markerContainingPoint(const LayoutPoint&, DocumentMarker::MarkerType);
     Vector<DocumentMarker*> markersFor(Node*, DocumentMarker::MarkerTypes = DocumentMarker::AllMarkers());
     Vector<DocumentMarker*> markersInRange(Range*, DocumentMarker::MarkerTypes);
-    Vector<DocumentMarker> markersForNode(Node*);
     Vector<DocumentMarker*> markers();
     Vector<IntRect> renderedRectsForMarkers(DocumentMarker::MarkerType);
 
diff --git a/Source/core/dom/DocumentStyleSheetCollection.cpp b/Source/core/dom/DocumentStyleSheetCollection.cpp
index 3fa1ce5..8055751 100644
--- a/Source/core/dom/DocumentStyleSheetCollection.cpp
+++ b/Source/core/dom/DocumentStyleSheetCollection.cpp
@@ -45,10 +45,10 @@
 
 using namespace HTMLNames;
 
-DocumentStyleSheetCollection::DocumentStyleSheetCollection(TreeScope* treeScope)
+DocumentStyleSheetCollection::DocumentStyleSheetCollection(TreeScope& treeScope)
     : StyleSheetCollection(treeScope)
 {
-    ASSERT(treeScope->rootNode() == treeScope->rootNode()->document());
+    ASSERT(treeScope.rootNode() == &treeScope.rootNode()->document());
 }
 
 void DocumentStyleSheetCollection::collectStyleSheets(StyleSheetCollections* collections, Vector<RefPtr<StyleSheet> >& styleSheets, Vector<RefPtr<CSSStyleSheet> >& activeSheets)
@@ -65,7 +65,7 @@
         if (n->nodeType() == Node::PROCESSING_INSTRUCTION_NODE && !document()->isHTMLDocument()) {
             // Processing instruction (XML documents only).
             // We don't support linking to embedded CSS stylesheets, see <https://bugs.webkit.org/show_bug.cgi?id=49281> for discussion.
-            ProcessingInstruction* pi = static_cast<ProcessingInstruction*>(n);
+            ProcessingInstruction* pi = toProcessingInstruction(n);
             // Don't apply XSL transforms to already transformed documents -- <rdar://problem/4132806>
             if (pi->isXSL() && !document()->transformSourceDocument()) {
                 // Don't apply XSL transforms until loading is finished.
@@ -102,7 +102,7 @@
             } else if (n->isSVGElement() && n->hasTagName(SVGNames::styleTag)) {
                 sheet = static_cast<SVGStyleElement*>(n)->sheet();
             } else {
-                sheet = static_cast<HTMLStyleElement*>(n)->sheet();
+                sheet = toHTMLStyleElement(n)->sheet();
             }
 
             if (sheet && !sheet->disabled() && sheet->isCSSStyleSheet())
@@ -143,7 +143,7 @@
     HTMLIFrameElement* seamlessParentIFrame = document->seamlessParentIFrame();
     if (!seamlessParentIFrame)
         return;
-    sheets.append(seamlessParentIFrame->document()->styleSheetCollections()->activeAuthorStyleSheets());
+    sheets.append(seamlessParentIFrame->document().styleSheetCollections()->activeAuthorStyleSheets());
 }
 
 bool DocumentStyleSheetCollection::updateActiveStyleSheets(StyleSheetCollections* collections, StyleResolverUpdateMode updateMode)
diff --git a/Source/core/dom/DocumentStyleSheetCollection.h b/Source/core/dom/DocumentStyleSheetCollection.h
index 4072cc8..9f035f0 100644
--- a/Source/core/dom/DocumentStyleSheetCollection.h
+++ b/Source/core/dom/DocumentStyleSheetCollection.h
@@ -41,7 +41,7 @@
 class DocumentStyleSheetCollection FINAL : public StyleSheetCollection {
     WTF_MAKE_NONCOPYABLE(DocumentStyleSheetCollection); WTF_MAKE_FAST_ALLOCATED;
 public:
-    explicit DocumentStyleSheetCollection(TreeScope*);
+    explicit DocumentStyleSheetCollection(TreeScope&);
 
     bool updateActiveStyleSheets(StyleSheetCollections*, StyleResolverUpdateMode);
 
diff --git a/Source/core/dom/DocumentType.cpp b/Source/core/dom/DocumentType.cpp
index 12fbd2f..7c392a7 100644
--- a/Source/core/dom/DocumentType.cpp
+++ b/Source/core/dom/DocumentType.cpp
@@ -54,7 +54,7 @@
 
 PassRefPtr<Node> DocumentType::cloneNode(bool /*deep*/)
 {
-    return create(document(), m_name, m_publicId, m_systemId);
+    return create(&document(), m_name, m_publicId, m_systemId);
 }
 
 Node::InsertionNotificationRequest DocumentType::insertedInto(ContainerNode* insertionPoint)
@@ -64,14 +64,14 @@
     // DocumentType can only be inserted into a Document.
     ASSERT(parentNode()->isDocumentNode());
 
-    document()->setDoctype(this);
+    document().setDoctype(this);
 
     return InsertionDone;
 }
 
 void DocumentType::removedFrom(ContainerNode* insertionPoint)
 {
-    document()->setDoctype(0);
+    document().setDoctype(0);
     Node::removedFrom(insertionPoint);
 }
 
diff --git a/Source/core/dom/DocumentType.h b/Source/core/dom/DocumentType.h
index 0ad56fa..7da8ac8 100644
--- a/Source/core/dom/DocumentType.h
+++ b/Source/core/dom/DocumentType.h
@@ -64,6 +64,18 @@
     String m_subset;
 };
 
+inline DocumentType* toDocumentType(Node* node)
+{
+    ASSERT_WITH_SECURITY_IMPLICATION(!node || node->nodeType() == Node::DOCUMENT_TYPE_NODE);
+    return static_cast<DocumentType*>(node);
+}
+
+inline const DocumentType* toDocumentType(const Node* node)
+{
+    ASSERT_WITH_SECURITY_IMPLICATION(!node || node->nodeType() == Node::DOCUMENT_TYPE_NODE);
+    return static_cast<const DocumentType*>(node);
+}
+
 } // namespace WebCore
 
 #endif
diff --git a/Source/core/dom/Element.cpp b/Source/core/dom/Element.cpp
index ce5e91a..02518c5 100644
--- a/Source/core/dom/Element.cpp
+++ b/Source/core/dom/Element.cpp
@@ -61,6 +61,7 @@
 #include "core/dom/NamedNodeMap.h"
 #include "core/dom/NodeRenderStyle.h"
 #include "core/dom/NodeRenderingContext.h"
+#include "core/dom/PostAttachCallbacks.h"
 #include "core/dom/PseudoElement.h"
 #include "core/dom/ScriptableDocumentParser.h"
 #include "core/dom/SelectorQuery.h"
@@ -104,7 +105,7 @@
 
 static inline bool shouldIgnoreAttributeCase(const Element* e)
 {
-    return e && e->document()->isHTMLDocument() && e->isHTMLElement();
+    return e && e->document().isHTMLDocument() && e->isHTMLElement();
 }
 
 class StyleResolverParentPusher {
@@ -118,7 +119,7 @@
     {
         if (m_pushedStyleResolver)
             return;
-        m_pushedStyleResolver = m_parent->document()->styleResolver();
+        m_pushedStyleResolver = m_parent->document().styleResolver();
         m_pushedStyleResolver->pushParentElement(m_parent);
     }
     ~StyleResolverParentPusher()
@@ -129,8 +130,8 @@
 
         // This tells us that our pushed style selector is in a bad state,
         // so we should just bail out in that scenario.
-        ASSERT(m_pushedStyleResolver == m_parent->document()->styleResolver());
-        if (m_pushedStyleResolver != m_parent->document()->styleResolver())
+        ASSERT(m_pushedStyleResolver == m_parent->document().styleResolver());
+        if (m_pushedStyleResolver != m_parent->document().styleResolver())
             return;
 
         m_pushedStyleResolver->popParentElement(m_parent);
@@ -195,7 +196,7 @@
 Element::~Element()
 {
 #ifndef NDEBUG
-    if (document() && document()->renderer()) {
+    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.
@@ -226,7 +227,7 @@
         detachAllAttrNodesFromElement();
 
     if (hasPendingResources()) {
-        document()->accessSVGExtensions()->removeElementFromPendingResources(this);
+        document().accessSVGExtensions()->removeElementFromPendingResources(this);
         ASSERT(!hasPendingResources());
     }
 }
@@ -284,7 +285,7 @@
         // We can't just use needsStyleRecalc() because if the node is in a
         // display:none tree it might say it needs style recalc but the whole
         // document is actually up to date.
-        ASSERT(!document()->childNeedsStyleRecalc());
+        ASSERT(!document().childNeedsStyleRecalc());
     }
 
     // FIXME: Even if we are not visible, we might have a child that is visible.
@@ -325,7 +326,7 @@
 
 PassRefPtr<Element> Element::cloneElementWithoutAttributesAndChildren()
 {
-    return document()->createElement(tagQName(), false);
+    return document().createElement(tagQName(), false);
 }
 
 PassRefPtr<Attr> Element::detachAttribute(size_t index)
@@ -480,7 +481,7 @@
 
 void Element::scrollIntoView(bool alignToTop)
 {
-    document()->updateLayoutIgnorePendingStylesheets();
+    document().updateLayoutIgnorePendingStylesheets();
 
     if (!renderer())
         return;
@@ -495,7 +496,7 @@
 
 void Element::scrollIntoViewIfNeeded(bool centerIfNeeded)
 {
-    document()->updateLayoutIgnorePendingStylesheets();
+    document().updateLayoutIgnorePendingStylesheets();
 
     if (!renderer())
         return;
@@ -509,7 +510,7 @@
 
 void Element::scrollByUnits(int units, ScrollGranularity granularity)
 {
-    document()->updateLayoutIgnorePendingStylesheets();
+    document().updateLayoutIgnorePendingStylesheets();
 
     if (!renderer())
         return;
@@ -569,7 +570,7 @@
 
 int Element::offsetLeft()
 {
-    document()->updateLayoutIgnorePendingStylesheets();
+    document().partialUpdateLayoutIgnorePendingStylesheets(this);
     if (RenderBoxModelObject* renderer = renderBoxModelObject())
         return adjustForLocalZoom(renderer->pixelSnappedOffsetLeft(), renderer);
     return 0;
@@ -577,7 +578,7 @@
 
 int Element::offsetTop()
 {
-    document()->updateLayoutIgnorePendingStylesheets();
+    document().partialUpdateLayoutIgnorePendingStylesheets(this);
     if (RenderBoxModelObject* renderer = renderBoxModelObject())
         return adjustForLocalZoom(renderer->pixelSnappedOffsetTop(), renderer);
     return 0;
@@ -585,14 +586,14 @@
 
 int Element::offsetWidth()
 {
-    document()->updateStyleForNodeIfNeeded(this);
+    document().updateStyleForNodeIfNeeded(this);
 
     if (RenderBox* renderer = renderBox()) {
         if (!renderer->requiresLayoutToDetermineWidth())
             return adjustLayoutUnitForAbsoluteZoom(renderer->fixedOffsetWidth(), renderer).round();
     }
 
-    document()->updateLayoutIgnorePendingStylesheets();
+    document().partialUpdateLayoutIgnorePendingStylesheets(this);
     if (RenderBoxModelObject* renderer = renderBoxModelObject())
         return adjustLayoutUnitForAbsoluteZoom(renderer->pixelSnappedOffsetWidth(), renderer).round();
     return 0;
@@ -600,7 +601,7 @@
 
 int Element::offsetHeight()
 {
-    document()->updateLayoutIgnorePendingStylesheets();
+    document().partialUpdateLayoutIgnorePendingStylesheets(this);
     if (RenderBoxModelObject* renderer = renderBoxModelObject())
         return adjustLayoutUnitForAbsoluteZoom(renderer->pixelSnappedOffsetHeight(), renderer).round();
     return 0;
@@ -616,7 +617,7 @@
 
 Element* Element::offsetParent()
 {
-    document()->updateLayoutIgnorePendingStylesheets();
+    document().updateLayoutIgnorePendingStylesheets();
     if (RenderObject* renderer = this->renderer())
         return renderer->offsetParent();
     return 0;
@@ -624,7 +625,7 @@
 
 int Element::clientLeft()
 {
-    document()->updateLayoutIgnorePendingStylesheets();
+    document().updateLayoutIgnorePendingStylesheets();
 
     if (RenderBox* renderer = renderBox())
         return adjustForAbsoluteZoom(roundToInt(renderer->clientLeft()), renderer);
@@ -633,7 +634,7 @@
 
 int Element::clientTop()
 {
-    document()->updateLayoutIgnorePendingStylesheets();
+    document().updateLayoutIgnorePendingStylesheets();
 
     if (RenderBox* renderer = renderBox())
         return adjustForAbsoluteZoom(roundToInt(renderer->clientTop()), renderer);
@@ -642,15 +643,15 @@
 
 int Element::clientWidth()
 {
-    document()->updateLayoutIgnorePendingStylesheets();
+    document().updateLayoutIgnorePendingStylesheets();
 
     // When in strict mode, clientWidth for the document element should return the width of the containing frame.
     // When in quirks mode, clientWidth for the body element should return the width of the containing frame.
-    bool inQuirksMode = document()->inQuirksMode();
-    if ((!inQuirksMode && document()->documentElement() == this) ||
-        (inQuirksMode && isHTMLElement() && document()->body() == this)) {
-        if (FrameView* view = document()->view()) {
-            if (RenderView* renderView = document()->renderView())
+    bool inQuirksMode = document().inQuirksMode();
+    if ((!inQuirksMode && document().documentElement() == this)
+        || (inQuirksMode && isHTMLElement() && document().body() == this)) {
+        if (FrameView* view = document().view()) {
+            if (RenderView* renderView = document().renderView())
                 return adjustForAbsoluteZoom(view->layoutWidth(), renderView);
         }
     }
@@ -662,16 +663,16 @@
 
 int Element::clientHeight()
 {
-    document()->updateLayoutIgnorePendingStylesheets();
+    document().updateLayoutIgnorePendingStylesheets();
 
     // When in strict mode, clientHeight for the document element should return the height of the containing frame.
     // When in quirks mode, clientHeight for the body element should return the height of the containing frame.
-    bool inQuirksMode = document()->inQuirksMode();
+    bool inQuirksMode = document().inQuirksMode();
 
-    if ((!inQuirksMode && document()->documentElement() == this) ||
-        (inQuirksMode && isHTMLElement() && document()->body() == this)) {
-        if (FrameView* view = document()->view()) {
-            if (RenderView* renderView = document()->renderView())
+    if ((!inQuirksMode && document().documentElement() == this)
+        || (inQuirksMode && isHTMLElement() && document().body() == this)) {
+        if (FrameView* view = document().view()) {
+            if (RenderView* renderView = document().renderView())
                 return adjustForAbsoluteZoom(view->layoutHeight(), renderView);
         }
     }
@@ -683,7 +684,7 @@
 
 int Element::scrollLeft()
 {
-    document()->updateLayoutIgnorePendingStylesheets();
+    document().updateLayoutIgnorePendingStylesheets();
     if (RenderBox* rend = renderBox())
         return adjustForAbsoluteZoom(rend->scrollLeft(), rend);
     return 0;
@@ -691,7 +692,7 @@
 
 int Element::scrollTop()
 {
-    document()->updateLayoutIgnorePendingStylesheets();
+    document().updateLayoutIgnorePendingStylesheets();
     if (RenderBox* rend = renderBox())
         return adjustForAbsoluteZoom(rend->scrollTop(), rend);
     return 0;
@@ -699,21 +700,21 @@
 
 void Element::setScrollLeft(int newLeft)
 {
-    document()->updateLayoutIgnorePendingStylesheets();
+    document().updateLayoutIgnorePendingStylesheets();
     if (RenderBox* rend = renderBox())
         rend->setScrollLeft(static_cast<int>(newLeft * rend->style()->effectiveZoom()));
 }
 
 void Element::setScrollTop(int newTop)
 {
-    document()->updateLayoutIgnorePendingStylesheets();
+    document().updateLayoutIgnorePendingStylesheets();
     if (RenderBox* rend = renderBox())
         rend->setScrollTop(static_cast<int>(newTop * rend->style()->effectiveZoom()));
 }
 
 int Element::scrollWidth()
 {
-    document()->updateLayoutIgnorePendingStylesheets();
+    document().updateLayoutIgnorePendingStylesheets();
     if (RenderBox* rend = renderBox())
         return adjustForAbsoluteZoom(rend->scrollWidth(), rend);
     return 0;
@@ -721,7 +722,7 @@
 
 int Element::scrollHeight()
 {
-    document()->updateLayoutIgnorePendingStylesheets();
+    document().updateLayoutIgnorePendingStylesheets();
     if (RenderBox* rend = renderBox())
         return adjustForAbsoluteZoom(rend->scrollHeight(), rend);
     return 0;
@@ -729,9 +730,9 @@
 
 IntRect Element::boundsInRootViewSpace()
 {
-    document()->updateLayoutIgnorePendingStylesheets();
+    document().updateLayoutIgnorePendingStylesheets();
 
-    FrameView* view = document()->view();
+    FrameView* view = document().view();
     if (!view)
         return IntRect();
 
@@ -761,7 +762,7 @@
 
 PassRefPtr<ClientRectList> Element::getClientRects()
 {
-    document()->updateLayoutIgnorePendingStylesheets();
+    document().updateLayoutIgnorePendingStylesheets();
 
     RenderBoxModelObject* renderBoxModelObject = this->renderBoxModelObject();
     if (!renderBoxModelObject)
@@ -772,13 +773,13 @@
 
     Vector<FloatQuad> quads;
     renderBoxModelObject->absoluteQuads(quads);
-    document()->adjustFloatQuadsForScrollAndAbsoluteZoom(quads, renderBoxModelObject);
+    document().adjustFloatQuadsForScrollAndAbsoluteZoom(quads, renderBoxModelObject);
     return ClientRectList::create(quads);
 }
 
 PassRefPtr<ClientRect> Element::getBoundingClientRect()
 {
-    document()->updateLayoutIgnorePendingStylesheets();
+    document().updateLayoutIgnorePendingStylesheets();
 
     Vector<FloatQuad> quads;
     if (isSVGElement() && renderer() && !renderer()->isSVGRoot()) {
@@ -800,7 +801,7 @@
     for (size_t i = 1; i < quads.size(); ++i)
         result.unite(quads[i].boundingBox());
 
-    document()->adjustFloatRectForScrollAndAbsoluteZoom(result, renderer());
+    document().adjustFloatRectForScrollAndAbsoluteZoom(result, renderer());
     return ClientRect::create(result);
 }
 
@@ -809,7 +810,7 @@
     if (!renderer())
         return IntRect();
     // FIXME: this should probably respect transforms
-    return document()->view()->contentsToScreen(renderer()->absoluteBoundingBoxRectIgnoringTransforms());
+    return document().view()->contentsToScreen(renderer()->absoluteBoundingBoxRectIgnoringTransforms());
 }
 
 const AtomicString& Element::getAttribute(const AtomicString& localName) const
@@ -868,21 +869,23 @@
         return;
     }
 
+    QualifiedName existingAttributeName = attributeItem(index)->name();
+
     if (!inSynchronizationOfLazyAttribute)
-        willModifyAttribute(name, attributeItem(index)->value(), newValue);
+        willModifyAttribute(existingAttributeName, attributeItem(index)->value(), newValue);
 
     if (newValue != attributeItem(index)->value()) {
         // If there is an Attr node hooked to this attribute, the Attr::setValue() call below
         // will write into the ElementData.
         // FIXME: Refactor this so it makes some sense.
-        if (RefPtr<Attr> attrNode = inSynchronizationOfLazyAttribute ? 0 : attrIfExists(name))
+        if (RefPtr<Attr> attrNode = inSynchronizationOfLazyAttribute ? 0 : attrIfExists(existingAttributeName))
             attrNode->setValue(newValue);
         else
             ensureUniqueElementData()->attributeItem(index)->setValue(newValue);
     }
 
     if (!inSynchronizationOfLazyAttribute)
-        didModifyAttribute(name, newValue);
+        didModifyAttribute(existingAttributeName, newValue);
 }
 
 static inline AtomicString makeIdForStyleResolution(const AtomicString& value, bool inQuirksMode)
@@ -911,9 +914,9 @@
 
     parseAttribute(name, newValue);
 
-    document()->incDOMTreeVersion();
+    document().incDOMTreeVersion();
 
-    StyleResolver* styleResolver = document()->styleResolverIfExists();
+    StyleResolver* styleResolver = document().styleResolverIfExists();
     bool testShouldInvalidateStyle = attached() && styleResolver && styleChangeType() < SubtreeStyleChange;
     bool shouldInvalidateStyle = false;
 
@@ -926,7 +929,7 @@
 
     if (isIdAttributeName(name)) {
         AtomicString oldId = elementData()->idForStyleResolution();
-        AtomicString newId = makeIdForStyleResolution(newValue, document()->inQuirksMode());
+        AtomicString newId = makeIdForStyleResolution(newValue, document().inQuirksMode());
         if (newId != oldId) {
             elementData()->setIdForStyleResolution(newId);
             shouldInvalidateStyle = testShouldInvalidateStyle && checkNeedsStyleInvalidationForIdChange(oldId, newId, styleResolver->ruleFeatureSet());
@@ -947,7 +950,7 @@
     if (shouldInvalidateStyle)
         setNeedsStyleRecalc();
 
-    if (AXObjectCache* cache = document()->existingAXObjectCache())
+    if (AXObjectCache* cache = document().existingAXObjectCache())
         cache->handleAttributeChanged(name, this);
 }
 
@@ -1028,12 +1031,12 @@
 
 void Element::classAttributeChanged(const AtomicString& newClassString)
 {
-    StyleResolver* styleResolver = document()->styleResolverIfExists();
+    StyleResolver* styleResolver = document().styleResolverIfExists();
     bool testShouldInvalidateStyle = attached() && styleResolver && styleChangeType() < SubtreeStyleChange;
     bool shouldInvalidateStyle = false;
 
     if (classStringHasClassName(newClassString)) {
-        const bool shouldFoldCase = document()->inQuirksMode();
+        const bool shouldFoldCase = document().inQuirksMode();
         const SpaceSplitString oldClasses = elementData()->classNames();
         elementData()->setClass(newClassString, shouldFoldCase);
         const SpaceSplitString& newClasses = elementData()->classNames();
@@ -1058,7 +1061,7 @@
 
     if (isIdAttributeName(name)) {
         AtomicString oldId = elementData()->idForStyleResolution();
-        AtomicString newId = makeIdForStyleResolution(newValue, document()->inQuirksMode());
+        AtomicString newId = makeIdForStyleResolution(newValue, document().inQuirksMode());
         if (newId != oldId) {
             if (!oldId.isEmpty() && featureSet.hasSelectorForId(oldId))
                 return true;
@@ -1070,7 +1073,7 @@
     if (name == HTMLNames::classAttr) {
         const AtomicString& newClassString = newValue;
         if (classStringHasClassName(newClassString)) {
-            const bool shouldFoldCase = document()->inQuirksMode();
+            const bool shouldFoldCase = document().inQuirksMode();
             const SpaceSplitString& oldClasses = elementData()->classNames();
             const SpaceSplitString newClasses(newClassString, shouldFoldCase);
             if (checkSelectorForClassChange(oldClasses, newClasses, featureSet))
@@ -1126,8 +1129,8 @@
     if (attributeVector.isEmpty())
         return;
 
-    if (document() && document()->sharedObjectPool())
-        m_elementData = document()->sharedObjectPool()->cachedShareableElementDataWithAttributes(attributeVector);
+    if (document().sharedObjectPool())
+        m_elementData = document().sharedObjectPool()->cachedShareableElementDataWithAttributes(attributeVector);
     else
         m_elementData = ShareableElementData::createWithAttributes(attributeVector);
 
@@ -1192,14 +1195,14 @@
     return KURL(parentBase, baseAttribute);
 }
 
-const AtomicString& Element::imageSourceURL() const
+const AtomicString Element::imageSourceURL() const
 {
     return getAttribute(srcAttr);
 }
 
-bool Element::rendererIsNeeded(const NodeRenderingContext& context)
+bool Element::rendererIsNeeded(const RenderStyle& style)
 {
-    return context.style()->display() != NONE;
+    return style.display() != NONE;
 }
 
 RenderObject* Element::createRenderer(RenderStyle* style)
@@ -1234,8 +1237,8 @@
     if (isUpgradedCustomElement() && inDocument())
         CustomElement::didEnterDocument(this, document());
 
-    TreeScope* scope = insertionPoint->treeScope();
-    if (scope != treeScope())
+    TreeScope& scope = insertionPoint->treeScope();
+    if (&scope != &treeScope())
         return InsertionDone;
 
     const AtomicString& idValue = getIdAttribute();
@@ -1247,7 +1250,7 @@
         updateName(nullAtom, nameValue);
 
     if (hasTagName(labelTag)) {
-        if (scope->shouldCacheLabelsByForAttribute())
+        if (scope.shouldCacheLabelsByForAttribute())
             updateLabel(scope, nullAtom, fastGetAttribute(forAttr));
     }
 
@@ -1269,17 +1272,17 @@
 
     if (Element* backdrop = pseudoElement(BACKDROP))
         backdrop->removedFrom(insertionPoint);
-    document()->removeFromTopLayer(this);
+    document().removeFromTopLayer(this);
 
     if (containsFullScreenElement())
         setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(false);
 
-    if (document()->page())
-        document()->page()->pointerLockController().elementRemoved(this);
+    if (document().page())
+        document().page()->pointerLockController().elementRemoved(this);
 
     setSavedLayerScrollOffset(IntSize());
 
-    if (insertionPoint->isInTreeScope() && treeScope() == document()) {
+    if (insertionPoint->isInTreeScope() && &treeScope() == &document()) {
         const AtomicString& idValue = getIdAttribute();
         if (!idValue.isNull())
             updateId(insertionPoint->treeScope(), idValue, nullAtom);
@@ -1289,8 +1292,8 @@
             updateName(nameValue, nullAtom);
 
         if (hasTagName(labelTag)) {
-            TreeScope* treeScope = insertionPoint->treeScope();
-            if (treeScope->shouldCacheLabelsByForAttribute())
+            TreeScope& treeScope = insertionPoint->treeScope();
+            if (treeScope.shouldCacheLabelsByForAttribute())
                 updateLabel(treeScope, fastGetAttribute(forAttr), nullAtom);
         }
     }
@@ -1298,7 +1301,7 @@
     ContainerNode::removedFrom(insertionPoint);
     if (wasInDocument) {
         if (hasPendingResources())
-            document()->accessSVGExtensions()->removeElementFromPendingResources(this);
+            document().accessSVGExtensions()->removeElementFromPendingResources(this);
 
         if (isUpgradedCustomElement())
             CustomElement::didLeaveDocument(this, insertionPoint->document());
@@ -1310,9 +1313,9 @@
 
 void Element::attach(const AttachContext& context)
 {
-    PostAttachCallbackDisabler callbackDisabler(this);
+    ASSERT(document().inStyleRecalc());
+
     StyleResolverParentPusher parentPusher(this);
-    WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates;
 
     // We've already been through detach when doing a lazyAttach, but we might
     // need to clear any state that's been added since then.
@@ -1343,23 +1346,19 @@
     if (hasRareData()) {
         ElementRareData* data = elementRareData();
         if (data->needsFocusAppearanceUpdateSoonAfterAttach()) {
-            if (isFocusable() && document()->focusedElement() == this)
-                document()->updateFocusAppearanceSoon(false /* don't restore selection */);
+            if (isFocusable() && document().focusedElement() == this)
+                document().updateFocusAppearanceSoon(false /* don't restore selection */);
             data->setNeedsFocusAppearanceUpdateSoonAfterAttach(false);
         }
     }
 
-    // FIXME: It doesn't appear safe to call didRecalculateStyleForElement when
-    // not in a Document::recalcStyle. Since we're hopefully going to always
-    // lazyAttach in the future that problem should go away.
-    if (document()->inStyleRecalc())
-        InspectorInstrumentation::didRecalculateStyleForElement(this);
+    InspectorInstrumentation::didRecalculateStyleForElement(this);
 }
 
 void Element::unregisterNamedFlowContentNode()
 {
-    if (RuntimeEnabledFeatures::cssRegionsEnabled() && inNamedFlow() && document()->renderView())
-        document()->renderView()->flowThreadController()->unregisterNamedFlowContentNode(this);
+    if (RuntimeEnabledFeatures::cssRegionsEnabled() && inNamedFlow() && document().renderView())
+        document().renderView()->flowThreadController()->unregisterNamedFlowContentNode(this);
 }
 
 void Element::detach(const AttachContext& context)
@@ -1440,12 +1439,12 @@
 
 PassRefPtr<RenderStyle> Element::originalStyleForRenderer()
 {
-    return document()->styleResolver()->styleForElement(this);
+    return document().styleResolver()->styleForElement(this);
 }
 
-bool Element::recalcStyle(StyleChange change)
+bool Element::recalcStyle(StyleRecalcChange change)
 {
-    ASSERT(document()->inStyleRecalc());
+    ASSERT(document().inStyleRecalc());
 
     if (hasCustomStyleCallbacks())
         willRecalcStyle(change);
@@ -1473,14 +1472,14 @@
     return change == Reattach;
 }
 
-Node::StyleChange Element::recalcOwnStyle(StyleChange change)
+StyleRecalcChange Element::recalcOwnStyle(StyleRecalcChange change)
 {
-    ASSERT(document()->inStyleRecalc());
+    ASSERT(document().inStyleRecalc());
 
     CSSAnimationUpdateScope cssAnimationUpdateScope(this);
     RefPtr<RenderStyle> oldStyle = renderStyle();
     RefPtr<RenderStyle> newStyle = styleForRenderer();
-    StyleChange localChange = oldStyle ? Node::diff(oldStyle.get(), newStyle.get(), document()) : Reattach;
+    StyleRecalcChange localChange = RenderStyle::compare(oldStyle.get(), newStyle.get());
 
     if (localChange == Reattach) {
         AttachContext reattachContext;
@@ -1503,9 +1502,9 @@
 
     // If "rem" units are used anywhere in the document, and if the document element's font size changes, then go ahead and force font updating
     // all the way down the tree. This is simpler than having to maintain a cache of objects (and such font size changes should be rare anyway).
-    if (document()->styleSheetCollections()->usesRemUnits() && document()->documentElement() == this && oldStyle && newStyle && oldStyle->fontSize() != newStyle->fontSize()) {
+    if (document().styleSheetCollections()->usesRemUnits() && document().documentElement() == this && oldStyle && newStyle && oldStyle->fontSize() != newStyle->fontSize()) {
         // Cached RenderStyles may depend on the re units.
-        document()->styleResolver()->invalidateMatchedPropertiesCache();
+        document().styleResolver()->invalidateMatchedPropertiesCache();
         return Force;
     }
 
@@ -1515,9 +1514,9 @@
     return max(localChange, change);
 }
 
-void Element::recalcChildStyle(StyleChange change)
+void Element::recalcChildStyle(StyleRecalcChange change)
 {
-    ASSERT(document()->inStyleRecalc());
+    ASSERT(document().inStyleRecalc());
 
     StyleResolverParentPusher parentPusher(this);
 
@@ -1564,6 +1563,8 @@
             if (shouldRecalcStyle(change, element)) {
                 parentPusher.push();
                 didReattach = element->recalcStyle(change);
+            } else if (document().styleResolver()->supportsStyleSharing(element)) {
+                document().styleResolver()->addToStyleSharingList(element);
             }
         }
 
@@ -1622,6 +1623,10 @@
     return 0;
 }
 
+void Element::didAddShadowRoot(ShadowRoot&)
+{
+}
+
 ShadowRoot* Element::userAgentShadowRoot() const
 {
     if (ElementShadow* elementShadow = shadow()) {
@@ -1670,7 +1675,7 @@
 static void checkForSiblingStyleChanges(Element* e, RenderStyle* style, bool finishedParsingCallback,
                                         Node* beforeChange, Node* afterChange, int childCountDelta)
 {
-    if (!e->attached() || e->document()->hasPendingForcedStyleRecalc() || e->styleChangeType() >= SubtreeStyleChange)
+    if (!e->attached() || e->document().hasPendingForcedStyleRecalc() || e->styleChangeType() >= SubtreeStyleChange)
         return;
 
     // :empty selector.
@@ -1762,18 +1767,12 @@
 void Element::beginParsingChildren()
 {
     clearIsParsingChildrenFinished();
-    StyleResolver* styleResolver = document()->styleResolverIfExists();
-    if (styleResolver && attached())
-        styleResolver->pushParentElement(this);
 }
 
 void Element::finishParsingChildren()
 {
-    ContainerNode::finishParsingChildren();
     setIsParsingChildrenFinished();
     checkForSiblingStyleChanges(this, renderStyle(), true, lastChild(), 0, 0);
-    if (StyleResolver* styleResolver = document()->styleResolverIfExists())
-        styleResolver->popParentElement(this);
     if (isCustomElement())
         CustomElement::didFinishParsingChildren(this);
 }
@@ -1844,7 +1843,7 @@
     setAttributeInternal(index, attrNode->qualifiedName(), attrNode->value(), NotInSynchronizationOfLazyAttribute);
 
     attrNode->attachToElement(this);
-    treeScope()->adoptIfNeeded(attrNode);
+    treeScope().adoptIfNeeded(attrNode);
     ensureAttrNodeListForElement(this)->append(attrNode);
 
     return oldAttrNode.release();
@@ -1866,7 +1865,7 @@
         return 0;
     }
 
-    ASSERT(document() == attr->document());
+    ASSERT(&document() == &attr->document());
 
     synchronizeAttribute(attr->qualifiedName());
 
@@ -2005,15 +2004,15 @@
     if (!inDocument())
         return;
 
-    Document* doc = document();
-    if (doc->focusedElement() == this)
+    Document& doc = document();
+    if (doc.focusedElement() == this)
         return;
 
     // If the stylesheets have already been loaded we can reliably check isFocusable.
     // If not, we continue and set the focused node on the focus controller below so
     // that it can be updated soon after attach.
-    if (doc->haveStylesheetsLoaded()) {
-        doc->updateLayoutIgnorePendingStylesheets();
+    if (doc.haveStylesheetsLoaded()) {
+        doc.updateLayoutIgnorePendingStylesheets();
         if (!isFocusable())
             return;
     }
@@ -2022,17 +2021,17 @@
         return;
 
     RefPtr<Node> protect;
-    if (Page* page = doc->page()) {
+    if (Page* page = doc.page()) {
         // Focus and change event handlers can cause us to lose our last ref.
         // If a focus event handler changes the focus to a different node it
         // does not make sense to continue and update appearence.
         protect = this;
-        if (!page->focusController().setFocusedElement(this, doc->frame(), direction))
+        if (!page->focusController().setFocusedElement(this, doc.frame(), direction))
             return;
     }
 
     // Setting the focused node above might have invalidated the layout due to scripts.
-    doc->updateLayoutIgnorePendingStylesheets();
+    doc.updateLayoutIgnorePendingStylesheets();
 
     if (!isFocusable()) {
         ensureElementRareData()->setNeedsFocusAppearanceUpdateSoonAfterAttach(true);
@@ -2046,20 +2045,20 @@
 void Element::updateFocusAppearance(bool /*restorePreviousSelection*/)
 {
     if (isRootEditableElement()) {
-        Frame* frame = document()->frame();
+        Frame* frame = document().frame();
         if (!frame)
             return;
 
         // When focusing an editable element in an iframe, don't reset the selection if it already contains a selection.
-        if (this == frame->selection()->rootEditableElement())
+        if (this == frame->selection().rootEditableElement())
             return;
 
         // FIXME: We should restore the previous selection if there is one.
         VisibleSelection newSelection = VisibleSelection(firstPositionInOrBeforeNode(this), DOWNSTREAM);
 
-        if (frame->selection()->shouldChangeSelection(newSelection)) {
-            frame->selection()->setSelection(newSelection);
-            frame->selection()->revealSelection();
+        if (frame->selection().shouldChangeSelection(newSelection)) {
+            frame->selection().setSelection(newSelection);
+            frame->selection().revealSelection();
         }
     } else if (renderer() && !renderer()->isWidget())
         renderer()->scrollRectToVisible(boundingBox());
@@ -2068,12 +2067,12 @@
 void Element::blur()
 {
     cancelFocusAppearanceUpdate();
-    if (treeScope()->adjustedFocusedElement() == this) {
-        Document* doc = document();
-        if (doc->page())
-            doc->page()->focusController().setFocusedElement(0, doc->frame());
+    if (treeScope().adjustedFocusedElement() == this) {
+        Document& doc = document();
+        if (doc.page())
+            doc.page()->focusController().setFocusedElement(0, doc.frame());
         else
-            doc->setFocusedElement(0);
+            doc.setFocusedElement(0);
     }
 }
 
@@ -2094,13 +2093,13 @@
 
 void Element::dispatchFocusEvent(Element* oldFocusedElement, FocusDirection)
 {
-    RefPtr<FocusEvent> event = FocusEvent::create(eventNames().focusEvent, false, false, document()->defaultView(), 0, oldFocusedElement);
+    RefPtr<FocusEvent> event = FocusEvent::create(eventNames().focusEvent, false, false, document().defaultView(), 0, oldFocusedElement);
     EventDispatcher::dispatchEvent(this, FocusEventDispatchMediator::create(event.release()));
 }
 
 void Element::dispatchBlurEvent(Element* newFocusedElement)
 {
-    RefPtr<FocusEvent> event = FocusEvent::create(eventNames().blurEvent, false, false, document()->defaultView(), 0, newFocusedElement);
+    RefPtr<FocusEvent> event = FocusEvent::create(eventNames().blurEvent, false, false, document().defaultView(), 0, newFocusedElement);
     EventDispatcher::dispatchEvent(this, BlurEventDispatchMediator::create(event.release()));
 }
 
@@ -2108,20 +2107,20 @@
 {
     ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
     ASSERT(eventType == eventNames().focusinEvent || eventType == eventNames().DOMFocusInEvent);
-    dispatchScopedEventDispatchMediator(FocusInEventDispatchMediator::create(FocusEvent::create(eventType, true, false, document()->defaultView(), 0, oldFocusedElement)));
+    dispatchScopedEventDispatchMediator(FocusInEventDispatchMediator::create(FocusEvent::create(eventType, true, false, document().defaultView(), 0, oldFocusedElement)));
 }
 
 void Element::dispatchFocusOutEvent(const AtomicString& eventType, Element* newFocusedElement)
 {
     ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
     ASSERT(eventType == eventNames().focusoutEvent || eventType == eventNames().DOMFocusOutEvent);
-    dispatchScopedEventDispatchMediator(FocusOutEventDispatchMediator::create(FocusEvent::create(eventType, true, false, document()->defaultView(), 0, newFocusedElement)));
+    dispatchScopedEventDispatchMediator(FocusOutEventDispatchMediator::create(FocusEvent::create(eventType, true, false, document().defaultView(), 0, newFocusedElement)));
 }
 
 String Element::innerText()
 {
     // We need to update layout, since plainText uses line boxes in the render tree.
-    document()->updateLayoutIgnorePendingStylesheets();
+    document().updateLayoutIgnorePendingStylesheets();
 
     if (!renderer())
         return textContent(true);
@@ -2230,7 +2229,7 @@
 
     ElementRareData* data = ensureElementRareData();
     if (!data->computedStyle())
-        data->setComputedStyle(document()->styleForElementIgnoringPendingStylesheets(this));
+        data->setComputedStyle(document().styleForElementIgnoringPendingStylesheets(this));
     return pseudoElementSpecifier ? data->computedStyle()->getCachedPseudoStyle(pseudoElementSpecifier) : data->computedStyle();
 }
 
@@ -2424,15 +2423,15 @@
 
 Locale& Element::locale() const
 {
-    return document()->getCachedLocale(computeInheritedLanguage());
+    return document().getCachedLocale(computeInheritedLanguage());
 }
 
 void Element::cancelFocusAppearanceUpdate()
 {
     if (hasRareData())
         elementRareData()->setNeedsFocusAppearanceUpdateSoonAfterAttach(false);
-    if (document()->focusedElement() == this)
-        document()->cancelFocusAppearanceUpdate();
+    if (document().focusedElement() == this)
+        document().cancelFocusAppearanceUpdate();
 }
 
 void Element::normalizeAttributes()
@@ -2445,7 +2444,7 @@
     }
 }
 
-void Element::updatePseudoElement(PseudoId pseudoId, StyleChange change)
+void Element::updatePseudoElement(PseudoId pseudoId, StyleRecalcChange change)
 {
     PseudoElement* element = pseudoElement(pseudoId);
     if (element && (needsStyleRecalc() || shouldRecalcStyle(change, element))) {
@@ -2477,7 +2476,7 @@
     ASSERT(!isPseudoElement());
     RefPtr<PseudoElement> element = PseudoElement::create(this, pseudoId);
     if (pseudoId == BACKDROP)
-        document()->addToTopLayer(element.get(), this);
+        document().addToTopLayer(element.get(), this);
     element->attach();
 
     ensureElementRareData()->setPseudoElement(pseudoId, element.release());
@@ -2502,7 +2501,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);
@@ -2532,7 +2531,7 @@
             ASSERT(isURLAttribute(*attribute));
     }
 #endif
-    return document()->completeURL(stripLeadingAndTrailingHTMLSpaces(getAttribute(name)));
+    return document().completeURL(stripLeadingAndTrailingHTMLSpaces(getAttribute(name)));
 }
 
 KURL Element::getNonEmptyURLAttribute(const QualifiedName& name) const
@@ -2546,7 +2545,7 @@
     String value = stripLeadingAndTrailingHTMLSpaces(getAttribute(name));
     if (value.isEmpty())
         return KURL();
-    return document()->completeURL(value);
+    return document().completeURL(value);
 }
 
 int Element::getIntegralAttribute(const QualifiedName& attributeName) const
@@ -2571,23 +2570,23 @@
     setAttribute(attributeName, String::number(value));
 }
 
-bool Element::childShouldCreateRenderer(const NodeRenderingContext& childContext) const
+bool Element::childShouldCreateRenderer(const Node& child) const
 {
     // Only create renderers for SVG elements whose parents are SVG elements, or for proper <svg xmlns="svgNS"> subdocuments.
-    if (childContext.node()->isSVGElement())
-        return childContext.node()->hasTagName(SVGNames::svgTag) || isSVGElement();
+    if (child.isSVGElement())
+        return child.hasTagName(SVGNames::svgTag) || isSVGElement();
 
-    return ContainerNode::childShouldCreateRenderer(childContext);
+    return ContainerNode::childShouldCreateRenderer(child);
 }
 
 void Element::webkitRequestFullscreen()
 {
-    FullscreenElementStack::from(document())->requestFullScreenForElement(this, ALLOW_KEYBOARD_INPUT, FullscreenElementStack::EnforceIFrameAllowFullScreenRequirement);
+    FullscreenElementStack::from(&document())->requestFullScreenForElement(this, ALLOW_KEYBOARD_INPUT, FullscreenElementStack::EnforceIFrameAllowFullScreenRequirement);
 }
 
 void Element::webkitRequestFullScreen(unsigned short flags)
 {
-    FullscreenElementStack::from(document())->requestFullScreenForElement(this, (flags | LEGACY_MOZILLA_REQUEST), FullscreenElementStack::EnforceIFrameAllowFullScreenRequirement);
+    FullscreenElementStack::from(&document())->requestFullScreenForElement(this, (flags | LEGACY_MOZILLA_REQUEST), FullscreenElementStack::EnforceIFrameAllowFullScreenRequirement);
 }
 
 bool Element::containsFullScreenElement() const
@@ -2604,7 +2603,7 @@
 static Element* parentCrossingFrameBoundaries(Element* element)
 {
     ASSERT(element);
-    return element->parentElement() ? element->parentElement() : element->document()->ownerElement();
+    return element->parentElement() ? element->parentElement() : element->document().ownerElement();
 }
 
 void Element::setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(bool flag)
@@ -2632,8 +2631,8 @@
 
 void Element::webkitRequestPointerLock()
 {
-    if (document()->page())
-        document()->page()->pointerLockController().requestPointerLock(this);
+    if (document().page())
+        document().page()->pointerLockController().requestPointerLock(this);
 }
 
 SpellcheckAttributeState Element::spellcheckAttributeState() const
@@ -2691,7 +2690,7 @@
 
 const AtomicString& Element::webkitRegionOverset() const
 {
-    document()->updateLayoutIgnorePendingStylesheets();
+    document().updateLayoutIgnorePendingStylesheets();
 
     DEFINE_STATIC_LOCAL(AtomicString, undefinedState, ("undefined", AtomicString::ConstructFromLiteral));
     if (!RuntimeEnabledFeatures::cssRegionsEnabled() || !renderRegion())
@@ -2720,7 +2719,7 @@
 
 Vector<RefPtr<Range> > Element::webkitGetRegionFlowRanges() const
 {
-    document()->updateLayoutIgnorePendingStylesheets();
+    document().updateLayoutIgnorePendingStylesheets();
 
     Vector<RefPtr<Range> > rangeObjects;
     if (RuntimeEnabledFeatures::cssRegionsEnabled() && renderer() && renderer()->isRenderRegion()) {
@@ -2775,21 +2774,21 @@
     updateId(treeScope(), oldId, newId);
 }
 
-inline void Element::updateId(TreeScope* scope, const AtomicString& oldId, const AtomicString& newId)
+inline void Element::updateId(TreeScope& scope, const AtomicString& oldId, const AtomicString& newId)
 {
     ASSERT(isInTreeScope());
     ASSERT(oldId != newId);
 
     if (!oldId.isEmpty())
-        scope->removeElementById(oldId, this);
+        scope.removeElementById(oldId, this);
     if (!newId.isEmpty())
-        scope->addElementById(newId, this);
+        scope.addElementById(newId, this);
 
     if (shouldRegisterAsExtraNamedItem())
         updateExtraNamedItemRegistration(oldId, newId);
 }
 
-void Element::updateLabel(TreeScope* scope, const AtomicString& oldForAttributeValue, const AtomicString& newForAttributeValue)
+void Element::updateLabel(TreeScope& scope, const AtomicString& oldForAttributeValue, const AtomicString& newForAttributeValue)
 {
     ASSERT(hasTagName(labelTag));
 
@@ -2800,9 +2799,9 @@
         return;
 
     if (!oldForAttributeValue.isEmpty())
-        scope->removeLabel(oldForAttributeValue, toHTMLLabelElement(this));
+        scope.removeLabel(oldForAttributeValue, toHTMLLabelElement(this));
     if (!newForAttributeValue.isEmpty())
-        scope->addLabel(newForAttributeValue, toHTMLLabelElement(this));
+        scope.addLabel(newForAttributeValue, toHTMLLabelElement(this));
 }
 
 static bool hasSelectorForAttribute(Document* document, const AtomicString& localName)
@@ -2817,13 +2816,13 @@
     else if (name == HTMLNames::nameAttr)
         updateName(oldValue, newValue);
     else if (name == HTMLNames::forAttr && hasTagName(labelTag)) {
-        TreeScope* scope = treeScope();
-        if (scope->shouldCacheLabelsByForAttribute())
+        TreeScope& scope = treeScope();
+        if (scope.shouldCacheLabelsByForAttribute())
             updateLabel(scope, oldValue, newValue);
     }
 
     if (oldValue != newValue) {
-        if (attached() && hasSelectorForAttribute(document(), name.localName()))
+        if (attached() && hasSelectorForAttribute(&document(), name.localName()))
            setNeedsStyleRecalc();
 
         if (isUpgradedCustomElement())
@@ -2833,27 +2832,27 @@
     if (OwnPtr<MutationObserverInterestGroup> recipients = MutationObserverInterestGroup::createForAttributesMutation(this, name))
         recipients->enqueueMutationRecord(MutationRecord::createAttributes(this, name, oldValue));
 
-    InspectorInstrumentation::willModifyDOMAttr(document(), this, oldValue, newValue);
+    InspectorInstrumentation::willModifyDOMAttr(&document(), this, oldValue, newValue);
 }
 
 void Element::didAddAttribute(const QualifiedName& name, const AtomicString& value)
 {
     attributeChanged(name, value);
-    InspectorInstrumentation::didModifyDOMAttr(document(), this, name.localName(), value);
+    InspectorInstrumentation::didModifyDOMAttr(&document(), this, name.localName(), value);
     dispatchSubtreeModifiedEvent();
 }
 
 void Element::didModifyAttribute(const QualifiedName& name, const AtomicString& value)
 {
     attributeChanged(name, value);
-    InspectorInstrumentation::didModifyDOMAttr(document(), this, name.localName(), value);
+    InspectorInstrumentation::didModifyDOMAttr(&document(), this, name.localName(), value);
     // Do not dispatch a DOMSubtreeModified event here; see bug 81141.
 }
 
 void Element::didRemoveAttribute(const QualifiedName& name)
 {
     attributeChanged(name, nullAtom);
-    InspectorInstrumentation::didRemoveDOMAttr(document(), this, name.localName());
+    InspectorInstrumentation::didRemoveDOMAttr(&document(), this, name.localName());
     dispatchSubtreeModifiedEvent();
 }
 
@@ -2864,7 +2863,7 @@
     // If the documents differ by quirks mode then they differ by case sensitivity
     // for class and id names so we need to go through the attribute change logic
     // to pick up the new casing in the ElementData.
-    if (oldDocument->inQuirksMode() != document()->inQuirksMode()) {
+    if (oldDocument->inQuirksMode() != document().inQuirksMode()) {
         if (hasID())
             setIdAttribute(getIdAttribute());
         if (hasClass())
@@ -2874,26 +2873,26 @@
 
 void Element::updateNamedItemRegistration(const AtomicString& oldName, const AtomicString& newName)
 {
-    if (!document()->isHTMLDocument())
+    if (!document().isHTMLDocument())
         return;
 
     if (!oldName.isEmpty())
-        toHTMLDocument(document())->removeNamedItem(oldName);
+        toHTMLDocument(document()).removeNamedItem(oldName);
 
     if (!newName.isEmpty())
-        toHTMLDocument(document())->addNamedItem(newName);
+        toHTMLDocument(document()).addNamedItem(newName);
 }
 
 void Element::updateExtraNamedItemRegistration(const AtomicString& oldId, const AtomicString& newId)
 {
-    if (!document()->isHTMLDocument())
+    if (!document().isHTMLDocument())
         return;
 
     if (!oldId.isEmpty())
-        toHTMLDocument(document())->removeExtraNamedItem(oldId);
+        toHTMLDocument(document()).removeExtraNamedItem(oldId);
 
     if (!newId.isEmpty())
-        toHTMLDocument(document())->addExtraNamedItem(newId);
+        toHTMLDocument(document()).addExtraNamedItem(newId);
 }
 
 PassRefPtr<HTMLCollection> Element::ensureCachedHTMLCollection(CollectionType type)
@@ -2924,8 +2923,8 @@
 
 void Element::scheduleLayerUpdate()
 {
-    if (postAttachCallbacksAreSuspended())
-        queuePostAttachCallback(scheduleLayerUpdateCallback, this);
+    if (document().inStyleRecalc())
+        PostAttachCallbacks::queueCallback(scheduleLayerUpdateCallback, this);
     else
         scheduleLayerUpdateCallback(this);
 }
@@ -2959,8 +2958,8 @@
     AttrNodeList* attrNodeList = ensureAttrNodeListForElement(this);
     RefPtr<Attr> attrNode = findAttrNodeInList(attrNodeList, name);
     if (!attrNode) {
-        attrNode = Attr::create(this, name);
-        treeScope()->adoptIfNeeded(attrNode.get());
+        attrNode = Attr::create(*this, name);
+        treeScope().adoptIfNeeded(attrNode.get());
         attrNodeList->append(attrNode);
     }
     return attrNode.release();
@@ -2997,12 +2996,12 @@
     removeAttrNodeListForElement(this);
 }
 
-void Element::willRecalcStyle(StyleChange)
+void Element::willRecalcStyle(StyleRecalcChange)
 {
     ASSERT(hasCustomStyleCallbacks());
 }
 
-void Element::didRecalcStyle(StyleChange)
+void Element::didRecalcStyle(StyleRecalcChange)
 {
     ASSERT(hasCustomStyleCallbacks());
 }
@@ -3041,7 +3040,7 @@
     // if the idForStyleResolution and the className need different casing.
     bool ownerDocumentsHaveDifferentCaseSensitivity = false;
     if (other.hasClass() || other.hasID())
-        ownerDocumentsHaveDifferentCaseSensitivity = other.document()->inQuirksMode() != document()->inQuirksMode();
+        ownerDocumentsHaveDifferentCaseSensitivity = other.document().inQuirksMode() != document().inQuirksMode();
 
     // If 'other' has a mutable ElementData, convert it to an immutable one so we can share it between both elements.
     // We can only do this if there is no CSSOM wrapper for other's inline style, and there are no presentation attributes,
@@ -3195,7 +3194,7 @@
     ASSERT(isStyledElement());
     RefPtr<StylePropertySet>& inlineStyle = ensureUniqueElementData()->m_inlineStyle;
     if (!inlineStyle)
-        inlineStyle = MutableStylePropertySet::create(strictToCSSParserMode(isHTMLElement() && !document()->inQuirksMode()));
+        inlineStyle = MutableStylePropertySet::create(strictToCSSParserMode(isHTMLElement() && !document().inQuirksMode()));
     else if (!inlineStyle->isMutable())
         inlineStyle = inlineStyle->mutableCopy();
     ASSERT(inlineStyle->isMutable());
@@ -3229,7 +3228,7 @@
         inlineStyle = CSSParser::parseInlineStyleDeclaration(newStyleString, this);
     } else {
         ASSERT(inlineStyle->isMutable());
-        static_pointer_cast<MutableStylePropertySet>(inlineStyle)->parseDeclaration(newStyleString, document()->elementSheet()->contents());
+        static_pointer_cast<MutableStylePropertySet>(inlineStyle)->parseDeclaration(newStyleString, document().elementSheet()->contents());
     }
 }
 
@@ -3237,21 +3236,21 @@
 {
     ASSERT(isStyledElement());
     WTF::OrdinalNumber startLineNumber = WTF::OrdinalNumber::beforeFirst();
-    if (document() && document()->scriptableDocumentParser() && !document()->isInDocumentWrite())
-        startLineNumber = document()->scriptableDocumentParser()->lineNumber();
+    if (document().scriptableDocumentParser() && !document().isInDocumentWrite())
+        startLineNumber = document().scriptableDocumentParser()->lineNumber();
 
     if (newStyleString.isNull()) {
         if (PropertySetCSSStyleDeclaration* cssomWrapper = inlineStyleCSSOMWrapper())
             cssomWrapper->clearParentElement();
         ensureUniqueElementData()->m_inlineStyle.clear();
-    } else if (modificationReason == ModifiedByCloning || document()->contentSecurityPolicy()->allowInlineStyle(document()->url(), startLineNumber)) {
+    } else if (modificationReason == ModifiedByCloning || document().contentSecurityPolicy()->allowInlineStyle(document().url(), startLineNumber)) {
         setInlineStyleFromString(newStyleString);
     }
 
     elementData()->m_styleAttributeIsDirty = false;
 
     setNeedsStyleRecalc(LocalStyleChange);
-    InspectorInstrumentation::didInvalidateStyleAttr(document(), this);
+    InspectorInstrumentation::didInvalidateStyleAttr(&document(), this);
 }
 
 void Element::inlineStyleChanged()
@@ -3260,7 +3259,7 @@
     setNeedsStyleRecalc(LocalStyleChange);
     ASSERT(elementData());
     elementData()->m_styleAttributeIsDirty = true;
-    InspectorInstrumentation::didInvalidateStyleAttr(document(), this);
+    InspectorInstrumentation::didInvalidateStyleAttr(&document(), this);
 }
 
 bool Element::setInlineStyleProperty(CSSPropertyID propertyID, CSSValueID identifier, bool important)
@@ -3290,7 +3289,7 @@
 bool Element::setInlineStyleProperty(CSSPropertyID propertyID, const String& value, bool important)
 {
     ASSERT(isStyledElement());
-    bool changes = ensureMutableInlineStyle()->setProperty(propertyID, value, important, document()->elementSheet()->contents());
+    bool changes = ensureMutableInlineStyle()->setProperty(propertyID, value, important, document().elementSheet()->contents());
     if (changes)
         inlineStyleChanged();
     return changes;
@@ -3320,7 +3319,7 @@
 {
     ASSERT(isStyledElement());
     if (const StylePropertySet* inlineStyle = elementData() ? elementData()->inlineStyle() : 0)
-        inlineStyle->addSubresourceStyleURLs(urls, document()->elementSheet()->contents());
+        inlineStyle->addSubresourceStyleURLs(urls, document().elementSheet()->contents());
 }
 
 static inline bool attributeNameSort(const pair<StringImpl*, AtomicString>& p1, const pair<StringImpl*, AtomicString>& p2)
@@ -3435,7 +3434,7 @@
 void Element::addPropertyToPresentationAttributeStyle(MutableStylePropertySet* style, CSSPropertyID propertyID, const String& value)
 {
     ASSERT(isStyledElement());
-    style->setProperty(propertyID, value, false, document()->elementSheet()->contents());
+    style->setProperty(propertyID, value, false, document().elementSheet()->contents());
 }
 
 void ElementData::deref()
diff --git a/Source/core/dom/Element.h b/Source/core/dom/Element.h
index 1b35d58..25c434b 100644
--- a/Source/core/dom/Element.h
+++ b/Source/core/dom/Element.h
@@ -434,8 +434,8 @@
     virtual void attach(const AttachContext& = AttachContext()) OVERRIDE;
     virtual void detach(const AttachContext& = AttachContext()) OVERRIDE;
     virtual RenderObject* createRenderer(RenderStyle*);
-    virtual bool rendererIsNeeded(const NodeRenderingContext&);
-    bool recalcStyle(StyleChange = NoChange);
+    virtual bool rendererIsNeeded(const RenderStyle&);
+    bool recalcStyle(StyleRecalcChange);
     void didAffectSelector(AffectedSelectorMask);
 
     ElementShadow* shadow() const;
@@ -444,7 +444,7 @@
     ShadowRoot* shadowRoot() const;
 
     bool hasAuthorShadowRoot() const { return shadowRoot(); }
-
+    virtual void didAddShadowRoot(ShadowRoot&);
     ShadowRoot* userAgentShadowRoot() const;
     ShadowRoot* ensureUserAgentShadowRoot();
     virtual const AtomicString& shadowPseudoId() const { return !part().isEmpty() ? part() : pseudo(); }
@@ -500,7 +500,7 @@
     KURL getURLAttribute(const QualifiedName&) const;
     KURL getNonEmptyURLAttribute(const QualifiedName&) const;
 
-    virtual const AtomicString& imageSourceURL() const;
+    virtual const AtomicString imageSourceURL() const;
     virtual String target() const { return String(); }
     virtual Image* imageContents() { return 0; }
 
@@ -554,7 +554,6 @@
 
     DOMStringMap* dataset();
 
-    static bool isMathMLElement() { return false; }
     virtual bool isMediaElement() const { return false; }
 
 #if ENABLE(INPUT_SPEECH)
@@ -595,7 +594,7 @@
 
     virtual bool shouldBeReparentedUnderRenderView(const RenderStyle*) const { return isInTopLayer(); }
 
-    virtual bool childShouldCreateRenderer(const NodeRenderingContext&) const;
+    virtual bool childShouldCreateRenderer(const Node& child) const;
     bool hasPendingResources() const;
     void setHasPendingResources();
     void clearHasPendingResources();
@@ -665,8 +664,8 @@
     virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
     virtual void removeAllEventListeners() OVERRIDE;
 
-    virtual void willRecalcStyle(StyleChange);
-    virtual void didRecalcStyle(StyleChange);
+    virtual void willRecalcStyle(StyleRecalcChange);
+    virtual void didRecalcStyle(StyleRecalcChange);
     virtual PassRefPtr<RenderStyle> customStyleForRenderer();
 
     virtual bool shouldRegisterAsNamedItem() const { return false; }
@@ -697,13 +696,13 @@
     void setInlineStyleFromString(const AtomicString&);
     MutableStylePropertySet* ensureMutableInlineStyle();
 
-    StyleChange recalcOwnStyle(StyleChange);
-    void recalcChildStyle(StyleChange);
+    StyleRecalcChange recalcOwnStyle(StyleRecalcChange);
+    void recalcChildStyle(StyleRecalcChange);
 
     void makePresentationAttributeCacheKey(PresentationAttributeCacheKey&) const;
     void rebuildPresentationAttributeStyle();
 
-    void updatePseudoElement(PseudoId, StyleChange);
+    void updatePseudoElement(PseudoId, StyleRecalcChange);
     void createPseudoElementIfNeeded(PseudoId);
 
     // FIXME: Everyone should allow author shadows.
@@ -725,9 +724,9 @@
     void synchronizeAttribute(const AtomicString& localName) const;
 
     void updateId(const AtomicString& oldId, const AtomicString& newId);
-    void updateId(TreeScope*, const AtomicString& oldId, const AtomicString& newId);
+    void updateId(TreeScope&, const AtomicString& oldId, const AtomicString& newId);
     void updateName(const AtomicString& oldName, const AtomicString& newName);
-    void updateLabel(TreeScope*, const AtomicString& oldForAttributeValue, const AtomicString& newForAttributeValue);
+    void updateLabel(TreeScope&, const AtomicString& oldForAttributeValue, const AtomicString& newForAttributeValue);
 
     void scrollByUnits(int units, ScrollGranularity);
 
@@ -801,6 +800,12 @@
     return static_cast<const Element*>(node);
 }
 
+inline const Element& toElement(const Node& node)
+{
+    ASSERT_WITH_SECURITY_IMPLICATION(node.isElementNode());
+    return static_cast<const Element&>(node);
+}
+
 // This will catch anyone doing an unnecessary cast.
 void toElement(const Element*);
 
@@ -884,12 +889,12 @@
     // with a non-null namespace, because it will return false, a false negative, if the prefixes
     // don't match but the local name and namespace both do. However, since this has been like this
     // for a while and the code paths may be hot, we'll have to measure performance if we fix it.
-    return attributeName == document()->idAttributeName();
+    return attributeName == document().idAttributeName();
 }
 
 inline const AtomicString& Element::getIdAttribute() const
 {
-    return hasID() ? fastGetAttribute(document()->idAttributeName()) : nullAtom;
+    return hasID() ? fastGetAttribute(document().idAttributeName()) : nullAtom;
 }
 
 inline const AtomicString& Element::getNameAttribute() const
@@ -908,7 +913,7 @@
 
 inline void Element::setIdAttribute(const AtomicString& value)
 {
-    setAttribute(document()->idAttributeName(), value);
+    setAttribute(document().idAttributeName(), value);
 }
 
 inline const SpaceSplitString& Element::classNames() const
@@ -981,7 +986,7 @@
     ASSERT(insertionPoint->inDocument() || isContainerNode());
     if (insertionPoint->inDocument())
         clearFlag(InDocumentFlag);
-    if (isInShadowTree() && !treeScope()->rootNode()->isShadowRoot())
+    if (isInShadowTree() && !treeScope().rootNode()->isShadowRoot())
         clearFlag(IsInShadowTreeFlag);
 }
 
diff --git a/Source/core/dom/Element.idl b/Source/core/dom/Element.idl
index 9af4c05..3de2173 100644
--- a/Source/core/dom/Element.idl
+++ b/Source/core/dom/Element.idl
@@ -36,7 +36,7 @@
     [PerWorldBindings] NodeList getElementsByTagName([Default=Undefined] optional DOMString name);
 
     [PerWorldBindings] readonly attribute NamedNodeMap     attributes;
-    boolean            hasAttributes();
+    [MeasureAs=HasAttributes] boolean hasAttributes();
 
     // DOM Level 2 Core
 
@@ -124,16 +124,16 @@
 
     // Mozilla version
     const unsigned short ALLOW_KEYBOARD_INPUT = 1;
-    [EnabledAtRuntime=fullscreen] void webkitRequestFullScreen([Default=Undefined] optional unsigned short flags);
+    [EnabledAtRuntime=Fullscreen] void webkitRequestFullScreen([Default=Undefined] optional unsigned short flags);
 
     // W3C version
-    [EnabledAtRuntime=fullscreen] void webkitRequestFullscreen();
+    [EnabledAtRuntime=Fullscreen] void webkitRequestFullscreen();
 
     void webkitRequestPointerLock();
 
     // CSS Regions API
-    [EnabledAtRuntime=cssRegions, PerWorldBindings] readonly attribute DOMString webkitRegionOverset;
-    [EnabledAtRuntime=cssRegions] sequence<Range> webkitGetRegionFlowRanges();
+    [EnabledAtRuntime=CSSRegions, PerWorldBindings] readonly attribute DOMString webkitRegionOverset;
+    [EnabledAtRuntime=CSSRegions] sequence<Range> webkitGetRegionFlowRanges();
 
     // Event handler DOM attributes
     [NotEnumerable, PerWorldBindings] attribute EventHandler onabort;
@@ -203,10 +203,10 @@
     [NotEnumerable, PerWorldBindings] attribute EventHandler onreset;
     [NotEnumerable, PerWorldBindings] attribute EventHandler onsearch;
     [NotEnumerable, PerWorldBindings] attribute EventHandler onselectstart;
-    [NotEnumerable, EnabledAtRuntime=touch, PerWorldBindings] attribute EventHandler ontouchstart;
-    [NotEnumerable, EnabledAtRuntime=touch, PerWorldBindings] attribute EventHandler ontouchmove;
-    [NotEnumerable, EnabledAtRuntime=touch, PerWorldBindings] attribute EventHandler ontouchend;
-    [NotEnumerable, EnabledAtRuntime=touch, PerWorldBindings] attribute EventHandler ontouchcancel;
+    [NotEnumerable, EnabledAtRuntime=Touch, PerWorldBindings] attribute EventHandler ontouchstart;
+    [NotEnumerable, EnabledAtRuntime=Touch, PerWorldBindings] attribute EventHandler ontouchmove;
+    [NotEnumerable, EnabledAtRuntime=Touch, PerWorldBindings] attribute EventHandler ontouchend;
+    [NotEnumerable, EnabledAtRuntime=Touch, PerWorldBindings] attribute EventHandler ontouchcancel;
     [NotEnumerable, PerWorldBindings] attribute EventHandler onwebkitfullscreenchange;
     [NotEnumerable, PerWorldBindings] attribute EventHandler onwebkitfullscreenerror;
 };
diff --git a/Source/core/dom/ElementRareData.h b/Source/core/dom/ElementRareData.h
index dcc8564..7371c7a 100644
--- a/Source/core/dom/ElementRareData.h
+++ b/Source/core/dom/ElementRareData.h
@@ -272,7 +272,7 @@
     ASSERT(!element->nextSibling());
     ASSERT(!element->previousSibling());
 
-    element->document()->removeFromTopLayer(element);
+    element->document().removeFromTopLayer(element);
     element->setParentOrShadowHostNode(0);
 }
 
diff --git a/Source/core/dom/Entity.h b/Source/core/dom/Entity.h
index f49d26a..31e042a 100644
--- a/Source/core/dom/Entity.h
+++ b/Source/core/dom/Entity.h
@@ -36,10 +36,11 @@
 private:
     Entity() : ContainerNode(0)
     {
+        ASSERT_NOT_REACHED();
         ScriptWrappable::init(this);
     }
 };
 
-} //namespace
+} // namespace WebCore
 
 #endif
diff --git a/Source/core/dom/ErrorEvent.cpp b/Source/core/dom/ErrorEvent.cpp
index ecb3d4b..dc15aec 100644
--- a/Source/core/dom/ErrorEvent.cpp
+++ b/Source/core/dom/ErrorEvent.cpp
@@ -54,16 +54,18 @@
     , m_fileName(initializer.filename)
     , m_lineNumber(initializer.lineno)
     , m_columnNumber(initializer.colno)
+    , m_world(DOMWrapperWorld::current())
 {
     ScriptWrappable::init(this);
 }
 
-ErrorEvent::ErrorEvent(const String& message, const String& fileName, unsigned lineNumber, unsigned columnNumber)
+ErrorEvent::ErrorEvent(const String& message, const String& fileName, unsigned lineNumber, unsigned columnNumber, PassRefPtr<DOMWrapperWorld> world)
     : Event(eventNames().errorEvent, false, true)
     , m_sanitizedMessage(message)
     , m_fileName(fileName)
     , m_lineNumber(lineNumber)
     , m_columnNumber(columnNumber)
+    , m_world(world)
 {
     ScriptWrappable::init(this);
 }
diff --git a/Source/core/dom/ErrorEvent.h b/Source/core/dom/ErrorEvent.h
index 583f07f..34b8a42 100644
--- a/Source/core/dom/ErrorEvent.h
+++ b/Source/core/dom/ErrorEvent.h
@@ -31,7 +31,9 @@
 #ifndef ErrorEvent_h
 #define ErrorEvent_h
 
+#include "bindings/v8/DOMWrapperWorld.h"
 #include "core/dom/Event.h"
+#include "wtf/RefPtr.h"
 #include "wtf/text/WTFString.h"
 
 namespace WebCore {
@@ -51,17 +53,17 @@
     {
         return adoptRef(new ErrorEvent);
     }
-    static PassRefPtr<ErrorEvent> create(const String& message, const String& fileName, unsigned lineNumber, unsigned columnNumber)
+    static PassRefPtr<ErrorEvent> create(const String& message, const String& fileName, unsigned lineNumber, unsigned columnNumber, PassRefPtr<DOMWrapperWorld> world)
     {
-        return adoptRef(new ErrorEvent(message, fileName, lineNumber, columnNumber));
+        return adoptRef(new ErrorEvent(message, fileName, lineNumber, columnNumber, world));
     }
     static PassRefPtr<ErrorEvent> create(const AtomicString& type, const ErrorEventInit& initializer)
     {
         return adoptRef(new ErrorEvent(type, initializer));
     }
-    static PassRefPtr<ErrorEvent> createSanitizedError()
+    static PassRefPtr<ErrorEvent> createSanitizedError(PassRefPtr<DOMWrapperWorld> world)
     {
-        return adoptRef(new ErrorEvent("Script error.", String(), 0, 0));
+        return adoptRef(new ErrorEvent("Script error.", String(), 0, 0, world));
     }
     virtual ~ErrorEvent();
 
@@ -76,11 +78,13 @@
 
     virtual const AtomicString& interfaceName() const;
 
+    PassRefPtr<DOMWrapperWorld> world() const { return m_world; }
+
     void setUnsanitizedMessage(const String&);
 
 private:
     ErrorEvent();
-    ErrorEvent(const String& message, const String& fileName, unsigned lineNumber, unsigned columnNumber);
+    ErrorEvent(const String& message, const String& fileName, unsigned lineNumber, unsigned columnNumber, PassRefPtr<DOMWrapperWorld>);
     ErrorEvent(const AtomicString&, const ErrorEventInit&);
 
     String m_unsanitizedMessage;
@@ -88,6 +92,8 @@
     String m_fileName;
     unsigned m_lineNumber;
     unsigned m_columnNumber;
+
+    RefPtr<DOMWrapperWorld> m_world;
 };
 
 } // namespace WebCore
diff --git a/Source/core/dom/Event.h b/Source/core/dom/Event.h
index f867528..56dd5f9 100644
--- a/Source/core/dom/Event.h
+++ b/Source/core/dom/Event.h
@@ -92,9 +92,9 @@
     {
         return adoptRef(new Event(type, true, false));
     }
-    static PassRefPtr<Event> create(const AtomicString& type, bool canBubble, bool cancelable)
+    static PassRefPtr<Event> createCancelableBubble(const AtomicString& type)
     {
-        return adoptRef(new Event(type, canBubble, cancelable));
+        return adoptRef(new Event(type, true, true));
     }
 
     static PassRefPtr<Event> create(const AtomicString& type, const EventInit& initializer)
diff --git a/Source/core/dom/EventContext.cpp b/Source/core/dom/EventContext.cpp
index 13bf7a8..b1d2fe8 100644
--- a/Source/core/dom/EventContext.cpp
+++ b/Source/core/dom/EventContext.cpp
@@ -133,7 +133,7 @@
 void TouchEventContext::checkReachability(TouchList* touchList) const
 {
     for (size_t i = 0; i < touchList->length(); ++i)
-        ASSERT(touchList->item(i)->target()->toNode()->treeScope()->isInclusiveAncestorOf(m_node->treeScope()));
+        ASSERT(touchList->item(i)->target()->toNode()->treeScope().isInclusiveAncestorOf(m_node->treeScope()));
 }
 #endif
 
diff --git a/Source/core/dom/EventContext.h b/Source/core/dom/EventContext.h
index 4d15ece..748fff0 100644
--- a/Source/core/dom/EventContext.h
+++ b/Source/core/dom/EventContext.h
@@ -112,7 +112,7 @@
 inline bool EventContext::isUnreachableNode(EventTarget* target)
 {
     // FIXME: Checks also for SVG elements.
-    return target && target->toNode() && !target->toNode()->isSVGElement() && !target->toNode()->treeScope()->isInclusiveAncestorOf(m_node->treeScope());
+    return target && target->toNode() && !target->toNode()->isSVGElement() && !target->toNode()->treeScope().isInclusiveAncestorOf(m_node->treeScope());
 }
 #endif
 
diff --git a/Source/core/dom/EventDispatcher.cpp b/Source/core/dom/EventDispatcher.cpp
index bf9f40b..9bcfb11 100644
--- a/Source/core/dom/EventDispatcher.cpp
+++ b/Source/core/dom/EventDispatcher.cpp
@@ -60,7 +60,7 @@
     ASSERT(node);
     ASSERT(m_event.get());
     ASSERT(!m_event->type().isNull()); // JavaScript code can create an event with an empty name, but not null.
-    m_view = node->document()->view();
+    m_view = node->document().view();
     EventRetargeter::ensureEventPath(m_node.get(), m_event.get());
 }
 
@@ -84,17 +84,17 @@
     gNodesDispatchingSimulatedClicks->add(node);
 
     if (mouseEventOptions == SendMouseOverUpDownEvents)
-        EventDispatcher(node, SimulatedMouseEvent::create(eventNames().mouseoverEvent, node->document()->defaultView(), underlyingEvent)).dispatch();
+        EventDispatcher(node, SimulatedMouseEvent::create(eventNames().mouseoverEvent, node->document().defaultView(), underlyingEvent)).dispatch();
 
     if (mouseEventOptions != SendNoEvents)
-        EventDispatcher(node, SimulatedMouseEvent::create(eventNames().mousedownEvent, node->document()->defaultView(), underlyingEvent)).dispatch();
+        EventDispatcher(node, SimulatedMouseEvent::create(eventNames().mousedownEvent, node->document().defaultView(), underlyingEvent)).dispatch();
     node->setActive(true, visualOptions == ShowPressedLook);
     if (mouseEventOptions != SendNoEvents)
-        EventDispatcher(node, SimulatedMouseEvent::create(eventNames().mouseupEvent, node->document()->defaultView(), underlyingEvent)).dispatch();
+        EventDispatcher(node, SimulatedMouseEvent::create(eventNames().mouseupEvent, node->document().defaultView(), underlyingEvent)).dispatch();
     node->setActive(false);
 
     // always send click
-    EventDispatcher(node, SimulatedMouseEvent::create(eventNames().clickEvent, node->document()->defaultView(), underlyingEvent)).dispatch();
+    EventDispatcher(node, SimulatedMouseEvent::create(eventNames().clickEvent, node->document().defaultView(), underlyingEvent)).dispatch();
 
     gNodesDispatchingSimulatedClicks->remove(node);
 }
@@ -111,7 +111,7 @@
     ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
     ASSERT(m_event->target());
     WindowEventContext windowEventContext(m_event.get(), m_node.get(), topEventContext());
-    InspectorInstrumentationCookie cookie = InspectorInstrumentation::willDispatchEvent(m_node->document(), *m_event, windowEventContext.window(), m_node.get(), m_event->eventPath());
+    InspectorInstrumentationCookie cookie = InspectorInstrumentation::willDispatchEvent(&m_node->document(), *m_event, windowEventContext.window(), m_node.get(), m_event->eventPath());
 
     void* preDispatchEventHandlerResult;
     if (dispatchEventPreProcess(preDispatchEventHandlerResult) == ContinueDispatching)
diff --git a/Source/core/dom/EventListener.h b/Source/core/dom/EventListener.h
index 33c4a34..cb4eaa0 100644
--- a/Source/core/dom/EventListener.h
+++ b/Source/core/dom/EventListener.h
@@ -39,7 +39,6 @@
             ConditionEventListenerType,
             GObjectEventListenerType,
             NativeEventListenerType,
-            SVGTRefTargetEventListenerType
         };
 
         virtual ~EventListener() { }
diff --git a/Source/core/dom/EventPathWalker.cpp b/Source/core/dom/EventPathWalker.cpp
index de1d4d0..aea6933 100644
--- a/Source/core/dom/EventPathWalker.cpp
+++ b/Source/core/dom/EventPathWalker.cpp
@@ -39,11 +39,7 @@
     , m_isVisitingInsertionPointInReprojection(false)
 {
     ASSERT(node);
-    // FIXME: It's not clear if we need this document check, but I think we do
-    // since DocType nodes from document.implementation.createDocumentType
-    // don't have a document().
-    if (Document* document = node->document())
-        document->updateDistributionForNodeIfNeeded(const_cast<Node*>(node));
+    node->document().updateDistributionForNodeIfNeeded(const_cast<Node*>(node));
 }
 
 Node* EventPathWalker::parent(const Node* node)
diff --git a/Source/core/dom/EventRetargeter.cpp b/Source/core/dom/EventRetargeter.cpp
index cf2d449..da3e829 100644
--- a/Source/core/dom/EventRetargeter.cpp
+++ b/Source/core/dom/EventRetargeter.cpp
@@ -40,14 +40,14 @@
 
 static inline bool inTheSameScope(ShadowRoot* shadowRoot, EventTarget* target)
 {
-    return target->toNode() && target->toNode()->treeScope()->rootNode() == shadowRoot;
+    return target->toNode() && target->toNode()->treeScope().rootNode() == shadowRoot;
 }
 
 static inline EventDispatchBehavior determineDispatchBehavior(Event* event, ShadowRoot* shadowRoot, EventTarget* target)
 {
     // Video-only full screen is a mode where we use the shadow DOM as an implementation
     // detail that should not be detectable by the web content.
-    if (Element* element = FullscreenElementStack::currentFullScreenElementFrom(target->toNode()->document())) {
+    if (Element* element = FullscreenElementStack::currentFullScreenElementFrom(&target->toNode()->document())) {
         // FIXME: We assume that if the full screen element is a media element that it's
         // the video-only full screen. Both here and elsewhere. But that is probably wrong.
         if (element->isMediaElement() && shadowRoot && shadowRoot->host() == element)
@@ -100,6 +100,8 @@
             eventPath.append(adoptPtr(new TouchEventContext(node, eventTargetRespectingTargetRules(node), targetStack.last())));
         else
             eventPath.append(adoptPtr(new EventContext(node, eventTargetRespectingTargetRules(node), targetStack.last())));
+        if (!inDocument)
+            break;
         if (!node->isShadowRoot())
             continue;
         if (determineDispatchBehavior(event, toShadowRoot(node), targetStack.last()) == StayInsideShadowDOM)
@@ -118,7 +120,7 @@
     TreeScope* lastScope = 0;
     size_t eventPathSize = eventPath.size();
     for (size_t i = 0; i < eventPathSize; ++i) {
-        TreeScope* currentScope = eventPath[i]->node()->treeScope();
+        TreeScope* currentScope = &eventPath[i]->node()->treeScope();
         if (currentScope == lastScope) {
             // Fast path.
             eventPath[i]->setEventPath(eventPath[i - 1]->eventPath());
@@ -128,7 +130,7 @@
         Vector<RefPtr<Node> > nodes;
         for (size_t j = 0; j < eventPathSize; ++j) {
             Node* node = eventPath[j]->node();
-            if (node->treeScope()->isInclusiveAncestorOf(currentScope))
+            if (node->treeScope().isInclusiveAncestorOf(*currentScope))
                 nodes.append(node);
         }
         eventPath[i]->adoptEventPath(nodes);
@@ -213,7 +215,7 @@
     TreeScope* lastTreeScope = 0;
     Node* adjustedNode = 0;
     for (EventPath::const_iterator iter = eventPath.begin(); iter < eventPath.end(); ++iter) {
-        TreeScope* scope = (*iter)->node()->treeScope();
+        TreeScope* scope = &(*iter)->node()->treeScope();
         if (scope == lastTreeScope) {
             // Re-use the previous adjustedRelatedTarget if treeScope does not change. Just for the performance optimization.
             adjustedNodes.append(adjustedNode);
@@ -225,7 +227,7 @@
         if (eventWithRelatedTargetDispatchBehavior == DoesNotStopAtBoundary)
             continue;
         if (targetIsIdenticalToToRelatedTarget) {
-            if (node->treeScope()->rootNode() == (*iter)->node()) {
+            if (node->treeScope().rootNode() == (*iter)->node()) {
                 eventPath.shrink(iter + 1 - eventPath.begin());
                 break;
             }
@@ -248,7 +250,7 @@
             relatedNodeStack.append(node);
         else if (walker.isVisitingInsertionPointInReprojection())
             relatedNodeStack.append(relatedNodeStack.last());
-        TreeScope* scope = node->treeScope();
+        TreeScope* scope = &node->treeScope();
         // Skips adding a node to the map if treeScope does not change. Just for the performance optimization.
         if (scope != lastTreeScope)
             relatedNodeMap.add(scope, relatedNodeStack.last());
diff --git a/Source/core/dom/EventRetargeter.h b/Source/core/dom/EventRetargeter.h
index c76c0be..ea5b36e 100644
--- a/Source/core/dom/EventRetargeter.h
+++ b/Source/core/dom/EventRetargeter.h
@@ -81,7 +81,7 @@
 
     // Spec: The event handling for the non-exposed tree works as if the referenced element had been textually included
     // as a deeply cloned child of the 'use' element, except that events are dispatched to the SVGElementInstance objects.
-    Node* rootNode = referenceNode->treeScope()->rootNode();
+    Node* rootNode = referenceNode->treeScope().rootNode();
     Element* shadowHostElement = rootNode->isShadowRoot() ? toShadowRoot(rootNode)->host() : 0;
     // At this time, SVG nodes are not supported in non-<use> shadow trees.
     if (!shadowHostElement || !shadowHostElement->hasTagName(SVGNames::useTag))
diff --git a/Source/core/dom/EventTarget.cpp b/Source/core/dom/EventTarget.cpp
index 991f785..5745d7f 100644
--- a/Source/core/dom/EventTarget.cpp
+++ b/Source/core/dom/EventTarget.cpp
@@ -313,6 +313,9 @@
             break;
 
         ScriptExecutionContext* context = scriptExecutionContext();
+        if (!context)
+            break;
+
         InspectorInstrumentationCookie cookie = InspectorInstrumentation::willHandleEvent(context, event);
         // To match Mozilla, the AT_TARGET phase fires both capturing and bubbling
         // event listeners, even though that violates some versions of the DOM spec.
diff --git a/Source/core/dom/EventTarget.h b/Source/core/dom/EventTarget.h
index b63c8fb..3a5dc0a 100644
--- a/Source/core/dom/EventTarget.h
+++ b/Source/core/dom/EventTarget.h
@@ -161,8 +161,8 @@
         void type::setOn##attribute(PassRefPtr<EventListener> listener, DOMWrapperWorld* isolatedWorld) { setAttributeEventListener(eventNames().attribute##Event, listener, isolatedWorld); } \
 
     #define DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(attribute) \
-        EventListener* on##attribute(DOMWrapperWorld* isolatedWorld) { return document()->getWindowAttributeEventListener(eventNames().attribute##Event, isolatedWorld); } \
-        void setOn##attribute(PassRefPtr<EventListener> listener, DOMWrapperWorld* isolatedWorld) { document()->setWindowAttributeEventListener(eventNames().attribute##Event, listener, isolatedWorld); } \
+        EventListener* on##attribute(DOMWrapperWorld* isolatedWorld) { return document().getWindowAttributeEventListener(eventNames().attribute##Event, isolatedWorld); } \
+        void setOn##attribute(PassRefPtr<EventListener> listener, DOMWrapperWorld* isolatedWorld) { document().setWindowAttributeEventListener(eventNames().attribute##Event, listener, isolatedWorld); } \
 
     #define DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(attribute, eventName) \
         EventListener* on##attribute(DOMWrapperWorld* isolatedWorld) { return getAttributeEventListener(eventNames().eventName##Event, isolatedWorld); } \
diff --git a/Source/core/dom/EventTargetFactory.in b/Source/core/dom/EventTargetFactory.in
index abe0c16..5227c79 100644
--- a/Source/core/dom/EventTargetFactory.in
+++ b/Source/core/dom/EventTargetFactory.in
@@ -36,7 +36,7 @@
 modules/mediastream/RTCDTMFSender
 modules/mediastream/RTCDataChannel
 modules/mediastream/RTCPeerConnection
-modules/notifications/Notification Conditional=NOTIFICATIONS
+modules/notifications/Notification
 modules/speech/SpeechRecognition
 modules/speech/SpeechSynthesisUtterance
 modules/webaudio/AudioContext Conditional=WEB_AUDIO
diff --git a/Source/core/dom/FullscreenElementStack.cpp b/Source/core/dom/FullscreenElementStack.cpp
index 43ee0a7..ae70534 100644
--- a/Source/core/dom/FullscreenElementStack.cpp
+++ b/Source/core/dom/FullscreenElementStack.cpp
@@ -52,7 +52,7 @@
     do {
         if (!(owner->hasAttribute(attribute) || owner->hasAttribute(prefixedAttribute)))
             return false;
-    } while ((owner = owner->document()->ownerElement()));
+    } while ((owner = owner->document().ownerElement()));
     return true;
 }
 
@@ -134,7 +134,7 @@
 bool FullscreenElementStack::fullScreenIsAllowedForElement(Element* element) const
 {
     ASSERT(element);
-    return isAttributeOnAllOwners(allowfullscreenAttr, webkitallowfullscreenAttr, element->document()->ownerElement());
+    return isAttributeOnAllOwners(allowfullscreenAttr, webkitallowfullscreenAttr, element->document().ownerElement());
 }
 
 void FullscreenElementStack::requestFullScreenForElement(Element* element, unsigned short flags, FullScreenCheckType checkType)
@@ -199,7 +199,7 @@
 
         do {
             docs.prepend(currentDoc);
-            currentDoc = currentDoc->ownerElement() ? currentDoc->ownerElement()->document() : 0;
+            currentDoc = currentDoc->ownerElement() ? &currentDoc->ownerElement()->document() : 0;
         } while (currentDoc);
 
         // 4. For each document in docs, run these substeps:
@@ -304,7 +304,7 @@
         //    If doc's fullscreen element stack is non-empty and the element now at the top is either
         //    not in a document or its node document is not doc, repeat this substep.
         newTop = fullscreenElementFrom(currentDoc);
-        if (newTop && (!newTop->inDocument() || newTop->document() != currentDoc))
+        if (newTop && (!newTop->inDocument() || &newTop->document() != currentDoc))
             continue;
 
         // 2. Queue a task to fire an event named fullscreenchange with its bubbles attribute set to true
@@ -314,7 +314,7 @@
         // 3. If doc's fullscreen element stack is empty and doc's browsing context has a browsing context
         // container, set doc to that browsing context container's node document.
         if (!newTop && currentDoc->ownerElement()) {
-            currentDoc = currentDoc->ownerElement()->document();
+            currentDoc = &currentDoc->ownerElement()->document();
             continue;
         }
 
@@ -388,7 +388,7 @@
 
     m_fullScreenElement->setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(true);
 
-    document()->recalcStyle(Node::Force);
+    document()->recalcStyle(Force);
 }
 
 void FullscreenElementStack::webkitDidEnterFullScreenForElement(Element*)
diff --git a/Source/core/dom/FullscreenElementStack.h b/Source/core/dom/FullscreenElementStack.h
index fcf9996..8e5e986 100644
--- a/Source/core/dom/FullscreenElementStack.h
+++ b/Source/core/dom/FullscreenElementStack.h
@@ -118,7 +118,7 @@
 
 inline bool FullscreenElementStack::isActiveFullScreenElement(const Element* element)
 {
-    FullscreenElementStack* controller = fromIfExists(element->document());
+    FullscreenElementStack* controller = fromIfExists(&element->document());
     if (!controller)
         return false;
     return controller->webkitIsFullScreen() && controller->webkitCurrentFullScreenElement() == element;
diff --git a/Source/core/dom/LiveNodeList.cpp b/Source/core/dom/LiveNodeList.cpp
index 33f04cd..abb485e 100644
--- a/Source/core/dom/LiveNodeList.cpp
+++ b/Source/core/dom/LiveNodeList.cpp
@@ -32,7 +32,7 @@
 Node* LiveNodeListBase::rootNode() const
 {
     if (isRootedAtDocument() && m_ownerNode->inDocument())
-        return m_ownerNode->document();
+        return &m_ownerNode->document();
     return m_ownerNode.get();
 }
 
@@ -73,7 +73,7 @@
     Node* rootNode = this->rootNode();
 
     if (rootNode->inDocument()) {
-        Element* element = rootNode->treeScope()->getElementById(elementId);
+        Element* element = rootNode->treeScope().getElementById(elementId);
         if (element && nodeMatches(element) && element->isDescendantOf(rootNode))
             return element;
         if (!element)
diff --git a/Source/core/dom/LiveNodeList.h b/Source/core/dom/LiveNodeList.h
index 06e6d8f..97dd515 100644
--- a/Source/core/dom/LiveNodeList.h
+++ b/Source/core/dom/LiveNodeList.h
@@ -68,13 +68,13 @@
         ASSERT(!m_overridesItemAfter || !isNodeList(collectionType));
 
         if (collectionType != ChildNodeListType)
-            document()->registerNodeList(this);
+            document().registerNodeList(this);
     }
 
     virtual ~LiveNodeListBase()
     {
         if (type() != ChildNodeListType)
-            document()->unregisterNodeList(this);
+            document().unregisterNodeList(this);
     }
 
     // DOM API
@@ -99,7 +99,7 @@
     static bool shouldInvalidateTypeOnAttributeChange(NodeListInvalidationType, const QualifiedName&);
 
 protected:
-    Document* document() const { return m_ownerNode->document(); }
+    Document& document() const { return m_ownerNode->document(); }
     Node* rootNode() const;
     ContainerNode* rootContainerNode() const;
     bool overridesItemAfter() const { return m_overridesItemAfter; }
diff --git a/Source/core/dom/MouseEvent.cpp b/Source/core/dom/MouseEvent.cpp
index 2d5f328..6ae78a2 100644
--- a/Source/core/dom/MouseEvent.cpp
+++ b/Source/core/dom/MouseEvent.cpp
@@ -27,9 +27,6 @@
 #include "core/dom/EventDispatcher.h"
 #include "core/dom/EventNames.h"
 #include "core/dom/EventRetargeter.h"
-#include "core/html/HTMLIFrameElement.h"
-#include "core/page/Frame.h"
-#include "core/page/FrameView.h"
 #include "core/platform/PlatformMouseEvent.h"
 
 namespace WebCore {
@@ -58,7 +55,7 @@
     ASSERT(event.type() == PlatformEvent::MouseMoved || event.button() != NoButton);
 
     bool isMouseEnterOrLeave = eventType == eventNames().mouseenterEvent || eventType == eventNames().mouseleaveEvent;
-    bool isCancelable = eventType != eventNames().mousemoveEvent && !isMouseEnterOrLeave;
+    bool isCancelable = !isMouseEnterOrLeave;
     bool isBubbling = !isMouseEnterOrLeave;
 
     return MouseEvent::create(eventType, isBubbling, isCancelable, view,
diff --git a/Source/core/dom/MouseRelatedEvent.cpp b/Source/core/dom/MouseRelatedEvent.cpp
index 14a40aa..147ba2d 100644
--- a/Source/core/dom/MouseRelatedEvent.cpp
+++ b/Source/core/dom/MouseRelatedEvent.cpp
@@ -141,7 +141,7 @@
     m_offsetLocation = m_pageLocation;
 
     // Must have an updated render tree for this math to work correctly.
-    targetNode->document()->updateLayoutIgnorePendingStylesheets();
+    targetNode->document().updateLayoutIgnorePendingStylesheets();
 
     // Adjust offsetLocation to be relative to the target's position.
     if (RenderObject* r = targetNode->renderer()) {
diff --git a/Source/core/dom/MutationObserverInterestGroup.h b/Source/core/dom/MutationObserverInterestGroup.h
index 2de1070..4950f31 100644
--- a/Source/core/dom/MutationObserverInterestGroup.h
+++ b/Source/core/dom/MutationObserverInterestGroup.h
@@ -44,7 +44,7 @@
 public:
     static PassOwnPtr<MutationObserverInterestGroup> createForChildListMutation(Node* target)
     {
-        if (!target->document()->hasMutationObserversOfType(MutationObserver::ChildList))
+        if (!target->document().hasMutationObserversOfType(MutationObserver::ChildList))
             return nullptr;
 
         MutationRecordDeliveryOptions oldValueFlag = 0;
@@ -53,7 +53,7 @@
 
     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);
@@ -61,7 +61,7 @@
 
     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);
diff --git a/Source/core/dom/NamedFlow.cpp b/Source/core/dom/NamedFlow.cpp
index 00519a1..013b0eb 100644
--- a/Source/core/dom/NamedFlow.cpp
+++ b/Source/core/dom/NamedFlow.cpp
@@ -100,11 +100,19 @@
     const RenderRegionList& regionList = m_parentFlowThread->renderRegionList();
     if (regionList.isEmpty())
         return -1;
+
+    int countNonPseudoRegions = -1;
     RenderRegionList::const_iterator iter = regionList.begin();
     for (int index = 0; iter != regionList.end(); ++index, ++iter) {
         const RenderRegion* renderRegion = *iter;
+        // FIXME: Pseudo-elements are not included in the list.
+        // They will be included when we will properly support the Region interface
+        // http://dev.w3.org/csswg/css-regions/#the-region-interface
+        if (renderRegion->isPseudoElement())
+            continue;
+        countNonPseudoRegions++;
         if (renderRegion->regionOversetState() == RegionEmpty)
-            return index;
+            return countNonPseudoRegions;
     }
     return -1;
 }
@@ -128,8 +136,9 @@
         const RenderRegionList& regionList = m_parentFlowThread->renderRegionList();
         for (RenderRegionList::const_iterator iter = regionList.begin(); iter != regionList.end(); ++iter) {
             const RenderRegion* renderRegion = *iter;
-            // FIXME: Pseudo-elements are not included in the list.
-            if (!renderRegion->node())
+            // They will be included when we will properly support the Region interface
+            // http://dev.w3.org/csswg/css-regions/#the-region-interface
+            if (renderRegion->isPseudoElement())
                 continue;
             if (m_parentFlowThread->objectInFlowRegion(contentNode->renderer(), renderRegion))
                 regionNodes.append(renderRegion->node());
@@ -154,8 +163,9 @@
     const RenderRegionList& regionList = m_parentFlowThread->renderRegionList();
     for (RenderRegionList::const_iterator iter = regionList.begin(); iter != regionList.end(); ++iter) {
         const RenderRegion* renderRegion = *iter;
-        // FIXME: Pseudo-elements are not included in the list.
-        if (!renderRegion->node())
+        // They will be included when we will properly support the Region interface
+        // http://dev.w3.org/csswg/css-regions/#the-region-interface
+        if (renderRegion->isPseudoElement())
             continue;
         regionNodes.append(renderRegion->node());
     }
diff --git a/Source/core/dom/NamedNodeMap.cpp b/Source/core/dom/NamedNodeMap.cpp
index b24e12d..1e2d022 100644
--- a/Source/core/dom/NamedNodeMap.cpp
+++ b/Source/core/dom/NamedNodeMap.cpp
@@ -37,7 +37,7 @@
 
 static inline bool shouldIgnoreAttributeCase(const Element* e)
 {
-    return e && e->document()->isHTMLDocument() && e->isHTMLElement();
+    return e && e->document().isHTMLDocument() && e->isHTMLElement();
 }
 
 void NamedNodeMap::ref()
diff --git a/Source/core/dom/Node.cpp b/Source/core/dom/Node.cpp
index 75e593c..0e3d2cb 100644
--- a/Source/core/dom/Node.cpp
+++ b/Source/core/dom/Node.cpp
@@ -66,6 +66,7 @@
 #include "core/dom/TreeScopeAdopter.h"
 #include "core/dom/UIEvent.h"
 #include "core/dom/UserActionElementSet.h"
+#include "core/dom/WheelController.h"
 #include "core/dom/WheelEvent.h"
 #include "core/dom/shadow/ElementShadow.h"
 #include "core/dom/shadow/InsertionPoint.h"
@@ -264,68 +265,6 @@
 
 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, nodeCounter, ("WebCoreNode"));
 
-Node::StyleChange Node::diff(const RenderStyle* s1, const RenderStyle* s2, Document* doc)
-{
-    StyleChange ch = NoInherit;
-    EDisplay display1 = s1 ? s1->display() : NONE;
-    bool fl1 = s1 && s1->hasPseudoStyle(FIRST_LETTER);
-    EDisplay display2 = s2 ? s2->display() : NONE;
-    bool fl2 = s2 && s2->hasPseudoStyle(FIRST_LETTER);
-
-    // We just detach if a renderer acquires or loses a column-span, since spanning elements
-    // typically won't contain much content.
-    bool colSpan1 = s1 && s1->columnSpan();
-    bool colSpan2 = s2 && s2->columnSpan();
-
-    bool specifiesColumns1 = s1 && (!s1->hasAutoColumnCount() || !s1->hasAutoColumnWidth());
-    bool specifiesColumns2 = s2 && (!s2->hasAutoColumnCount() || !s2->hasAutoColumnWidth());
-
-    if (display1 != display2 || fl1 != fl2 || colSpan1 != colSpan2
-        || (specifiesColumns1 != specifiesColumns2 && doc->settings()->regionBasedColumnsEnabled())
-        || (s1 && s2 && !s1->contentDataEquivalent(s2)))
-        ch = Reattach;
-    else if (!s1 || !s2)
-        ch = Inherit;
-    else if (*s1 == *s2)
-        ch = NoChange;
-    else if (s1->inheritedNotEqual(s2))
-        ch = Inherit;
-    else if (s1->hasExplicitlyInheritedProperties() || s2->hasExplicitlyInheritedProperties())
-        ch = Inherit;
-
-    // If the pseudoStyles have changed, we want any StyleChange that is not NoChange
-    // because setStyle will do the right thing with anything else.
-    if (ch == NoChange && s1->hasAnyPublicPseudoStyles()) {
-        for (PseudoId pseudoId = FIRST_PUBLIC_PSEUDOID; ch == NoChange && pseudoId < FIRST_INTERNAL_PSEUDOID; pseudoId = static_cast<PseudoId>(pseudoId + 1)) {
-            if (s1->hasPseudoStyle(pseudoId)) {
-                RenderStyle* ps2 = s2->getCachedPseudoStyle(pseudoId);
-                if (!ps2)
-                    ch = NoInherit;
-                else {
-                    RenderStyle* ps1 = s1->getCachedPseudoStyle(pseudoId);
-                    ch = ps1 && *ps1 == *ps2 ? NoChange : NoInherit;
-                }
-            }
-        }
-    }
-
-    // When text-combine property has been changed, we need to prepare a separate renderer object.
-    // When text-combine is on, we use RenderCombineText, otherwise RenderText.
-    // https://bugs.webkit.org/show_bug.cgi?id=55069
-    if ((s1 && s2) && (s1->hasTextCombine() != s2->hasTextCombine()))
-        ch = Reattach;
-
-    // We need to reattach the node, so that it is moved to the correct RenderFlowThread.
-    if ((s1 && s2) && (s1->flowThread() != s2->flowThread()))
-        ch = Reattach;
-
-    // When the region thread has changed, we need to prepare a separate render region object.
-    if ((s1 && s2) && (s1->regionThread() != s2->regionThread()))
-        ch = Reattach;
-
-    return ch;
-}
-
 void Node::trackForDebugging()
 {
 #ifndef NDEBUG
@@ -350,8 +289,7 @@
     if (hasRareData())
         clearRareData();
 
-    if (renderer())
-        detach();
+    RELEASE_ASSERT(!renderer());
 
     if (!isContainerNode()) {
         if (Document* document = documentInternal())
@@ -600,7 +538,7 @@
             // Both non-empty text nodes. Merge them.
             unsigned offset = text->length();
             text->appendData(nextText->data());
-            document()->textNodesMerged(nextText.get(), offset);
+            document().textNodesMerged(nextText.get(), offset);
             nextText->remove(IGNORE_EXCEPTION);
         }
 
@@ -634,13 +572,13 @@
 
 bool Node::isContentEditable(UserSelectAllTreatment treatment)
 {
-    document()->updateStyleIfNeeded();
+    document().updateStyleIfNeeded();
     return rendererIsEditable(Editable, treatment);
 }
 
 bool Node::isContentRichlyEditable()
 {
-    document()->updateStyleIfNeeded();
+    document().updateStyleIfNeeded();
     return rendererIsEditable(RichlyEditable, UserSelectAllIsAlwaysNonEditable);
 }
 
@@ -684,14 +622,11 @@
     if (editableLevel == RichlyEditable)
         return false;
 
-    ASSERT(document());
     ASSERT(AXObjectCache::accessibilityEnabled());
-    ASSERT(document()->existingAXObjectCache());
+    ASSERT(document().existingAXObjectCache());
 
-    if (document()) {
-        if (AXObjectCache* cache = document()->existingAXObjectCache())
-            return cache->rootAXEditableElement(this);
-    }
+    if (AXObjectCache* cache = document().existingAXObjectCache())
+        return cache->rootAXEditableElement(this);
 
     return false;
 }
@@ -794,8 +729,8 @@
 {
     for (Node* node = this; node && !node->childNeedsDistributionRecalc(); node = node->parentOrShadowHostNode())
         node->setChildNeedsDistributionRecalc();
-    if (document()->childNeedsDistributionRecalc())
-        document()->scheduleStyleRecalc();
+    if (document().childNeedsDistributionRecalc())
+        document().scheduleStyleRecalc();
 }
 
 inline void Node::setStyleChange(StyleChangeType changeType)
@@ -808,8 +743,8 @@
     for (ContainerNode* p = parentOrShadowHostNode(); p && !p->childNeedsStyleRecalc(); p = p->parentOrShadowHostNode())
         p->setChildNeedsStyleRecalc();
 
-    if (document()->needsStyleRecalc() || document()->childNeedsStyleRecalc())
-        document()->scheduleStyleRecalc();
+    if (document().needsStyleRecalc() || document().childNeedsStyleRecalc())
+        document().scheduleStyleRecalc();
 }
 
 void Node::refEventTarget()
@@ -839,18 +774,16 @@
         markAncestorsWithChildNeedsStyleRecalc();
 }
 
-void Node::lazyAttach(ShouldSetAttached shouldSetAttached)
+void Node::lazyAttach()
 {
     markAncestorsWithChildNeedsStyleRecalc();
     for (Node* node = this; node; node = NodeTraversal::next(node, this)) {
+        node->setAttached();
         node->setStyleChange(LazyAttachStyleChange);
         if (node->isContainerNode())
             node->setChildNeedsStyleRecalc();
-        // FIXME: This flag is only used by HTMLFrameElementBase and doesn't look needed.
-        if (shouldSetAttached == SetAttached)
-            node->setAttached();
         for (ShadowRoot* root = node->youngestShadowRoot(); root; root = root->olderShadowRoot())
-            root->lazyAttach(shouldSetAttached);
+            root->lazyAttach();
     }
 }
 
@@ -867,10 +800,10 @@
 
 bool Node::isInert() const
 {
-    const HTMLDialogElement* dialog = document()->activeModalDialog();
+    const HTMLDialogElement* dialog = document().activeModalDialog();
     if (dialog && !containsIncludingShadowDOM(dialog) && !dialog->containsIncludingShadowDOM(this))
         return true;
-    return document()->ownerElement() && document()->ownerElement()->isInert();
+    return document().ownerElement() && document().ownerElement()->isInert();
 }
 
 unsigned Node::nodeIndex() const
@@ -927,10 +860,10 @@
     if (attrName && !attributeOwnerElement)
         return;
 
-    if (!document()->shouldInvalidateNodeListCaches(attrName))
+    if (!document().shouldInvalidateNodeListCaches(attrName))
         return;
 
-    document()->invalidateNodeListCaches(attrName);
+    document().invalidateNodeListCaches(attrName);
 
     for (Node* node = this; node; node = node->parentNode()) {
         if (!node->hasRareData())
@@ -977,7 +910,7 @@
     // Return true if other is an ancestor of this, otherwise false
     if (!other || !other->hasChildNodes() || inDocument() != other->inDocument())
         return false;
-    if (other->treeScope() != treeScope())
+    if (&other->treeScope() != &treeScope())
         return false;
     if (other->isTreeScope())
         return !isTreeScope();
@@ -1003,7 +936,7 @@
     if (this == node)
         return true;
 
-    if (document() != node->document())
+    if (&document() != &node->document())
         return false;
 
     if (inDocument() != node->inDocument())
@@ -1015,7 +948,7 @@
         return false;
 
     for (; node; node = node->shadowHost()) {
-        if (treeScope() == node->treeScope())
+        if (&treeScope() == &node->treeScope())
             return contains(node);
     }
 
@@ -1027,7 +960,7 @@
     while (node) {
         if (node == this)
             return true;
-        if (node->isDocumentFragment() && static_cast<const DocumentFragment*>(node)->isTemplateContent())
+        if (node->isDocumentFragment() && toDocumentFragment(node)->isTemplateContent())
             node = static_cast<const TemplateContentDocumentFragment*>(node)->host();
         else
             node = node->parentOrShadowHostNode();
@@ -1053,9 +986,6 @@
             continue;
         }
         // Handle normal reattaches from style recalc (ex. display type changes)
-        // or descendants of lazy attached nodes that got actually attached, for example,
-        // by innerHTML or editing.
-        // FIXME: innerHTML and editing should also lazyAttach.
         if (node->attached())
             node->detach(context);
         node = NodeTraversal::nextSkippingChildren(node, root);
@@ -1064,8 +994,6 @@
 
 void Node::reattach(const AttachContext& context)
 {
-    // FIXME: Text::updateTextRenderer calls reattach outside a style recalc.
-    ASSERT(document()->inStyleRecalc() || isTextNode());
     AttachContext reattachContext(context);
     reattachContext.performingReattach = true;
 
@@ -1075,30 +1003,10 @@
 
 void Node::attach(const AttachContext&)
 {
+    ASSERT(document().inStyleRecalc() || isDocumentNode());
     ASSERT(!attached());
     ASSERT(!renderer() || (renderer()->style() && (renderer()->parent() || renderer()->isRenderView())));
 
-    // If this node got a renderer it may be the previousRenderer() of sibling text nodes and thus affect the
-    // result of Text::textRendererIsNeeded() for those nodes.
-    // FIXME: This loop is no longer required once we lazy attach all the time.
-    if (renderer() && !document()->inStyleRecalc()) {
-        for (Node* next = nextSibling(); next; next = next->nextSibling()) {
-            if (next->renderer())
-                break;
-            if (!next->attached())
-                break; // Assume this means none of the following siblings are attached.
-            if (!next->isTextNode())
-                continue;
-            ASSERT(!next->renderer());
-            toText(next)->reattach();
-            // If we again decided not to create a renderer for next, we can bail out the loop,
-            // because it won't affect the result of Text::textRendererIsNeeded() for the rest
-            // of sibling nodes.
-            if (!next->renderer())
-                break;
-        }
-    }
-
     setAttached();
     clearNeedsStyleRecalc();
 
@@ -1131,13 +1039,13 @@
     // Do not remove the element's hovered and active status
     // if performing a reattach.
     if (!context.performingReattach) {
-        Document* doc = document();
+        Document& doc = document();
         if (isUserActionElement()) {
             if (hovered())
-                doc->hoveredNodeDetached(this);
+                doc.hoveredNodeDetached(this);
             if (inActiveChain())
-                doc->activeChainNodeDetached(this);
-            doc->userActionElements().didDetach(this);
+                doc.activeChainNodeDetached(this);
+            doc.userActionElements().didDetach(this);
         }
     }
 
@@ -1231,7 +1139,7 @@
 
 bool Node::isRegisteredWithNamedFlow() const
 {
-    return document()->renderView()->flowThreadController()->isContentNodeRegisteredWithAnyNamedFlow(this);
+    return document().renderView()->flowThreadController()->isContentNodeRegisteredWithAnyNamedFlow(this);
 }
 
 Element* Node::shadowHost() const
@@ -1251,7 +1159,7 @@
 
 ShadowRoot* Node::containingShadowRoot() const
 {
-    Node* root = treeScope()->rootNode();
+    Node* root = treeScope().rootNode();
     return root && root->isShadowRoot() ? toShadowRoot(root) : 0;
 }
 
@@ -1293,7 +1201,7 @@
 
 bool Node::isBlockFlowElement() const
 {
-    return isElementNode() && renderer() && renderer()->isBlockFlow();
+    return isElementNode() && renderer() && renderer()->isRenderBlockFlow();
 }
 
 Element *Node::enclosingBlockFlowElement() const
@@ -1321,7 +1229,7 @@
 Element* Node::rootEditableElement(EditableType editableType) const
 {
     if (editableType == HasEditableAXRole) {
-        if (AXObjectCache* cache = document()->existingAXObjectCache())
+        if (AXObjectCache* cache = document().existingAXObjectCache())
             return const_cast<Element*>(cache->rootAXEditableElement(this));
     }
 
@@ -1352,7 +1260,7 @@
     if (localName.isNull())
         return 0;
 
-    if (document()->isHTMLDocument())
+    if (document().isHTMLDocument())
         return ensureRareData()->ensureNodeLists()->addCacheWithAtomicName<HTMLTagNodeList>(this, HTMLTagNodeListType, localName);
     return ensureRareData()->ensureNodeLists()->addCacheWithAtomicName<TagNodeList>(this, TagNodeListType, localName);
 }
@@ -1391,7 +1299,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);
@@ -1404,15 +1312,15 @@
         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);
 }
 
-Document *Node::ownerDocument() const
+Document* Node::ownerDocument() const
 {
-    Document *doc = document();
+    Document* doc = &document();
     return doc == this ? 0 : doc;
 }
 
@@ -1463,8 +1371,8 @@
         return false;
 
     if (nodeType == DOCUMENT_TYPE_NODE) {
-        const DocumentType* documentTypeThis = static_cast<const DocumentType*>(this);
-        const DocumentType* documentTypeOther = static_cast<const DocumentType*>(other);
+        const DocumentType* documentTypeThis = toDocumentType(this);
+        const DocumentType* documentTypeOther = toDocumentType(other);
 
         if (documentTypeThis->publicId() != documentTypeOther->publicId())
             return false;
@@ -1653,12 +1561,12 @@
     case Node::CDATA_SECTION_NODE:
     case Node::COMMENT_NODE:
         isNullString = false;
-        content.append(static_cast<const CharacterData*>(node)->data());
+        content.append(toCharacterData(node)->data());
         break;
 
     case Node::PROCESSING_INSTRUCTION_NODE:
         isNullString = false;
-        content.append(static_cast<const ProcessingInstruction*>(node)->data());
+        content.append(toProcessingInstruction(node)->data());
         break;
 
     case Node::ELEMENT_NODE:
@@ -1712,7 +1620,7 @@
             ChildListMutationScope mutation(this);
             container->removeChildren();
             if (!text.isEmpty())
-                container->appendChild(document()->createTextNode(text), es);
+                container->appendChild(document().createTextNode(text), es);
             return;
         }
         case DOCUMENT_NODE:
@@ -1799,7 +1707,7 @@
     // If one node is in the document and the other is not, we must be disconnected.
     // If the nodes have different owning documents, they must be disconnected.  Note that we avoid
     // comparing Attr nodes here, since they return false from inDocument() all the time (which seems like a bug).
-    if (start1->inDocument() != start2->inDocument() || (treatment == TreatShadowTreesAsDisconnected && start1->treeScope() != start2->treeScope())) {
+    if (start1->inDocument() != start2->inDocument() || (treatment == TreatShadowTreesAsDisconnected && &start1->treeScope() != &start2->treeScope())) {
         unsigned short direction = (this > otherNode) ? DOCUMENT_POSITION_PRECEDING : DOCUMENT_POSITION_FOLLOWING;
         return DOCUMENT_POSITION_DISCONNECTED | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | direction;
     }
@@ -1820,7 +1728,7 @@
         return DOCUMENT_POSITION_DISCONNECTED | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | direction;
     }
 
-    unsigned connection = start1->treeScope() != start2->treeScope() ? DOCUMENT_POSITION_DISCONNECTED | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC : 0;
+    unsigned connection = &start1->treeScope() != &start2->treeScope() ? DOCUMENT_POSITION_DISCONNECTED | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC : 0;
 
     // Walk the two chains backwards and look for the first difference.
     for (unsigned i = min(index1, index2); i; --i) {
@@ -2062,8 +1970,8 @@
 static ContainerNode* parentOrShadowHostOrFrameOwner(const Node* node)
 {
     ContainerNode* parent = node->parentOrShadowHostNode();
-    if (!parent && node->document() && node->document()->frame())
-        parent = node->document()->frame()->ownerElement();
+    if (!parent && node->document().frame())
+        parent = node->document().frame()->ownerElement();
     return parent;
 }
 
@@ -2073,15 +1981,15 @@
         fputs("*", stderr);
     fputs(indent.utf8().data(), stderr);
     node->showNode();
-     if (node->isShadowRoot()) {
-         if (ShadowRoot* youngerShadowRoot = toShadowRoot(node)->youngerShadowRoot())
-             showSubTreeAcrossFrame(youngerShadowRoot, markedNode, indent + "\t");
-     } else {
-         if (node->isFrameOwnerElement())
-             showSubTreeAcrossFrame(static_cast<const HTMLFrameOwnerElement*>(node)->contentDocument(), markedNode, indent + "\t");
-         if (ShadowRoot* oldestShadowRoot = oldestShadowRootFor(node))
-             showSubTreeAcrossFrame(oldestShadowRoot, markedNode, indent + "\t");
-     }
+    if (node->isShadowRoot()) {
+        if (ShadowRoot* youngerShadowRoot = toShadowRoot(node)->youngerShadowRoot())
+            showSubTreeAcrossFrame(youngerShadowRoot, markedNode, indent + "\t");
+    } else {
+        if (node->isFrameOwnerElement())
+            showSubTreeAcrossFrame(toHTMLFrameOwnerElement(node)->contentDocument(), markedNode, indent + "\t");
+        if (ShadowRoot* oldestShadowRoot = oldestShadowRootFor(node))
+            showSubTreeAcrossFrame(oldestShadowRoot, markedNode, indent + "\t");
+    }
     for (Node* child = node->firstChild(); child; child = child->nextSibling())
         showSubTreeAcrossFrame(child, markedNode, indent + "\t");
 }
@@ -2136,7 +2044,7 @@
 
 ScriptExecutionContext* Node::scriptExecutionContext() const
 {
-    return document();
+    return document().contextDocument().get();
 }
 
 void Node::didMoveToNewDocument(Document* oldDocument)
@@ -2148,7 +2056,7 @@
         if (!listenerMap.isEmpty()) {
             Vector<AtomicString> types = listenerMap.eventTypes();
             for (unsigned i = 0; i < types.size(); ++i)
-                document()->addListenerTypeIfNeeded(types[i]);
+                document().addListenerTypeIfNeeded(types[i]);
         }
     }
 
@@ -2157,33 +2065,35 @@
             cache->remove(this);
 
     const EventListenerVector& mousewheelListeners = getEventListeners(eventNames().mousewheelEvent);
+    WheelController* oldController = WheelController::from(oldDocument);
+    WheelController* newController = WheelController::from(&document());
     for (size_t i = 0; i < mousewheelListeners.size(); ++i) {
-        oldDocument->didRemoveWheelEventHandler();
-        document()->didAddWheelEventHandler();
+        oldController->didRemoveWheelEventHandler(oldDocument);
+        newController->didAddWheelEventHandler(&document());
     }
 
     const EventListenerVector& wheelListeners = getEventListeners(eventNames().wheelEvent);
     for (size_t i = 0; i < wheelListeners.size(); ++i) {
-        oldDocument->didRemoveWheelEventHandler();
-        document()->didAddWheelEventHandler();
+        oldController->didRemoveWheelEventHandler(oldDocument);
+        newController->didAddWheelEventHandler(&document());
     }
 
     if (const TouchEventTargetSet* touchHandlers = oldDocument ? oldDocument->touchEventTargets() : 0) {
         while (touchHandlers->contains(this)) {
             oldDocument->didRemoveTouchEventHandler(this);
-            document()->didAddTouchEventHandler(this);
+            document().didAddTouchEventHandler(this);
         }
     }
 
     if (Vector<OwnPtr<MutationObserverRegistration> >* registry = mutationObserverRegistry()) {
         for (size_t i = 0; i < registry->size(); ++i) {
-            document()->addMutationObserverTypes(registry->at(i)->mutationTypes());
+            document().addMutationObserverTypes(registry->at(i)->mutationTypes());
         }
     }
 
     if (HashSet<MutationObserverRegistration*>* transientRegistry = transientMutationObserverRegistry()) {
         for (HashSet<MutationObserverRegistration*>::iterator iter = transientRegistry->begin(); iter != transientRegistry->end(); ++iter) {
-            document()->addMutationObserverTypes((*iter)->mutationTypes());
+            document().addMutationObserverTypes((*iter)->mutationTypes());
         }
     }
 }
@@ -2193,13 +2103,12 @@
     if (!targetNode->EventTarget::addEventListener(eventType, listener, useCapture))
         return false;
 
-    if (Document* document = targetNode->document()) {
-        document->addListenerTypeIfNeeded(eventType);
-        if (eventType == eventNames().wheelEvent || eventType == eventNames().mousewheelEvent)
-            document->didAddWheelEventHandler();
-        else if (eventNames().isTouchEventType(eventType))
-            document->didAddTouchEventHandler(targetNode);
-    }
+    Document& document = targetNode->document();
+    document.addListenerTypeIfNeeded(eventType);
+    if (eventType == eventNames().wheelEvent || eventType == eventNames().mousewheelEvent)
+        WheelController::from(&document)->didAddWheelEventHandler(&document);
+    else if (eventNames().isTouchEventType(eventType))
+        document.didAddTouchEventHandler(targetNode);
 
     return true;
 }
@@ -2216,12 +2125,11 @@
 
     // FIXME: Notify Document that the listener has vanished. We need to keep track of a number of
     // listeners for each type, not just a bool - see https://bugs.webkit.org/show_bug.cgi?id=33861
-    if (Document* document = targetNode->document()) {
-        if (eventType == eventNames().wheelEvent || eventType == eventNames().mousewheelEvent)
-            document->didRemoveWheelEventHandler();
-        else if (eventNames().isTouchEventType(eventType))
-            document->didRemoveTouchEventHandler(targetNode);
-    }
+    Document& document = targetNode->document();
+    if (eventType == eventNames().wheelEvent || eventType == eventNames().mousewheelEvent)
+        WheelController::from(&document)->didAddWheelEventHandler(&document);
+    else if (eventNames().isTouchEventType(eventType))
+        document.didRemoveTouchEventHandler(targetNode);
 
     return true;
 }
@@ -2322,7 +2230,7 @@
         registration = registry.last().get();
     }
 
-    document()->addMutationObserverTypes(registration->mutationTypes());
+    document().addMutationObserverTypes(registration->mutationTypes());
 }
 
 void Node::unregisterMutationObserver(MutationObserverRegistration* registration)
@@ -2362,7 +2270,7 @@
 
 void Node::notifyMutationObserversNodeWillDetach()
 {
-    if (!document()->hasMutationObservers())
+    if (!document().hasMutationObservers())
         return;
 
     for (Node* node = parentNode(); node; node = node->parentNode()) {
@@ -2416,7 +2324,7 @@
 
     ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
 
-    if (!document()->hasListenerType(Document::DOMSUBTREEMODIFIED_LISTENER))
+    if (!document().hasListenerType(Document::DOMSUBTREEMODIFIED_LISTENER))
         return;
 
     dispatchScopedEvent(MutationEvent::create(eventNames().DOMSubtreeModifiedEvent, true));
@@ -2425,7 +2333,7 @@
 bool Node::dispatchDOMActivateEvent(int detail, PassRefPtr<Event> underlyingEvent)
 {
     ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
-    RefPtr<UIEvent> event = UIEvent::create(eventNames().DOMActivateEvent, true, true, document()->defaultView(), detail);
+    RefPtr<UIEvent> event = UIEvent::create(eventNames().DOMActivateEvent, true, true, document().defaultView(), detail);
     event->setUnderlyingEvent(underlyingEvent);
     dispatchScopedEvent(event);
     return event->defaultHandled();
@@ -2433,18 +2341,18 @@
 
 bool Node::dispatchKeyEvent(const PlatformKeyboardEvent& event)
 {
-    return EventDispatcher::dispatchEvent(this, KeyboardEventDispatchMediator::create(KeyboardEvent::create(event, document()->defaultView())));
+    return EventDispatcher::dispatchEvent(this, KeyboardEventDispatchMediator::create(KeyboardEvent::create(event, document().defaultView())));
 }
 
 bool Node::dispatchMouseEvent(const PlatformMouseEvent& event, const AtomicString& eventType,
     int detail, Node* relatedTarget)
 {
-    return EventDispatcher::dispatchEvent(this, MouseEventDispatchMediator::create(MouseEvent::create(eventType, document()->defaultView(), event, detail, relatedTarget)));
+    return EventDispatcher::dispatchEvent(this, MouseEventDispatchMediator::create(MouseEvent::create(eventType, document().defaultView(), event, detail, relatedTarget)));
 }
 
 bool Node::dispatchGestureEvent(const PlatformGestureEvent& event)
 {
-    RefPtr<GestureEvent> gestureEvent = GestureEvent::create(document()->defaultView(), event);
+    RefPtr<GestureEvent> gestureEvent = GestureEvent::create(document().defaultView(), event);
     if (!gestureEvent.get())
         return false;
     return EventDispatcher::dispatchEvent(this, GestureEventDispatchMediator::create(gestureEvent));
@@ -2462,7 +2370,7 @@
 
 bool Node::dispatchBeforeLoadEvent(const String& sourceURL)
 {
-    if (!document()->hasListenerType(Document::BEFORELOAD_LISTENER))
+    if (!document().hasListenerType(Document::BEFORELOAD_LISTENER))
         return true;
 
     RefPtr<Node> protector(this);
@@ -2473,7 +2381,7 @@
 
 bool Node::dispatchWheelEvent(const PlatformWheelEvent& event)
 {
-    return EventDispatcher::dispatchEvent(this, WheelEventDispatchMediator::create(event, document()->defaultView()));
+    return EventDispatcher::dispatchEvent(this, WheelEventDispatchMediator::create(event, document().defaultView()));
 }
 
 void Node::dispatchChangeEvent()
@@ -2493,7 +2401,7 @@
     const AtomicString& eventType = event->type();
     if (eventType == eventNames().keydownEvent || eventType == eventNames().keypressEvent) {
         if (event->isKeyboardEvent()) {
-            if (Frame* frame = document()->frame())
+            if (Frame* frame = document().frame())
                 frame->eventHandler()->defaultKeyboardEventHandler(toKeyboardEvent(event));
         }
     } else if (eventType == eventNames().clickEvent) {
@@ -2501,13 +2409,13 @@
         if (dispatchDOMActivateEvent(detail, event))
             event->setDefaultHandled();
     } else if (eventType == eventNames().contextmenuEvent) {
-        if (Page* page = document()->page())
+        if (Page* page = document().page())
             page->contextMenuController().handleContextMenuEvent(event);
     } else if (eventType == eventNames().textInputEvent) {
         if (event->hasInterface(eventNames().interfaceForTextEvent))
-            if (Frame* frame = document()->frame())
+            if (Frame* frame = document().frame())
                 frame->eventHandler()->defaultTextInputEventHandler(static_cast<TextEvent*>(event));
-#if OS(WINDOWS)
+#if OS(WIN)
     } else if (eventType == eventNames().mousedownEvent && event->isMouseEvent()) {
         MouseEvent* mouseEvent = toMouseEvent(event);
         if (mouseEvent->button() == MiddleButton) {
@@ -2519,7 +2427,7 @@
                 renderer = renderer->parent();
 
             if (renderer) {
-                if (Frame* frame = document()->frame())
+                if (Frame* frame = document().frame())
                     frame->eventHandler()->startPanScrolling(renderer);
             }
         }
@@ -2534,7 +2442,7 @@
             startNode = startNode->parentOrShadowHostNode();
 
         if (startNode && startNode->renderer())
-            if (Frame* frame = document()->frame())
+            if (Frame* frame = document().frame())
                 frame->eventHandler()->defaultWheelEventHandler(startNode, wheelEvent);
     } else if (event->type() == eventNames().webkitEditableContentChangedEvent) {
         dispatchInputEvent();
@@ -2599,7 +2507,7 @@
     // faster for non-Document nodes, and because the call to removedLastRef that is inlined
     // at all deref call sites is smaller if it's a non-virtual function.
     if (isTreeScope()) {
-        treeScope()->removedLastRefToScope();
+        treeScope().removedLastRefToScope();
         return;
     }
 
@@ -2656,7 +2564,7 @@
 
 PassRefPtr<NodeList> Node::getDestinationInsertionPoints()
 {
-    document()->updateDistributionForNodeIfNeeded(this);
+    document().updateDistributionForNodeIfNeeded(this);
     Vector<InsertionPoint*, 8> insertionPoints;
     collectInsertionPointsWhereNodeIsDistributed(this, insertionPoints);
     Vector<RefPtr<Node> > filteredInsertionPoints;
@@ -2693,44 +2601,41 @@
 
 void Node::setFocus(bool flag)
 {
-    if (Document* document = this->document())
-        document->userActionElements().setFocused(this, flag);
+    document().userActionElements().setFocused(this, flag);
 }
 
 void Node::setActive(bool flag, bool)
 {
-    if (Document* document = this->document())
-        document->userActionElements().setActive(this, flag);
+    document().userActionElements().setActive(this, flag);
 }
 
 void Node::setHovered(bool flag)
 {
-    if (Document* document = this->document())
-        document->userActionElements().setHovered(this, flag);
+    document().userActionElements().setHovered(this, flag);
 }
 
 bool Node::isUserActionElementActive() const
 {
     ASSERT(isUserActionElement());
-    return document()->userActionElements().isActive(this);
+    return document().userActionElements().isActive(this);
 }
 
 bool Node::isUserActionElementInActiveChain() const
 {
     ASSERT(isUserActionElement());
-    return document()->userActionElements().isInActiveChain(this);
+    return document().userActionElements().isInActiveChain(this);
 }
 
 bool Node::isUserActionElementHovered() const
 {
     ASSERT(isUserActionElement());
-    return document()->userActionElements().isHovered(this);
+    return document().userActionElements().isHovered(this);
 }
 
 bool Node::isUserActionElementFocused() const
 {
     ASSERT(isUserActionElement());
-    return document()->userActionElements().isFocused(this);
+    return document().userActionElements().isFocused(this);
 }
 
 void Node::setCustomElementState(CustomElementState newState)
diff --git a/Source/core/dom/Node.h b/Source/core/dom/Node.h
index 5831fdd..58738dc 100644
--- a/Source/core/dom/Node.h
+++ b/Source/core/dom/Node.h
@@ -100,11 +100,6 @@
     StyleChangeFromRenderer
 };
 
-enum AttachBehavior {
-    DeprecatedAttachNow,
-    AttachLazily,
-};
-
 class NodeRareDataBase {
 public:
     RenderObject* renderer() const { return m_renderer; }
@@ -166,9 +161,6 @@
     static bool isSupported(const String& feature, const String& version);
     static void dumpStatistics();
 
-    enum StyleChange { NoChange, NoInherit, Inherit, Force, Reattach };
-    static StyleChange diff(const RenderStyle*, const RenderStyle*, Document*);
-
     virtual ~Node();
     void willBeDeletedFrom(Document*);
 
@@ -273,7 +265,7 @@
     bool isStyledElement() const { return isHTMLElement() || isSVGElement(); }
 
     bool isDocumentNode() const;
-    bool isTreeScope() const { return treeScope()->rootNode() == this; }
+    bool isTreeScope() const { return treeScope().rootNode() == this; }
     bool isDocumentFragment() const { return getFlag(IsDocumentFragmentFlag); }
     bool isShadowRoot() const { return isDocumentFragment() && isTreeScope(); }
     bool isInsertionPoint() const { return getFlag(IsInsertionPointFlag); }
@@ -415,12 +407,8 @@
     bool isV8CollectableDuringMinorGC() const { return getFlag(V8CollectableDuringMinorGCFlag); }
     void setV8CollectableDuringMinorGC(bool flag) { setFlag(flag, V8CollectableDuringMinorGCFlag); }
 
-    enum ShouldSetAttached {
-        SetAttached,
-        DoNotSetAttached
-    };
-    void lazyAttach(ShouldSetAttached = SetAttached);
-    void lazyReattach(ShouldSetAttached = SetAttached);
+    void lazyAttach();
+    void lazyReattach();
 
     virtual void setFocus(bool flag);
     virtual void setActive(bool flag = true, bool pause = false);
@@ -481,21 +469,18 @@
     unsigned nodeIndex() const;
 
     // Returns the DOM ownerDocument attribute. This method never returns NULL, except in the case
-    // of (1) a Document node or (2) a DocumentType node that is not used with any Document yet.
+    // of a Document node.
     Document* ownerDocument() const;
 
-    // Returns the document associated with this node. This method never returns NULL, except in the case
-    // of a DocumentType node that is not used with any Document yet. A Document node returns itself.
-    Document* document() const
+    // Returns the document associated with this node. A Document node returns itself.
+    Document& document() const
     {
         ASSERT(this);
-        // FIXME: below ASSERT is useful, but prevents the use of document() in the constructor or destructor
-        // due to the virtual function call to nodeType().
-        ASSERT(documentInternal() || (nodeType() == DOCUMENT_TYPE_NODE && !inDocument()));
-        return documentInternal();
+        ASSERT(documentInternal());
+        return *documentInternal();
     }
 
-    TreeScope* treeScope() const { return m_treeScope; }
+    TreeScope& treeScope() const { return *m_treeScope; }
 
     // Returns true if this node is associated with a document and is in its associated document's
     // node tree, false otherwise.
@@ -592,9 +577,9 @@
     // Implementation can determine the type of subtree by seeing insertionPoint->inDocument().
     // For a performance reason, notifications are delivered only to ContainerNode subclasses if the insertionPoint is out of document.
     //
-    // There are another callback named didNotifyDescendantInsertions(), which is called after all the descendant is notified.
-    // Only a few subclasses actually need this. To utilize this, the node should return InsertionShouldCallDidNotifyDescendantInsertions
-    // from insrtedInto().
+    // There are another callback named didNotifySubtreeInsertionsToDocument(), which is called after all the descendant is notified,
+    // if this node was inserted into the document tree. Only a few subclasses actually need this. To utilize this, the node should
+    // return InsertionShouldCallDidNotifySubtreeInsertions from insrtedInto().
     //
     enum InsertionNotificationRequest {
         InsertionDone,
@@ -602,7 +587,7 @@
     };
 
     virtual InsertionNotificationRequest insertedInto(ContainerNode* insertionPoint);
-    virtual void didNotifySubtreeInsertions(ContainerNode*) { }
+    virtual void didNotifySubtreeInsertionsToDocument() { }
 
     // Notifies the node that it is no longer part of the tree.
     //
@@ -820,7 +805,7 @@
 
     void setHasCustomStyleCallbacks() { setFlag(true, HasCustomStyleCallbacksFlag); }
 
-    Document* documentInternal() const { return treeScope()->documentScope(); }
+    Document* documentInternal() const { return treeScope().documentScope(); }
     void setTreeScope(TreeScope* scope) { m_treeScope = scope; }
 
 private:
@@ -924,7 +909,7 @@
         lazyReattach();
 }
 
-inline void Node::lazyReattach(ShouldSetAttached shouldSetAttached)
+inline void Node::lazyReattach()
 {
     if (styleChangeType() == LazyAttachStyleChange)
         return;
@@ -934,12 +919,12 @@
 
     if (attached())
         detach(context);
-    lazyAttach(shouldSetAttached);
+    lazyAttach();
 }
 
-inline bool shouldRecalcStyle(Node::StyleChange change, const Node* node)
+inline bool shouldRecalcStyle(StyleRecalcChange change, const Node* node)
 {
-    return change >= Node::Inherit || node->childNeedsStyleRecalc() || node->needsStyleRecalc();
+    return change >= Inherit || node->childNeedsStyleRecalc() || node->needsStyleRecalc();
 }
 
 } //namespace
diff --git a/Source/core/dom/NodeIterator.cpp b/Source/core/dom/NodeIterator.cpp
index 6bb4d9f..f2cb1e7 100644
--- a/Source/core/dom/NodeIterator.cpp
+++ b/Source/core/dom/NodeIterator.cpp
@@ -25,6 +25,7 @@
 #include "config.h"
 #include "core/dom/NodeIterator.h"
 
+#include "bindings/v8/ExceptionMessages.h"
 #include "bindings/v8/ExceptionState.h"
 #include "bindings/v8/ScriptState.h"
 #include "core/dom/Document.h"
@@ -78,23 +79,19 @@
     , m_referenceNode(root(), true)
     , m_detached(false)
 {
-    // Document type nodes may have a null document. But since they can't have children, there is no need to listen for modifications to these.
-    ASSERT(root()->document() || root()->nodeType() == Node::DOCUMENT_TYPE_NODE);
     ScriptWrappable::init(this);
-    if (Document* ownerDocument = root()->document())
-        ownerDocument->attachNodeIterator(this);
+    root()->document().attachNodeIterator(this);
 }
 
 NodeIterator::~NodeIterator()
 {
-    if (Document* ownerDocument = root()->document())
-        ownerDocument->detachNodeIterator(this);
+    root()->document().detachNodeIterator(this);
 }
 
 PassRefPtr<Node> NodeIterator::nextNode(ScriptState* state, ExceptionState& es)
 {
     if (m_detached) {
-        es.throwDOMException(InvalidStateError);
+        es.throwDOMException(InvalidStateError, ExceptionMessages::failedToExecute("nextNode", "NodeIterator", "The iterator is detached."));
         return 0;
     }
 
@@ -123,7 +120,7 @@
 PassRefPtr<Node> NodeIterator::previousNode(ScriptState* state, ExceptionState& es)
 {
     if (m_detached) {
-        es.throwDOMException(InvalidStateError);
+        es.throwDOMException(InvalidStateError, ExceptionMessages::failedToExecute("previousNode", "NodeIterator", "The iterator is detached."));
         return 0;
     }
 
@@ -151,8 +148,7 @@
 
 void NodeIterator::detach()
 {
-    if (Document* ownerDocument = root()->document())
-        ownerDocument->detachNodeIterator(this);
+    root()->document().detachNodeIterator(this);
     m_detached = true;
     m_referenceNode.node.clear();
 }
@@ -167,8 +163,7 @@
 {
     ASSERT(!m_detached);
     ASSERT(removedNode);
-    ASSERT(root()->document());
-    ASSERT(root()->document() == removedNode->document());
+    ASSERT(&root()->document() == &removedNode->document());
 
     // Iterator is not affected if the removed node is the reference node and is the root.
     // or if removed node is not the reference node, or the ancestor of the reference node.
diff --git a/Source/core/dom/NodeRenderingContext.cpp b/Source/core/dom/NodeRenderingContext.cpp
index a59c09e..da6f56f 100644
--- a/Source/core/dom/NodeRenderingContext.cpp
+++ b/Source/core/dom/NodeRenderingContext.cpp
@@ -79,7 +79,7 @@
         if (!element->isInTopLayer())
             return 0;
 
-        const Vector<RefPtr<Element> >& topLayerElements = element->document()->topLayerElements();
+        const Vector<RefPtr<Element> >& topLayerElements = element->document().topLayerElements();
         size_t position = topLayerElements.find(element);
         ASSERT(position != notFound);
         for (size_t i = position + 1; i < topLayerElements.size(); ++i) {
@@ -144,7 +144,7 @@
         // will prevent it.
         if (!m_renderingParent || !m_renderingParent->renderer())
             return 0;
-        return m_node->document()->renderView();
+        return m_node->document().renderView();
     }
 
     if (m_parentFlowRenderer)
@@ -162,7 +162,7 @@
         return false;
     if (!parentRenderer->canHaveChildren())
         return false;
-    if (!m_renderingParent->childShouldCreateRenderer(*this))
+    if (!m_renderingParent->childShouldCreateRenderer(*m_node))
         return false;
     return true;
 }
@@ -182,7 +182,7 @@
         elementInsideRegionNeedsRenderer = element->shouldMoveToFlowThread(m_style.get());
 
         // Children of this element will only be allowed to be flowed into other flow-threads if display is NOT none.
-        if (element->rendererIsNeeded(*this))
+        if (element->rendererIsNeeded(*m_style))
             element->setIsInsideRegion(true);
     }
 
@@ -199,8 +199,8 @@
     if (!element->shouldMoveToFlowThread(m_style.get()))
         return;
 
-    ASSERT(m_node->document()->renderView());
-    FlowThreadController* flowThreadController = m_node->document()->renderView()->flowThreadController();
+    ASSERT(m_node->document().renderView());
+    FlowThreadController* flowThreadController = m_node->document().renderView()->flowThreadController();
     m_parentFlowRenderer = flowThreadController->ensureRenderFlowThreadWithName(m_style->flowThread());
     flowThreadController->registerNamedFlowContentNode(m_node, m_parentFlowRenderer);
 }
@@ -224,7 +224,7 @@
 
     moveToFlowThreadIfNeeded();
 
-    if (!element->rendererIsNeeded(*this))
+    if (!element->rendererIsNeeded(*m_style))
         return;
 
     RenderObject* newRenderer = element->createRenderer(m_style.get());
@@ -247,7 +247,7 @@
     newRenderer->setAnimatableStyle(m_style.release()); // setAnimatableStyle() can depend on renderer() already being set.
 
     if (FullscreenElementStack::isActiveFullScreenElement(element)) {
-        newRenderer = RenderFullScreen::wrapRenderer(newRenderer, parentRenderer, element->document());
+        newRenderer = RenderFullScreen::wrapRenderer(newRenderer, parentRenderer, &element->document());
         if (!newRenderer)
             return;
     }
@@ -268,7 +268,7 @@
     RenderObject* parentRenderer = this->parentRenderer();
 
     if (m_parentDetails.resetStyleInheritance())
-        m_style = textNode->document()->styleResolver()->defaultStyleForElement();
+        m_style = textNode->document().styleResolver()->defaultStyleForElement();
     else
         m_style = parentRenderer->style();
 
diff --git a/Source/core/dom/NodeRenderingTraversal.cpp b/Source/core/dom/NodeRenderingTraversal.cpp
index 2563ccb..7353a13 100644
--- a/Source/core/dom/NodeRenderingTraversal.cpp
+++ b/Source/core/dom/NodeRenderingTraversal.cpp
@@ -50,7 +50,7 @@
 ContainerNode* parent(const Node* node, ParentDetails* details)
 {
     // FIXME: Once everything lazy attaches we should assert that we don't need a distribution recalc here.
-    ComposedTreeWalker walker(node, ComposedTreeWalker::CrossUpperBoundary, ComposedTreeWalker::CanStartFromShadowBoundary);
+    ComposedTreeWalker walker(node, ComposedTreeWalker::CanStartFromShadowBoundary);
     ContainerNode* found = toContainerNode(walker.traverseParent(walker.get(), details));
     return details->outOfComposition() ? 0 : found;
 }
@@ -93,34 +93,6 @@
     return 0;
 }
 
-Node* nextInScope(const Node* node)
-{
-    ComposedTreeWalker walker = ComposedTreeWalker(node, ComposedTreeWalker::DoNotCrossUpperBoundary);
-    walker.next();
-    return walker.get();
-}
-
-Node* previousInScope(const Node* node)
-{
-    ComposedTreeWalker walker = ComposedTreeWalker(node, ComposedTreeWalker::DoNotCrossUpperBoundary);
-    walker.previous();
-    return walker.get();
-}
-
-Node* parentInScope(const Node* node)
-{
-    ComposedTreeWalker walker = ComposedTreeWalker(node, ComposedTreeWalker::DoNotCrossUpperBoundary);
-    walker.parent();
-    return walker.get();
-}
-
-Node* lastChildInScope(const Node* node)
-{
-    ComposedTreeWalker walker = ComposedTreeWalker(node, ComposedTreeWalker::DoNotCrossUpperBoundary);
-    walker.lastChild();
-    return walker.get();
-}
-
 }
 
 } // namespace
diff --git a/Source/core/dom/NodeRenderingTraversal.h b/Source/core/dom/NodeRenderingTraversal.h
index 2db8aaf..135d866 100644
--- a/Source/core/dom/NodeRenderingTraversal.h
+++ b/Source/core/dom/NodeRenderingTraversal.h
@@ -69,11 +69,6 @@
 Node* nextSibling(const Node*);
 Node* previousSibling(const Node*);
 
-Node* nextInScope(const Node*);
-Node* previousInScope(const Node*);
-Node* parentInScope(const Node*);
-Node* lastChildInScope(const Node*);
-
 inline ContainerNode* parent(const Node* node)
 {
     ParentDetails unusedDetails;
diff --git a/Source/core/dom/Notation.cpp b/Source/core/dom/Notation.cpp
index 7636048..e635eab 100644
--- a/Source/core/dom/Notation.cpp
+++ b/Source/core/dom/Notation.cpp
@@ -29,6 +29,7 @@
     , m_publicId(publicId)
     , m_systemId(systemId)
 {
+    ASSERT_NOT_REACHED();
     ScriptWrappable::init(this);
 }
 
diff --git a/Source/core/dom/Position.cpp b/Source/core/dom/Position.cpp
index 02f46bc..646f305 100644
--- a/Source/core/dom/Position.cpp
+++ b/Source/core/dom/Position.cpp
@@ -37,6 +37,8 @@
 #include "core/editing/htmlediting.h"
 #include "core/html/HTMLHtmlElement.h"
 #include "core/html/HTMLTableElement.h"
+#include "core/page/Frame.h"
+#include "core/page/Settings.h"
 #include "core/platform/Logging.h"
 #include "core/rendering/InlineIterator.h"
 #include "core/rendering/InlineTextBox.h"
@@ -149,7 +151,7 @@
         return m_anchorNode.get();
     case PositionIsBeforeAnchor:
     case PositionIsAfterAnchor:
-        return findParent(m_anchorNode.get());
+        return m_anchorNode->parentNode();
     }
     ASSERT_NOT_REACHED();
     return 0;
@@ -209,7 +211,7 @@
 
     // FIXME: This should only be necessary for legacy positions, but is also needed for positions before and after Tables
     if (m_offset <= 0 && (m_anchorType != PositionIsAfterAnchor && m_anchorType != PositionIsAfterChildren)) {
-        if (findParent(m_anchorNode.get()) && (editingIgnoresContent(m_anchorNode.get()) || isTableElement(m_anchorNode.get())))
+        if (m_anchorNode->parentNode() && (editingIgnoresContent(m_anchorNode.get()) || isTableElement(m_anchorNode.get())))
             return positionInParentBeforeNode(m_anchorNode.get());
         return Position(m_anchorNode.get(), 0, PositionIsOffsetInAnchor);
     }
@@ -294,17 +296,16 @@
 
 Position Position::previous(PositionMoveType moveType) const
 {
-    Node* n = deprecatedNode();
-    if (!n)
+    Node* node = deprecatedNode();
+    if (!node)
         return *this;
 
-    int o = deprecatedEditingOffset();
+    int offset = deprecatedEditingOffset();
     // FIXME: Negative offsets shouldn't be allowed. We should catch this earlier.
-    ASSERT(o >= 0);
+    ASSERT(offset >= 0);
 
-    if (o > 0) {
-        Node* child = n->childNode(o - 1);
-        if (child)
+    if (offset > 0) {
+        if (Node* child = node->childNode(offset - 1))
             return lastPositionInOrAfterNode(child);
 
         // There are two reasons child might be 0:
@@ -314,51 +315,46 @@
         //      Going from 1 to 0 is correct.
         switch (moveType) {
         case CodePoint:
-            return createLegacyEditingPosition(n, o - 1);
+            return createLegacyEditingPosition(node, offset - 1);
         case Character:
-            return createLegacyEditingPosition(n, uncheckedPreviousOffset(n, o));
+            return createLegacyEditingPosition(node, uncheckedPreviousOffset(node, offset));
         case BackwardDeletion:
-            return createLegacyEditingPosition(n, uncheckedPreviousOffsetForBackwardDeletion(n, o));
+            return createLegacyEditingPosition(node, uncheckedPreviousOffsetForBackwardDeletion(node, offset));
         }
     }
 
-    ContainerNode* parent = findParent(n);
-    if (!parent)
-        return *this;
-
-    return createLegacyEditingPosition(parent, n->nodeIndex());
+    if (ContainerNode* parent = node->parentNode())
+        return createLegacyEditingPosition(parent, node->nodeIndex());
+    return *this;
 }
 
 Position Position::next(PositionMoveType moveType) const
 {
     ASSERT(moveType != BackwardDeletion);
 
-    Node* n = deprecatedNode();
-    if (!n)
+    Node* node = deprecatedNode();
+    if (!node)
         return *this;
 
-    int o = deprecatedEditingOffset();
+    int offset = deprecatedEditingOffset();
     // FIXME: Negative offsets shouldn't be allowed. We should catch this earlier.
-    ASSERT(o >= 0);
+    ASSERT(offset >= 0);
 
-    Node* child = n->childNode(o);
-    if (child || (!n->hasChildNodes() && o < lastOffsetForEditing(n))) {
-        if (child)
-            return firstPositionInOrBeforeNode(child);
+    if (Node* child = node->childNode(offset))
+        return firstPositionInOrBeforeNode(child);
 
+    if (!node->hasChildNodes() && offset < lastOffsetForEditing(node)) {
         // There are two reasons child might be 0:
         //   1) The node is node like a text node that is not an element, and therefore has no children.
         //      Going forward one character at a time is correct.
         //   2) The new offset is a bogus offset like (<br>, 1), and there is no child.
         //      Going from 0 to 1 is correct.
-        return createLegacyEditingPosition(n, (moveType == Character) ? uncheckedNextOffset(n, o) : o + 1);
+        return createLegacyEditingPosition(node, (moveType == Character) ? uncheckedNextOffset(node, offset) : offset + 1);
     }
 
-    ContainerNode* parent = findParent(n);
-    if (!parent)
-        return *this;
-
-    return createLegacyEditingPosition(parent, n->nodeIndex() + 1);
+    if (ContainerNode* parent = node->parentNode())
+        return createLegacyEditingPosition(parent, node->nodeIndex() + 1);
+    return *this;
 }
 
 int Position::uncheckedPreviousOffset(const Node* n, int current)
@@ -428,10 +424,10 @@
 
 Node* Position::parentEditingBoundary() const
 {
-    if (!m_anchorNode || !m_anchorNode->document())
+    if (!m_anchorNode)
         return 0;
 
-    Node* documentElement = m_anchorNode->document()->documentElement();
+    Node* documentElement = m_anchorNode->document().documentElement();
     if (!documentElement)
         return 0;
 
@@ -447,14 +443,14 @@
 {
     if (isNull())
         return true;
-    return !findParent(deprecatedNode()) && m_offset <= 0;
+    return !deprecatedNode()->parentNode() && m_offset <= 0;
 }
 
 bool Position::atEndOfTree() const
 {
     if (isNull())
         return true;
-    return !findParent(deprecatedNode()) && m_offset >= lastOffsetForEditing(deprecatedNode());
+    return !deprecatedNode()->parentNode() && m_offset >= lastOffsetForEditing(deprecatedNode());
 }
 
 int Position::renderedOffset() const
@@ -847,11 +843,6 @@
     return node && node->renderer() && !node->renderer()->isSelectable();
 }
 
-ContainerNode* Position::findParent(const Node* node)
-{
-    return node->parentNode();
-}
-
 bool Position::nodeIsUserSelectAll(const Node* node)
 {
     return RuntimeEnabledFeatures::userSelectAllEnabled() && node && node->renderer() && node->renderer()->style()->userSelect() == SELECT_ALL;
@@ -904,14 +895,17 @@
     if (isHTMLHtmlElement(m_anchorNode.get()))
         return false;
 
-    if (renderer->isBlockFlow()) {
+    if (renderer->isRenderBlockFlow()) {
         if (toRenderBlock(renderer)->logicalHeight() || m_anchorNode->hasTagName(bodyTag)) {
             if (!Position::hasRenderedNonAnonymousDescendantsWithHeight(renderer))
                 return atFirstEditingPositionForNode() && !Position::nodeIsUserSelectNone(deprecatedNode());
             return m_anchorNode->rendererIsEditable() && !Position::nodeIsUserSelectNone(deprecatedNode()) && atEditingBoundary();
         }
-    } else
-        return m_anchorNode->rendererIsEditable() && !Position::nodeIsUserSelectNone(deprecatedNode()) && atEditingBoundary();
+    } else {
+        Frame* frame = m_anchorNode->document().frame();
+        bool caretBrowsing = frame->settings() && frame->settings()->caretBrowsingEnabled();
+        return (caretBrowsing || m_anchorNode->rendererIsEditable()) && !Position::nodeIsUserSelectNone(deprecatedNode()) && atEditingBoundary();
+    }
 
     return false;
 }
@@ -1159,7 +1153,7 @@
 
     if (!renderer->isText()) {
         inlineBox = 0;
-        if (canHaveChildrenForEditing(deprecatedNode()) && renderer->isBlockFlow() && hasRenderedNonAnonymousDescendantsWithHeight(renderer)) {
+        if (canHaveChildrenForEditing(deprecatedNode()) && renderer->isRenderBlockFlow() && hasRenderedNonAnonymousDescendantsWithHeight(renderer)) {
             // Try a visually equivalent position with possibly opposite editability. This helps in case |this| is in
             // an editable block but surrounded by non-editable positions. It acts to negate the logic at the beginning
             // of RenderObject::createVisiblePosition().
@@ -1307,7 +1301,7 @@
 {
     TextDirection primaryDirection = LTR;
     for (const RenderObject* r = m_anchorNode->renderer(); r; r = r->parent()) {
-        if (r->isBlockFlow()) {
+        if (r->isRenderBlockFlow()) {
             primaryDirection = r->style()->direction();
             break;
         }
diff --git a/Source/core/dom/Position.h b/Source/core/dom/Position.h
index 4189054..d2b1d1e 100644
--- a/Source/core/dom/Position.h
+++ b/Source/core/dom/Position.h
@@ -127,7 +127,8 @@
     // will be treated as before ignoredNode (thus node() is really after the position, not containing it).
     Node* deprecatedNode() const { return m_anchorNode.get(); }
 
-    Document* document() const { return m_anchorNode ? m_anchorNode->document() : 0; }
+    Document* document() const { return m_anchorNode ? &m_anchorNode->document() : 0; }
+    bool inDocument() const { return m_anchorNode && m_anchorNode->inDocument(); }
     Element* rootEditableElement() const
     {
         Node* container = containerNode();
@@ -249,13 +250,13 @@
     // At least one caller currently hits this ASSERT though, which indicates
     // that the caller is trying to make a position relative to a disconnected node (which is likely an error)
     // Specifically, editing/deleting/delete-ligature-001.html crashes with ASSERT(node->parentNode())
-    return Position(Position::findParent(node), node->nodeIndex(), Position::PositionIsOffsetInAnchor);
+    return Position(node->parentNode(), node->nodeIndex(), Position::PositionIsOffsetInAnchor);
 }
 
 inline Position positionInParentAfterNode(const Node* node)
 {
-    ASSERT(Position::findParent(node));
-    return Position(Position::findParent(node), node->nodeIndex() + 1, Position::PositionIsOffsetInAnchor);
+    ASSERT(node->parentNode());
+    return Position(node->parentNode(), node->nodeIndex() + 1, Position::PositionIsOffsetInAnchor);
 }
 
 // positionBeforeNode and positionAfterNode return neighbor-anchored positions, construction is O(1)
diff --git a/Source/core/dom/PositionIterator.cpp b/Source/core/dom/PositionIterator.cpp
index 34328d6..5cc76b1 100644
--- a/Source/core/dom/PositionIterator.cpp
+++ b/Source/core/dom/PositionIterator.cpp
@@ -160,7 +160,7 @@
     if (isTableElement(m_anchorNode) || editingIgnoresContent(m_anchorNode))
         return (atStartOfNode() || atEndOfNode()) && !Position::nodeIsUserSelectNone(m_anchorNode->parentNode());
 
-    if (!isHTMLHtmlElement(m_anchorNode) && renderer->isBlockFlow()) {
+    if (!isHTMLHtmlElement(m_anchorNode) && renderer->isRenderBlockFlow()) {
         if (toRenderBlock(renderer)->logicalHeight() || m_anchorNode->hasTagName(bodyTag)) {
             if (!Position::hasRenderedNonAnonymousDescendantsWithHeight(renderer))
                 return atStartOfNode() && !Position::nodeIsUserSelectNone(m_anchorNode);
diff --git a/Source/core/dom/PostAttachCallbacks.cpp b/Source/core/dom/PostAttachCallbacks.cpp
new file mode 100644
index 0000000..b862396
--- /dev/null
+++ b/Source/core/dom/PostAttachCallbacks.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer
+ *    in the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. 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/PostAttachCallbacks.h"
+
+#include "core/dom/Node.h"
+#include "wtf/RefPtr.h"
+
+namespace WebCore {
+
+typedef std::pair<PostAttachCallbacks::Callback, RefPtr<Node> > CallbackInfo;
+typedef Vector<CallbackInfo> CallbackQueue;
+
+static size_t s_attachDepth;
+
+static CallbackQueue& callbackQueue()
+{
+    DEFINE_STATIC_LOCAL(CallbackQueue, callbackQueue, ());
+    return callbackQueue;
+}
+
+void PostAttachCallbacks::queueCallback(Callback callback, Node* node)
+{
+    callbackQueue().append(CallbackInfo(callback, node));
+}
+
+PostAttachCallbacks::SuspendScope::SuspendScope()
+{
+    ++s_attachDepth;
+}
+
+PostAttachCallbacks::SuspendScope::~SuspendScope()
+{
+    if (s_attachDepth == 1) {
+        // We recalculate size() each time through the loop because a callback
+        // can add more callbacks to the end of the queue.
+        CallbackQueue& queue = callbackQueue();
+        for (size_t i = 0; i < queue.size(); ++i) {
+            const CallbackInfo& info = queue[i];
+            info.first(info.second.get());
+        }
+        queue.clear();
+    }
+    --s_attachDepth;
+}
+
+} // namespace WebCore
diff --git a/Source/core/dom/PostAttachCallbacks.h b/Source/core/dom/PostAttachCallbacks.h
new file mode 100644
index 0000000..5684cb8
--- /dev/null
+++ b/Source/core/dom/PostAttachCallbacks.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PostAttachCallbacks_h
+#define PostAttachCallbacks_h
+
+#include "wtf/Forward.h"
+
+namespace WebCore {
+
+class Node;
+
+class PostAttachCallbacks {
+public:
+    typedef void (*Callback)(Node*);
+    static void queueCallback(Callback, Node*);
+
+    class SuspendScope {
+    public:
+        SuspendScope();
+        ~SuspendScope();
+    };
+private:
+    PostAttachCallbacks();
+};
+
+} // namespace WebCore
+
+#endif // PostAttachCallbacks_h
diff --git a/Source/core/dom/ProcessingInstruction.cpp b/Source/core/dom/ProcessingInstruction.cpp
index a4ede16..94ee37e 100644
--- a/Source/core/dom/ProcessingInstruction.cpp
+++ b/Source/core/dom/ProcessingInstruction.cpp
@@ -36,7 +36,7 @@
 
 namespace WebCore {
 
-inline ProcessingInstruction::ProcessingInstruction(Document* document, const String& target, const String& data)
+inline ProcessingInstruction::ProcessingInstruction(Document& document, const String& target, const String& data)
     : CharacterData(document, data, CreateOther)
     , m_target(target)
     , m_resource(0)
@@ -49,7 +49,7 @@
     ScriptWrappable::init(this);
 }
 
-PassRefPtr<ProcessingInstruction> ProcessingInstruction::create(Document* document, const String& target, const String& data)
+PassRefPtr<ProcessingInstruction> ProcessingInstruction::create(Document& document, const String& target, const String& data)
 {
     return adoptRef(new ProcessingInstruction(document, target, data));
 }
@@ -63,7 +63,7 @@
         m_resource->removeClient(this);
 
     if (inDocument())
-        document()->styleSheetCollections()->removeStyleSheetCandidateNode(this);
+        document().styleSheetCollections()->removeStyleSheetCandidateNode(this);
 }
 
 String ProcessingInstruction::nodeName() const
@@ -85,7 +85,7 @@
 
 void ProcessingInstruction::checkStyleSheet()
 {
-    if (m_target == "xml-stylesheet" && document()->frame() && parentNode() == document()) {
+    if (m_target == "xml-stylesheet" && document().frame() && parentNode() == &document()) {
         // see http://www.w3.org/TR/xml-stylesheet/
         // ### support stylesheet included in a fragment of this (or another) document
         // ### make sure this gets called when adding from javascript
@@ -128,30 +128,30 @@
                 m_resource = 0;
             }
 
-            String url = document()->completeURL(href).string();
+            String url = document().completeURL(href).string();
             if (!dispatchBeforeLoadEvent(url))
                 return;
 
             m_loading = true;
-            document()->styleSheetCollections()->addPendingSheet();
-            FetchRequest request(ResourceRequest(document()->completeURL(href)), FetchInitiatorTypeNames::processinginstruction);
+            document().styleSheetCollections()->addPendingSheet();
+            FetchRequest request(ResourceRequest(document().completeURL(href)), FetchInitiatorTypeNames::processinginstruction);
             if (m_isXSL)
-                m_resource = document()->fetcher()->fetchXSLStyleSheet(request);
+                m_resource = document().fetcher()->fetchXSLStyleSheet(request);
             else
             {
                 String charset = attrs.get("charset");
                 if (charset.isEmpty())
-                    charset = document()->charset();
+                    charset = document().charset();
                 request.setCharset(charset);
 
-                m_resource = document()->fetcher()->fetchCSSStyleSheet(request);
+                m_resource = document().fetcher()->fetchCSSStyleSheet(request);
             }
             if (m_resource)
                 m_resource->addClient(this);
             else {
                 // The request may have been denied if (for example) the stylesheet is local and the document is remote.
                 m_loading = false;
-                document()->styleSheetCollections()->removePendingSheet(this);
+                document().styleSheetCollections()->removePendingSheet(this);
             }
         }
     }
@@ -169,7 +169,7 @@
 bool ProcessingInstruction::sheetLoaded()
 {
     if (!isLoading()) {
-        document()->styleSheetCollections()->removePendingSheet(this);
+        document().styleSheetCollections()->removePendingSheet(this);
         return true;
     }
     return false;
@@ -248,7 +248,7 @@
     CharacterData::insertedInto(insertionPoint);
     if (!insertionPoint->inDocument())
         return InsertionDone;
-    document()->styleSheetCollections()->addStyleSheetCandidateNode(this, m_createdByParser);
+    document().styleSheetCollections()->addStyleSheetCandidateNode(this, m_createdByParser);
     checkStyleSheet();
     return InsertionDone;
 }
@@ -259,7 +259,7 @@
     if (!insertionPoint->inDocument())
         return;
 
-    document()->styleSheetCollections()->removeStyleSheetCandidateNode(this);
+    document().styleSheetCollections()->removeStyleSheetCandidateNode(this);
 
     RefPtr<StyleSheet> removedSheet = m_sheet;
 
@@ -270,8 +270,8 @@
     }
 
     // If we're in document teardown, then we don't need to do any notification of our sheet's removal.
-    if (document()->renderer())
-        document()->removedStyleSheet(removedSheet.get());
+    if (document().renderer())
+        document().removedStyleSheet(removedSheet.get());
 }
 
 void ProcessingInstruction::finishParsingChildren()
diff --git a/Source/core/dom/ProcessingInstruction.h b/Source/core/dom/ProcessingInstruction.h
index 7b216f0..7c8ace9 100644
--- a/Source/core/dom/ProcessingInstruction.h
+++ b/Source/core/dom/ProcessingInstruction.h
@@ -33,7 +33,7 @@
 
 class ProcessingInstruction FINAL : public CharacterData, private StyleSheetResourceClient {
 public:
-    static PassRefPtr<ProcessingInstruction> create(Document*, const String& target, const String& data);
+    static PassRefPtr<ProcessingInstruction> create(Document&, const String& target, const String& data);
     virtual ~ProcessingInstruction();
 
     const String& target() const { return m_target; }
@@ -53,7 +53,7 @@
 
 private:
     friend class CharacterData;
-    ProcessingInstruction(Document*, const String& target, const String& data);
+    ProcessingInstruction(Document&, const String& target, const String& data);
 
     virtual String nodeName() const;
     virtual NodeType nodeType() const;
@@ -91,6 +91,12 @@
     return static_cast<ProcessingInstruction*>(node);
 }
 
-} //namespace
+inline const ProcessingInstruction* toProcessingInstruction(const Node* node)
+{
+    ASSERT_WITH_SECURITY_IMPLICATION(!node || node->nodeType() == Node::PROCESSING_INSTRUCTION_NODE);
+    return static_cast<const ProcessingInstruction*>(node);
+}
+
+} // namespace WebCore
 
 #endif
diff --git a/Source/core/dom/Promise.idl b/Source/core/dom/Promise.idl
index d2fa864..3413c52 100644
--- a/Source/core/dom/Promise.idl
+++ b/Source/core/dom/Promise.idl
@@ -28,15 +28,12 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-// FIXME: |PromiseValue| should be changed to |Promise|. http://crbug.com/266700
-// IDLs using |Promise| should be written with "typedef any PromiseValue;" and |PromiseValue|.
-
 callback PromiseInit = void (PromiseResolver resolver);
 callback AnyCallback = any (optional any value);
 [
    GlobalContext=Window&WorkerGlobalScope,
    CustomConstructor(PromiseInit init),
-   EnabledAtRuntime=promise
+   EnabledAtRuntime=Promise
 ] interface Promise {
    [Custom] Promise then(optional AnyCallback fulfillCallback, optional AnyCallback rejectCallback);
    [Custom] Promise catch(optional AnyCallback rejectCallback);
diff --git a/Source/core/dom/PromiseResolver.idl b/Source/core/dom/PromiseResolver.idl
index b671070..ab417fa 100644
--- a/Source/core/dom/PromiseResolver.idl
+++ b/Source/core/dom/PromiseResolver.idl
@@ -30,7 +30,7 @@
 
 [
    GlobalContext=Window&WorkerGlobalScope,
-   EnabledAtRuntime=promise
+   EnabledAtRuntime=Promise
 ] interface PromiseResolver {
    [Custom] void fulfill(optional any value);
    [Custom] void resolve(optional any value);
diff --git a/Source/core/dom/PseudoElement.cpp b/Source/core/dom/PseudoElement.cpp
index 105ac7e..e397b9b 100644
--- a/Source/core/dom/PseudoElement.cpp
+++ b/Source/core/dom/PseudoElement.cpp
@@ -27,7 +27,6 @@
 #include "config.h"
 #include "core/dom/PseudoElement.h"
 
-#include "core/dom/NodeRenderingContext.h"
 #include "core/rendering/RenderObject.h"
 #include "core/rendering/RenderQuote.h"
 #include "core/rendering/style/ContentData.h"
@@ -55,7 +54,7 @@
 }
 
 PseudoElement::PseudoElement(Element* parent, PseudoId pseudoId)
-    : Element(pseudoElementTagName(), parent->document(), CreatePseudoElement)
+    : Element(pseudoElementTagName(), &parent->document(), CreatePseudoElement)
     , m_pseudoId(pseudoId)
 {
     ASSERT(pseudoId != NOPSEUDO);
@@ -99,12 +98,12 @@
     }
 }
 
-bool PseudoElement::rendererIsNeeded(const NodeRenderingContext& context)
+bool PseudoElement::rendererIsNeeded(const RenderStyle& style)
 {
-    return pseudoElementRendererIsNeeded(context.style());
+    return pseudoElementRendererIsNeeded(&style);
 }
 
-void PseudoElement::didRecalcStyle(StyleChange)
+void PseudoElement::didRecalcStyle(StyleRecalcChange)
 {
     if (!renderer())
         return;
diff --git a/Source/core/dom/PseudoElement.h b/Source/core/dom/PseudoElement.h
index 0f2ad66..0bd4984 100644
--- a/Source/core/dom/PseudoElement.h
+++ b/Source/core/dom/PseudoElement.h
@@ -43,7 +43,7 @@
 
     virtual PassRefPtr<RenderStyle> customStyleForRenderer() OVERRIDE;
     virtual void attach(const AttachContext& = AttachContext()) OVERRIDE;
-    virtual bool rendererIsNeeded(const NodeRenderingContext&) OVERRIDE;
+    virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
 
     // As per http://dev.w3.org/csswg/css3-regions/#flow-into, pseudo-elements such as ::first-line, ::first-letter, ::before or ::after
     // cannot be directly collected into a named flow.
@@ -57,7 +57,7 @@
 private:
     PseudoElement(Element*, PseudoId);
 
-    virtual void didRecalcStyle(StyleChange) OVERRIDE;
+    virtual void didRecalcStyle(StyleRecalcChange) OVERRIDE;
     virtual PseudoId customPseudoId() const OVERRIDE { return m_pseudoId; }
 
     PseudoId m_pseudoId;
diff --git a/Source/core/dom/Range.cpp b/Source/core/dom/Range.cpp
index ba27e67..7767ffd 100644
--- a/Source/core/dom/Range.cpp
+++ b/Source/core/dom/Range.cpp
@@ -50,7 +50,9 @@
 #include "wtf/Vector.h"
 #include "wtf/text/CString.h"
 #include "wtf/text/StringBuilder.h"
+#ifndef NDEBUG
 #include <stdio.h>
+#endif
 
 namespace WebCore {
 
@@ -59,8 +61,8 @@
 
 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, rangeCounter, ("Range"));
 
-inline Range::Range(PassRefPtr<Document> ownerDocument)
-    : m_ownerDocument(ownerDocument)
+inline Range::Range(Document& ownerDocument)
+    : m_ownerDocument(&ownerDocument)
     , m_start(m_ownerDocument)
     , m_end(m_ownerDocument)
 {
@@ -72,13 +74,13 @@
     m_ownerDocument->attachRange(this);
 }
 
-PassRefPtr<Range> Range::create(PassRefPtr<Document> ownerDocument)
+PassRefPtr<Range> Range::create(Document& ownerDocument)
 {
     return adoptRef(new Range(ownerDocument));
 }
 
-inline Range::Range(PassRefPtr<Document> ownerDocument, PassRefPtr<Node> startContainer, int startOffset, PassRefPtr<Node> endContainer, int endOffset)
-    : m_ownerDocument(ownerDocument)
+inline Range::Range(Document& ownerDocument, Node* startContainer, int startOffset, Node* endContainer, int endOffset)
+    : m_ownerDocument(&ownerDocument)
     , m_start(m_ownerDocument)
     , m_end(m_ownerDocument)
 {
@@ -95,12 +97,12 @@
     setEnd(endContainer, endOffset);
 }
 
-PassRefPtr<Range> Range::create(PassRefPtr<Document> ownerDocument, PassRefPtr<Node> startContainer, int startOffset, PassRefPtr<Node> endContainer, int endOffset)
+PassRefPtr<Range> Range::create(Document& ownerDocument, Node* startContainer, int startOffset, Node* endContainer, int endOffset)
 {
     return adoptRef(new Range(ownerDocument, startContainer, startOffset, endContainer, endOffset));
 }
 
-PassRefPtr<Range> Range::create(PassRefPtr<Document> ownerDocument, const Position& start, const Position& end)
+PassRefPtr<Range> Range::create(Document& ownerDocument, const Position& start, const Position& end)
 {
     return adoptRef(new Range(ownerDocument, start.containerNode(), start.computeOffsetInContainerNode(), end.containerNode(), end.computeOffsetInContainerNode()));
 }
@@ -115,14 +117,14 @@
 #endif
 }
 
-void Range::setDocument(Document* document)
+void Range::setDocument(Document& document)
 {
-    ASSERT(m_ownerDocument != document);
-    if (m_ownerDocument)
-        m_ownerDocument->detachRange(this);
-    m_ownerDocument = document;
-    m_start.setToStartOfNode(document);
-    m_end.setToStartOfNode(document);
+    ASSERT(m_ownerDocument != &document);
+    ASSERT(m_ownerDocument);
+    m_ownerDocument->detachRange(this);
+    m_ownerDocument = &document;
+    m_start.setToStartOfNode(&document);
+    m_end.setToStartOfNode(&document);
     m_ownerDocument->attachRange(this);
 }
 
@@ -222,7 +224,7 @@
     }
 
     bool didMoveDocument = false;
-    if (refNode->document() != m_ownerDocument) {
+    if (&refNode->document() != m_ownerDocument) {
         setDocument(refNode->document());
         didMoveDocument = true;
     }
@@ -250,7 +252,7 @@
     }
 
     bool didMoveDocument = false;
-    if (refNode->document() != m_ownerDocument) {
+    if (&refNode->document() != m_ownerDocument) {
         setDocument(refNode->document());
         didMoveDocument = true;
     }
@@ -302,7 +304,7 @@
         return false;
     }
 
-    if (!refNode->attached() || refNode->document() != m_ownerDocument) {
+    if (!refNode->attached() || &refNode->document() != m_ownerDocument) {
         return false;
     }
 
@@ -330,7 +332,7 @@
         return 0;
     }
 
-    if (!refNode->attached() || refNode->document() != m_ownerDocument) {
+    if (!refNode->attached() || &refNode->document() != m_ownerDocument) {
         es.throwDOMException(WrongDocumentError);
         return 0;
     }
@@ -375,7 +377,7 @@
         return NODE_BEFORE;
     }
 
-    if (refNode->document() != m_ownerDocument) {
+    if (&refNode->document() != m_ownerDocument) {
         // Firefox doesn't throw an exception for this case; it returns 0.
         return NODE_BEFORE;
     }
@@ -420,7 +422,7 @@
     if (es.hadException())
         return 0;
 
-    if (thisCont->document() != sourceCont->document()) {
+    if (&thisCont->document() != &sourceCont->document()) {
         es.throwDOMException(WrongDocumentError);
         return 0;
     }
@@ -579,7 +581,7 @@
         return false;
     }
 
-    if (!refNode->attached() || refNode->document() != m_ownerDocument) {
+    if (!refNode->attached() || &refNode->document() != m_ownerDocument) {
         // Firefox doesn't throw an exception for these cases; it returns false.
         return false;
     }
@@ -647,9 +649,9 @@
     case Node::TEXT_NODE:
     case Node::CDATA_SECTION_NODE:
     case Node::COMMENT_NODE:
-        return static_cast<CharacterData*>(node)->length();
+        return toCharacterData(node)->length();
     case Node::PROCESSING_INSTRUCTION_NODE:
-        return static_cast<ProcessingInstruction*>(node)->data().length();
+        return toProcessingInstruction(node)->data().length();
     case Node::ELEMENT_NODE:
     case Node::ATTRIBUTE_NODE:
     case Node::ENTITY_NODE:
@@ -670,7 +672,7 @@
 
     RefPtr<DocumentFragment> fragment;
     if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS)
-        fragment = DocumentFragment::create(m_ownerDocument.get());
+        fragment = DocumentFragment::create(*m_ownerDocument.get());
 
     if (collapsed(es))
         return fragment.release();
@@ -791,7 +793,7 @@
     case Node::TEXT_NODE:
     case Node::CDATA_SECTION_NODE:
     case Node::COMMENT_NODE:
-        ASSERT(endOffset <= static_cast<CharacterData*>(container)->length());
+        endOffset = std::min(endOffset, toCharacterData(container)->length());
         if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) {
             RefPtr<CharacterData> c = static_pointer_cast<CharacterData>(container->cloneNode(true));
             deleteCharacterData(c, startOffset, endOffset, es);
@@ -802,10 +804,10 @@
                 result = c.release();
         }
         if (action == EXTRACT_CONTENTS || action == DELETE_CONTENTS)
-            static_cast<CharacterData*>(container)->deleteData(startOffset, endOffset - startOffset, es);
+            toCharacterData(container)->deleteData(startOffset, endOffset - startOffset, es);
         break;
     case Node::PROCESSING_INSTRUCTION_NODE:
-        ASSERT(endOffset <= static_cast<ProcessingInstruction*>(container)->data().length());
+        endOffset = std::min(endOffset, toProcessingInstruction(container)->data().length());
         if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) {
             RefPtr<ProcessingInstruction> c = static_pointer_cast<ProcessingInstruction>(container->cloneNode(true));
             c->setData(c->data().substring(startOffset, endOffset - startOffset));
@@ -816,7 +818,7 @@
                 result = c.release();
         }
         if (action == EXTRACT_CONTENTS || action == DELETE_CONTENTS) {
-            ProcessingInstruction* pi = static_cast<ProcessingInstruction*>(container);
+            ProcessingInstruction* pi = toProcessingInstruction(container);
             String data(pi->data());
             data.remove(startOffset, endOffset - startOffset);
             pi->setData(data);
@@ -1062,7 +1064,7 @@
     Node* pastLast = pastLastNode();
     for (Node* n = firstNode(); n != pastLast; n = NodeTraversal::next(n)) {
         if (n->nodeType() == Node::TEXT_NODE || n->nodeType() == Node::CDATA_SECTION_NODE) {
-            String data = static_cast<CharacterData*>(n)->data();
+            String data = toCharacterData(n)->data();
             int length = data.length();
             int start = (n == m_start.container()) ? min(max(0, m_start.offset()), length) : 0;
             int end = (n == m_end.container()) ? min(max(start, m_end.offset()), length) : length;
@@ -1085,7 +1087,7 @@
 
     // We need to update layout, since plainText uses line boxes in the render tree.
     // FIXME: As with innerText, we'd like this to work even if there are no render objects.
-    m_start.container()->document()->updateLayout();
+    m_start.container()->document().updateLayout();
 
     return plainText(this);
 }
@@ -1136,11 +1138,11 @@
         case Node::CDATA_SECTION_NODE:
         case Node::COMMENT_NODE:
         case Node::TEXT_NODE:
-            if (static_cast<unsigned>(offset) > static_cast<CharacterData*>(n)->length())
+            if (static_cast<unsigned>(offset) > toCharacterData(n)->length())
                 es.throwDOMException(IndexSizeError);
             return 0;
         case Node::PROCESSING_INSTRUCTION_NODE:
-            if (static_cast<unsigned>(offset) > static_cast<ProcessingInstruction*>(n)->data().length())
+            if (static_cast<unsigned>(offset) > toProcessingInstruction(n)->data().length())
                 es.throwDOMException(IndexSizeError);
             return 0;
         case Node::ATTRIBUTE_NODE:
@@ -1229,7 +1231,7 @@
         return 0;
     }
 
-    return Range::create(m_ownerDocument, m_start.container(), m_start.offset(), m_end.container(), m_end.offset());
+    return Range::create(*m_ownerDocument.get(), m_start.container(), m_start.offset(), m_end.container(), m_end.offset());
 }
 
 void Range::setStartAfter(Node* refNode, ExceptionState& es)
@@ -1317,7 +1319,7 @@
             return;
     }
 
-    if (m_ownerDocument != refNode->document())
+    if (m_ownerDocument != &refNode->document())
         setDocument(refNode->document());
 
     setStartBefore(refNode);
@@ -1358,7 +1360,7 @@
         }
     }
 
-    if (m_ownerDocument != refNode->document())
+    if (m_ownerDocument != &refNode->document())
         setDocument(refNode->document());
 
     m_start.setToStartOfNode(refNode);
@@ -1655,7 +1657,7 @@
 void Range::nodeChildrenChanged(ContainerNode* container)
 {
     ASSERT(container);
-    ASSERT(container->document() == m_ownerDocument);
+    ASSERT(&container->document() == m_ownerDocument);
     boundaryNodeChildrenChanged(m_start, container);
     boundaryNodeChildrenChanged(m_end, container);
 }
@@ -1680,7 +1682,7 @@
 void Range::nodeChildrenWillBeRemoved(ContainerNode* container)
 {
     ASSERT(container);
-    ASSERT(container->document() == m_ownerDocument);
+    ASSERT(&container->document() == m_ownerDocument);
     boundaryNodeChildrenWillBeRemoved(m_start, container);
     boundaryNodeChildrenWillBeRemoved(m_end, container);
 }
@@ -1703,9 +1705,13 @@
 void Range::nodeWillBeRemoved(Node* node)
 {
     ASSERT(node);
-    ASSERT(node->document() == m_ownerDocument);
+    ASSERT(&node->document() == m_ownerDocument);
     ASSERT(node != m_ownerDocument);
-    ASSERT(node->parentNode());
+
+    // FIXME: Once DOMNodeRemovedFromDocument mutation event removed, we
+    // should change following if-statement to ASSERT(!node->parentNode).
+    if (!node->parentNode())
+        return;
     boundaryNodeWillBeRemoved(m_start, node);
     boundaryNodeWillBeRemoved(m_end, node);
 }
@@ -1723,7 +1729,7 @@
 void Range::textInserted(Node* text, unsigned offset, unsigned length)
 {
     ASSERT(text);
-    ASSERT(text->document() == m_ownerDocument);
+    ASSERT(&text->document() == m_ownerDocument);
     boundaryTextInserted(m_start, text, offset, length);
     boundaryTextInserted(m_end, text, offset, length);
 }
@@ -1744,7 +1750,7 @@
 void Range::textRemoved(Node* text, unsigned offset, unsigned length)
 {
     ASSERT(text);
-    ASSERT(text->document() == m_ownerDocument);
+    ASSERT(&text->document() == m_ownerDocument);
     boundaryTextRemoved(m_start, text, offset, length);
     boundaryTextRemoved(m_end, text, offset, length);
 }
@@ -1760,7 +1766,7 @@
 void Range::textNodesMerged(NodeWithIndex& oldNode, unsigned offset)
 {
     ASSERT(oldNode.node());
-    ASSERT(oldNode.node()->document() == m_ownerDocument);
+    ASSERT(&oldNode.node()->document() == m_ownerDocument);
     ASSERT(oldNode.node()->parentNode());
     ASSERT(oldNode.node()->isTextNode());
     ASSERT(oldNode.node()->previousSibling());
@@ -1782,7 +1788,7 @@
 void Range::textNodeSplit(Text* oldNode)
 {
     ASSERT(oldNode);
-    ASSERT(oldNode->document() == m_ownerDocument);
+    ASSERT(&oldNode->document() == m_ownerDocument);
     ASSERT(oldNode->parentNode());
     ASSERT(oldNode->isTextNode());
     ASSERT(oldNode->nextSibling());
diff --git a/Source/core/dom/Range.h b/Source/core/dom/Range.h
index 5faaf9c..736b7a8 100644
--- a/Source/core/dom/Range.h
+++ b/Source/core/dom/Range.h
@@ -49,12 +49,12 @@
 
 class Range : public RefCounted<Range>, public ScriptWrappable {
 public:
-    static PassRefPtr<Range> create(PassRefPtr<Document>);
-    static PassRefPtr<Range> create(PassRefPtr<Document>, PassRefPtr<Node> startContainer, int startOffset, PassRefPtr<Node> endContainer, int endOffset);
-    static PassRefPtr<Range> create(PassRefPtr<Document>, const Position&, const Position&);
+    static PassRefPtr<Range> create(Document&);
+    static PassRefPtr<Range> create(Document&, Node* startContainer, int startOffset, Node* endContainer, int endOffset);
+    static PassRefPtr<Range> create(Document&, const Position&, const Position&);
     ~Range();
 
-    Document* ownerDocument() const { return m_ownerDocument.get(); }
+    Document& ownerDocument() const { ASSERT(m_ownerDocument); return *m_ownerDocument.get(); }
     Node* startContainer() const { return m_start.container(); }
     int startOffset() const { return m_start.offset(); }
     Node* endContainer() const { return m_end.container(); }
@@ -150,10 +150,10 @@
 #endif
 
 private:
-    explicit Range(PassRefPtr<Document>);
-    Range(PassRefPtr<Document>, PassRefPtr<Node> startContainer, int startOffset, PassRefPtr<Node> endContainer, int endOffset);
+    explicit Range(Document&);
+    Range(Document&, Node* startContainer, int startOffset, Node* endContainer, int endOffset);
 
-    void setDocument(Document*);
+    void setDocument(Document&);
 
     Node* checkNodeWOffset(Node*, int offset, ExceptionState&) const;
     void checkNodeBA(Node*, ExceptionState&, const char* methodName) const;
@@ -168,7 +168,7 @@
     enum ContentsProcessDirection { ProcessContentsForward, ProcessContentsBackward };
     static PassRefPtr<Node> processAncestorsAndTheirSiblings(ActionType, Node* container, ContentsProcessDirection, PassRefPtr<Node> clonedContainer, Node* commonRoot, ExceptionState&);
 
-    RefPtr<Document> m_ownerDocument;
+    RefPtr<Document> m_ownerDocument; // Cannot be null.
     RangeBoundaryPoint m_start;
     RangeBoundaryPoint m_end;
 };
diff --git a/Source/core/dom/ScriptExecutionContext.cpp b/Source/core/dom/ScriptExecutionContext.cpp
index 2cc9e4b..9ac54d9 100644
--- a/Source/core/dom/ScriptExecutionContext.cpp
+++ b/Source/core/dom/ScriptExecutionContext.cpp
@@ -241,7 +241,7 @@
 
     RefPtr<ErrorEvent> errorEvent = event;
     if (shouldSanitizeScriptError(errorEvent->filename(), corsStatus))
-        errorEvent = ErrorEvent::createSanitizedError();
+        errorEvent = ErrorEvent::createSanitizedError(errorEvent->world());
 
     ASSERT(!m_inDispatchErrorEvent);
     m_inDispatchErrorEvent = true;
diff --git a/Source/core/dom/ScriptExecutionContext.h b/Source/core/dom/ScriptExecutionContext.h
index 1bcf0ab..a595aa1 100644
--- a/Source/core/dom/ScriptExecutionContext.h
+++ b/Source/core/dom/ScriptExecutionContext.h
@@ -31,7 +31,7 @@
 #include "core/dom/ActiveDOMObject.h"
 #include "core/dom/ErrorEvent.h"
 #include "core/dom/SecurityContext.h"
-#include "core/loader/CrossOriginAccessControl.h"
+#include "core/fetch/CrossOriginAccessControl.h"
 #include "core/page/ConsoleTypes.h"
 #include "core/page/DOMTimer.h"
 #include "core/platform/LifecycleContext.h"
@@ -41,6 +41,10 @@
 #include "wtf/OwnPtr.h"
 #include "wtf/PassOwnPtr.h"
 
+namespace WTF {
+class OrdinalNumber;
+}
+
 namespace WebCore {
 
 class ContextLifecycleNotifier;
diff --git a/Source/core/dom/ScriptLoader.cpp b/Source/core/dom/ScriptLoader.cpp
index 30f9de9..0345ad9 100644
--- a/Source/core/dom/ScriptLoader.cpp
+++ b/Source/core/dom/ScriptLoader.cpp
@@ -68,8 +68,8 @@
     , m_willExecuteInOrder(false)
 {
     ASSERT(m_element);
-    if (parserInserted && element->document()->scriptableDocumentParser() && !element->document()->isInDocumentWrite())
-        m_startLineNumber = element->document()->scriptableDocumentParser()->lineNumber();
+    if (parserInserted && element->document().scriptableDocumentParser() && !element->document().isInDocumentWrite())
+        m_startLineNumber = element->document().scriptableDocumentParser()->lineNumber();
 }
 
 ScriptLoader::~ScriptLoader()
@@ -77,9 +77,9 @@
     stopLoadRequest();
 }
 
-void ScriptLoader::insertedInto(ContainerNode* insertionPoint)
+void ScriptLoader::didNotifySubtreeInsertionsToDocument()
 {
-    if (insertionPoint->inDocument() && !m_parserInserted)
+    if (!m_parserInserted)
         prepareScript(); // FIXME: Provide a real starting line number here.
 }
 
@@ -166,14 +166,6 @@
     return false;
 }
 
-Document* ScriptLoader::executingDocument() const
-{
-    Document* document = m_element->document();
-    if (!document->import())
-        return document;
-    return document->import()->master();
-}
-
 // http://dev.w3.org/html5/spec/Overview.html#prepare-a-script
 bool ScriptLoader::prepareScript(const TextPosition& scriptStartPosition, LegacyTypeSupport supportLegacyTypes)
 {
@@ -211,16 +203,10 @@
     m_alreadyStarted = true;
 
     // FIXME: If script is parser inserted, verify it's still in the original document.
-    Document* executingDocument = this->executingDocument();
-    Document* elementDocument = m_element->document();
+    Document& elementDocument = m_element->document();
+    Document* contextDocument = elementDocument.contextDocument().get();
 
-    // FIXME: Eventually we'd like to evaluate scripts which are inserted into a
-    // viewless document but this'll do for now.
-    // See http://bugs.webkit.org/show_bug.cgi?id=5727
-    if (!executingDocument->frame())
-        return false;
-
-    if (!executingDocument->frame()->script()->canExecuteScripts(AboutToExecuteScript))
+    if (!contextDocument || !contextDocument->allowExecutingScripts(m_element))
         return false;
 
     if (!isScriptForEventSupported())
@@ -229,7 +215,7 @@
     if (!client->charsetAttributeValue().isEmpty())
         m_characterEncoding = client->charsetAttributeValue();
     else
-        m_characterEncoding = elementDocument->charset();
+        m_characterEncoding = elementDocument.charset();
 
     if (client->hasSourceAttribute()) {
         if (!fetchScript(client->sourceAttributeValue()))
@@ -241,20 +227,20 @@
         m_willBeParserExecuted = true;
     } else if (client->hasSourceAttribute() && m_parserInserted && !client->asyncAttributeValue()) {
         m_willBeParserExecuted = true;
-    } else if (!client->hasSourceAttribute() && m_parserInserted && !elementDocument->haveStylesheetsAndImportsLoaded()) {
+    } else if (!client->hasSourceAttribute() && m_parserInserted && !elementDocument.haveStylesheetsAndImportsLoaded()) {
         m_willBeParserExecuted = true;
         m_readyToBeParserExecuted = true;
     } else if (client->hasSourceAttribute() && !client->asyncAttributeValue() && !m_forceAsync) {
         m_willExecuteInOrder = true;
-        executingDocument->scriptRunner()->queueScriptForExecution(this, m_resource, ScriptRunner::IN_ORDER_EXECUTION);
+        contextDocument->scriptRunner()->queueScriptForExecution(this, m_resource, ScriptRunner::IN_ORDER_EXECUTION);
         m_resource->addClient(this);
     } else if (client->hasSourceAttribute()) {
-        executingDocument->scriptRunner()->queueScriptForExecution(this, m_resource, ScriptRunner::ASYNC_EXECUTION);
+        contextDocument->scriptRunner()->queueScriptForExecution(this, m_resource, ScriptRunner::ASYNC_EXECUTION);
         m_resource->addClient(this);
     } else {
         // Reset line numbering for nested writes.
-        TextPosition position = elementDocument->isInDocumentWrite() ? TextPosition() : scriptStartPosition;
-        KURL scriptURL = (!elementDocument->isInDocumentWrite() && m_parserInserted) ? elementDocument->url() : KURL();
+        TextPosition position = elementDocument.isInDocumentWrite() ? TextPosition() : scriptStartPosition;
+        KURL scriptURL = (!elementDocument.isInDocumentWrite() && m_parserInserted) ? elementDocument.url() : KURL();
         executeScript(ScriptSourceCode(scriptContent(), scriptURL, position));
     }
 
@@ -265,10 +251,10 @@
 {
     ASSERT(m_element);
 
-    RefPtr<Document> elementDocument = m_element->document();
+    RefPtr<Document> elementDocument = &m_element->document();
     if (!m_element->dispatchBeforeLoadEvent(sourceUrl))
         return false;
-    if (!m_element->inDocument() || m_element->document() != elementDocument)
+    if (!m_element->inDocument() || &m_element->document() != elementDocument)
         return false;
 
     ASSERT(!m_resource);
@@ -315,9 +301,12 @@
     if (sourceCode.isEmpty())
         return;
 
-    RefPtr<Document> executingDocument = this->executingDocument();
-    RefPtr<Document> elementDocument = m_element->document();
-    Frame* frame = executingDocument->frame();
+    RefPtr<Document> elementDocument = &m_element->document();
+    RefPtr<Document> contextDocument = elementDocument->contextDocument().get();
+    if (!contextDocument)
+        return;
+
+    Frame* frame = contextDocument->frame();
 
     bool shouldBypassMainWorldContentSecurityPolicy = (frame && frame->script()->shouldBypassMainWorldContentSecurityPolicy()) || elementDocument->contentSecurityPolicy()->allowScriptNonce(m_element->fastGetAttribute(HTMLNames::nonceAttr));
 
@@ -325,18 +314,18 @@
         return;
 
     if (m_isExternalScript && m_resource && !m_resource->mimeTypeAllowedByNosniff()) {
-        executingDocument->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, "Refused to execute script from '" + m_resource->url().elidedString() + "' because its MIME type ('" + m_resource->mimeType() + "') is not executable, and strict MIME type checking is enabled.");
+        contextDocument->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, "Refused to execute script from '" + m_resource->url().elidedString() + "' because its MIME type ('" + m_resource->mimeType() + "') is not executable, and strict MIME type checking is enabled.");
         return;
     }
 
     if (frame) {
-        IgnoreDestructiveWriteCountIncrementer ignoreDesctructiveWriteCountIncrementer(m_isExternalScript ? executingDocument.get() : 0);
+        IgnoreDestructiveWriteCountIncrementer ignoreDesctructiveWriteCountIncrementer(m_isExternalScript ? contextDocument.get() : 0);
 
         if (isHTMLScriptLoader(m_element))
-            executingDocument->pushCurrentScript(toHTMLScriptElement(m_element));
+            contextDocument->pushCurrentScript(toHTMLScriptElement(m_element));
 
         AccessControlStatus corsCheck = NotSharableCrossOrigin;
-        if (sourceCode.resource() && sourceCode.resource()->passesAccessControlCheck(m_element->document()->securityOrigin()))
+        if (sourceCode.resource() && sourceCode.resource()->passesAccessControlCheck(m_element->document().securityOrigin()))
             corsCheck = SharableCrossOrigin;
 
         // Create a script from the script element node, using the script
@@ -345,8 +334,8 @@
         frame->script()->executeScriptInMainWorld(sourceCode, corsCheck);
 
         if (isHTMLScriptLoader(m_element)) {
-            ASSERT(executingDocument->currentScript() == m_element);
-            executingDocument->popCurrentScript();
+            ASSERT(contextDocument->currentScript() == m_element);
+            contextDocument->popCurrentScript();
         }
     }
 }
@@ -377,8 +366,10 @@
 {
     ASSERT(!m_willBeParserExecuted);
 
-    RefPtr<Document> executingDocument = this->executingDocument();
-    RefPtr<Document> elementDocument = m_element->document();
+    RefPtr<Document> elementDocument = &m_element->document();
+    RefPtr<Document> contextDocument = elementDocument->contextDocument().get();
+    if (!contextDocument)
+        return;
 
     // Resource possibly invokes this notifyFinished() more than
     // once because ScriptLoader doesn't unsubscribe itself from
@@ -393,9 +384,9 @@
     }
 
     if (m_willExecuteInOrder)
-        executingDocument->scriptRunner()->notifyScriptReady(this, ScriptRunner::IN_ORDER_EXECUTION);
+        contextDocument->scriptRunner()->notifyScriptReady(this, ScriptRunner::IN_ORDER_EXECUTION);
     else
-        executingDocument->scriptRunner()->notifyScriptReady(this, ScriptRunner::ASYNC_EXECUTION);
+        contextDocument->scriptRunner()->notifyScriptReady(this, ScriptRunner::ASYNC_EXECUTION);
 
     m_resource = 0;
 }
diff --git a/Source/core/dom/ScriptLoader.h b/Source/core/dom/ScriptLoader.h
index cd180f0..e6ba8d3 100644
--- a/Source/core/dom/ScriptLoader.h
+++ b/Source/core/dom/ScriptLoader.h
@@ -67,7 +67,7 @@
     bool forceAsync() const { return m_forceAsync; }
 
     // Helper functions used by our parent classes.
-    void insertedInto(ContainerNode*);
+    void didNotifySubtreeInsertionsToDocument();
     void childrenChanged();
     void handleSourceAttribute(const String& sourceUrl);
     void handleAsyncAttribute();
@@ -82,7 +82,6 @@
     void stopLoadRequest();
 
     ScriptLoaderClient* client() const;
-    Document* executingDocument() const;
 
     // ResourceClient
     virtual void notifyFinished(Resource*) OVERRIDE;
diff --git a/Source/core/dom/SecurityPolicyViolationEvent.idl b/Source/core/dom/SecurityPolicyViolationEvent.idl
index 8eab91e..d067fab 100644
--- a/Source/core/dom/SecurityPolicyViolationEvent.idl
+++ b/Source/core/dom/SecurityPolicyViolationEvent.idl
@@ -23,7 +23,7 @@
  */
 
 [
-    EnabledAtRuntime=experimentalContentSecurityPolicyFeatures,
+    EnabledAtRuntime=ExperimentalContentSecurityPolicyFeatures,
     ConstructorTemplate=Event
 ] interface SecurityPolicyViolationEvent : Event {
     [InitializedByEventConstructor] readonly attribute DOMString documentURI;
diff --git a/Source/core/dom/SelectorQuery.cpp b/Source/core/dom/SelectorQuery.cpp
index db7afdf..82baa86 100644
--- a/Source/core/dom/SelectorQuery.cpp
+++ b/Source/core/dom/SelectorQuery.cpp
@@ -223,7 +223,7 @@
 
 inline bool SelectorDataList::canUseFastQuery(Node* rootNode) const
 {
-    return m_selectors.size() == 1 && rootNode->inDocument() && !rootNode->document()->inQuirksMode();
+    return m_selectors.size() == 1 && rootNode->inDocument() && !rootNode->document().inQuirksMode();
 }
 
 // If returns true, traversalRoots has the elements that may match the selector query.
@@ -245,8 +245,8 @@
     bool startFromParent = false;
 
     for (const CSSSelector* selector = m_selectors[0].selector; selector; selector = selector->tagHistory()) {
-        if (selector->m_match == CSSSelector::Id && !rootNode->document()->containsMultipleElementsWithId(selector->value())) {
-            Element* element = rootNode->treeScope()->getElementById(selector->value());
+        if (selector->m_match == CSSSelector::Id && !rootNode->document().containsMultipleElementsWithId(selector->value())) {
+            Element* element = rootNode->treeScope().getElementById(selector->value());
             if (element && (isTreeScopeRoot(rootNode) || element->isDescendantOf(rootNode)))
                 rootNode = element;
             else if (!element || isRightmostSelector)
@@ -313,11 +313,11 @@
         switch (firstSelector->m_match) {
         case CSSSelector::Id:
             {
-                if (rootNode->document()->containsMultipleElementsWithId(firstSelector->value()))
+                if (rootNode->document().containsMultipleElementsWithId(firstSelector->value()))
                     break;
 
                 // Just the same as getElementById.
-                Element* element = rootNode->treeScope()->getElementById(firstSelector->value());
+                Element* element = rootNode->treeScope().getElementById(firstSelector->value());
                 if (element && (isTreeScopeRoot(rootNode) || element->isDescendantOf(rootNode)))
                     matchedElements.append(element);
                 return;
@@ -374,8 +374,8 @@
     bool matchSingleNode = true;
     bool startFromParent = false;
     for (const CSSSelector* selector = m_selectors[0].selector; selector; selector = selector->tagHistory()) {
-        if (selector->m_match == CSSSelector::Id && !rootNode->document()->containsMultipleElementsWithId(selector->value())) {
-            Element* element = rootNode->treeScope()->getElementById(selector->value());
+        if (selector->m_match == CSSSelector::Id && !rootNode->document().containsMultipleElementsWithId(selector->value())) {
+            Element* element = rootNode->treeScope().getElementById(selector->value());
             if (element && (isTreeScopeRoot(rootNode) || element->isDescendantOf(rootNode)))
                 rootNode = element;
             else if (!element || matchSingleNode)
@@ -427,9 +427,9 @@
         switch (selector->m_match) {
         case CSSSelector::Id:
             {
-                if (rootNode->document()->containsMultipleElementsWithId(selector->value()))
+                if (rootNode->document().containsMultipleElementsWithId(selector->value()))
                     break;
-                Element* element = rootNode->treeScope()->getElementById(selector->value());
+                Element* element = rootNode->treeScope().getElementById(selector->value());
                 return element && (isTreeScopeRoot(rootNode) || element->isDescendantOf(rootNode)) ? element : 0;
             }
         case CSSSelector::Class:
@@ -480,7 +480,7 @@
     return m_selectors.queryFirst(rootNode);
 }
 
-SelectorQuery* SelectorQueryCache::add(const AtomicString& selectors, Document* document, ExceptionState& es)
+SelectorQuery* SelectorQueryCache::add(const AtomicString& selectors, const Document& document, ExceptionState& es)
 {
     HashMap<AtomicString, OwnPtr<SelectorQuery> >::iterator it = m_entries.find(selectors);
     if (it != m_entries.end())
@@ -491,13 +491,13 @@
     parser.parseSelector(selectors, selectorList);
 
     if (!selectorList.first()) {
-        es.throwDOMException(SyntaxError);
+        es.throwDOMException(SyntaxError, "Failed to execute query: '" + selectors + "' is not a valid selector.");
         return 0;
     }
 
     // throw a NamespaceError if the selector includes any namespace prefixes.
     if (selectorList.selectorsNeedNamespaceResolution()) {
-        es.throwDOMException(NamespaceError);
+        es.throwDOMException(NamespaceError, "Failed to execute query: '" + selectors + "' contains namespaces, which are not supported.");
         return 0;
     }
 
diff --git a/Source/core/dom/SelectorQuery.h b/Source/core/dom/SelectorQuery.h
index 66f12a6..2f654c4 100644
--- a/Source/core/dom/SelectorQuery.h
+++ b/Source/core/dom/SelectorQuery.h
@@ -88,7 +88,7 @@
 class SelectorQueryCache {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    SelectorQuery* add(const AtomicString&, Document*, ExceptionState&);
+    SelectorQuery* add(const AtomicString&, const Document&, ExceptionState&);
     void invalidate();
 
 private:
diff --git a/Source/core/dom/ShadowTreeStyleSheetCollection.cpp b/Source/core/dom/ShadowTreeStyleSheetCollection.cpp
index ff29a77..a0d7c84 100644
--- a/Source/core/dom/ShadowTreeStyleSheetCollection.cpp
+++ b/Source/core/dom/ShadowTreeStyleSheetCollection.cpp
@@ -41,7 +41,7 @@
 
 using namespace HTMLNames;
 
-ShadowTreeStyleSheetCollection::ShadowTreeStyleSheetCollection(ShadowRoot* shadowRoot)
+ShadowTreeStyleSheetCollection::ShadowTreeStyleSheetCollection(ShadowRoot& shadowRoot)
     : StyleSheetCollection(shadowRoot)
 {
 }
@@ -65,7 +65,7 @@
         AtomicString title = element->getAttribute(titleAttr);
         bool enabledViaScript = false;
 
-        sheet = static_cast<HTMLStyleElement*>(node)->sheet();
+        sheet = toHTMLStyleElement(node)->sheet();
         if (sheet && !sheet->disabled() && sheet->isCSSStyleSheet())
             activeSheet = static_cast<CSSStyleSheet*>(sheet);
 
diff --git a/Source/core/dom/ShadowTreeStyleSheetCollection.h b/Source/core/dom/ShadowTreeStyleSheetCollection.h
index 2e0a979..a849d68 100644
--- a/Source/core/dom/ShadowTreeStyleSheetCollection.h
+++ b/Source/core/dom/ShadowTreeStyleSheetCollection.h
@@ -41,7 +41,7 @@
 class ShadowTreeStyleSheetCollection FINAL : public StyleSheetCollection {
     WTF_MAKE_NONCOPYABLE(ShadowTreeStyleSheetCollection); WTF_MAKE_FAST_ALLOCATED;
 public:
-    explicit ShadowTreeStyleSheetCollection(ShadowRoot*);
+    explicit ShadowTreeStyleSheetCollection(ShadowRoot&);
 
     bool updateActiveStyleSheets(StyleSheetCollections*, StyleResolverUpdateMode);
 
diff --git a/Source/core/dom/StyleElement.cpp b/Source/core/dom/StyleElement.cpp
index 683a8f2..8f8a151 100644
--- a/Source/core/dom/StyleElement.cpp
+++ b/Source/core/dom/StyleElement.cpp
@@ -55,22 +55,20 @@
         clearSheet();
 }
 
-void StyleElement::processStyleSheet(Document* document, Element* element)
+void StyleElement::processStyleSheet(Document& document, Element* element)
 {
-    ASSERT(document);
     ASSERT(element);
-    document->styleSheetCollections()->addStyleSheetCandidateNode(element, m_createdByParser);
+    document.styleSheetCollections()->addStyleSheetCandidateNode(element, m_createdByParser);
     if (m_createdByParser)
         return;
 
     process(element);
 }
 
-void StyleElement::removedFromDocument(Document* document, Element* element, ContainerNode* scopingNode)
+void StyleElement::removedFromDocument(Document& document, Element* element, ContainerNode* scopingNode)
 {
-    ASSERT(document);
     ASSERT(element);
-    document->styleSheetCollections()->removeStyleSheetCandidateNode(element, scopingNode);
+    document.styleSheetCollections()->removeStyleSheetCandidateNode(element, scopingNode);
 
     RefPtr<StyleSheet> removedSheet = m_sheet;
 
@@ -78,17 +76,17 @@
         clearSheet();
 
     // If we're in document teardown, then we don't need to do any notification of our sheet's removal.
-    if (document->renderer())
-        document->removedStyleSheet(removedSheet.get());
+    if (document.renderer())
+        document.removedStyleSheet(removedSheet.get());
 }
 
-void StyleElement::clearDocumentData(Document* document, Element* element)
+void StyleElement::clearDocumentData(Document& document, Element* element)
 {
     if (m_sheet)
         m_sheet->clearOwnerNode();
 
     if (element->inDocument())
-        document->styleSheetCollections()->removeStyleSheetCandidateNode(element, isHTMLStyleElement(element) ? toHTMLStyleElement(element)->scopingNode() :  0);
+        document.styleSheetCollections()->removeStyleSheetCandidateNode(element, isHTMLStyleElement(element) ? toHTMLStyleElement(element)->scopingNode() :  0);
 }
 
 void StyleElement::childrenChanged(Element* element)
@@ -124,26 +122,26 @@
 {
     ASSERT(e);
     ASSERT(e->inDocument());
-    Document* document = e->document();
+    Document& document = e->document();
     if (m_sheet) {
         if (m_sheet->isLoading())
-            document->styleSheetCollections()->removePendingSheet(e);
+            document.styleSheetCollections()->removePendingSheet(e);
         clearSheet();
     }
 
     // If type is empty or CSS, this is a CSS style sheet.
     const AtomicString& type = this->type();
-    if (document->contentSecurityPolicy()->allowInlineStyle(e->document()->url(), m_startPosition.m_line) && isCSS(e, type)) {
+    if (document.contentSecurityPolicy()->allowInlineStyle(e->document().url(), m_startPosition.m_line) && isCSS(e, type)) {
         RefPtr<MediaQuerySet> mediaQueries = MediaQuerySet::create(media());
 
         MediaQueryEvaluator screenEval("screen", true);
         MediaQueryEvaluator printEval("print", true);
         if (screenEval.eval(mediaQueries.get()) || printEval.eval(mediaQueries.get())) {
-            document->styleSheetCollections()->addPendingSheet();
+            document.styleSheetCollections()->addPendingSheet();
             m_loading = true;
 
             TextPosition startPosition = m_startPosition == TextPosition::belowRangePosition() ? TextPosition::minimumPosition() : m_startPosition;
-            m_sheet = CSSStyleSheet::createInline(e, KURL(), startPosition, document->inputEncoding());
+            m_sheet = CSSStyleSheet::createInline(e, KURL(), startPosition, document.inputEncoding());
             m_sheet->setMediaQueries(mediaQueries.release());
             m_sheet->setTitle(e->title());
             m_sheet->contents()->parseStringAtPosition(text, startPosition, m_createdByParser);
@@ -163,20 +161,18 @@
     return m_sheet ? m_sheet->isLoading() : false;
 }
 
-bool StyleElement::sheetLoaded(Document* document)
+bool StyleElement::sheetLoaded(Document& document)
 {
-    ASSERT(document);
     if (isLoading())
         return false;
 
-    document->styleSheetCollections()->removePendingSheet(m_sheet->ownerNode());
+    document.styleSheetCollections()->removePendingSheet(m_sheet->ownerNode());
     return true;
 }
 
-void StyleElement::startLoadingDynamicSheet(Document* document)
+void StyleElement::startLoadingDynamicSheet(Document& document)
 {
-    ASSERT(document);
-    document->styleSheetCollections()->addPendingSheet();
+    document.styleSheetCollections()->addPendingSheet();
 }
 
 }
diff --git a/Source/core/dom/StyleElement.h b/Source/core/dom/StyleElement.h
index 38ffd15..a26f5a5 100644
--- a/Source/core/dom/StyleElement.h
+++ b/Source/core/dom/StyleElement.h
@@ -42,12 +42,12 @@
     CSSStyleSheet* sheet() const { return m_sheet.get(); }
 
     bool isLoading() const;
-    bool sheetLoaded(Document*);
-    void startLoadingDynamicSheet(Document*);
+    bool sheetLoaded(Document&);
+    void startLoadingDynamicSheet(Document&);
 
-    void processStyleSheet(Document*, Element*);
-    void removedFromDocument(Document*, Element*, ContainerNode* scopingNode = 0);
-    void clearDocumentData(Document*, Element*);
+    void processStyleSheet(Document&, Element*);
+    void removedFromDocument(Document&, Element*, ContainerNode* scopingNode = 0);
+    void clearDocumentData(Document&, Element*);
     void childrenChanged(Element*);
     void finishParsingChildren(Element*);
 
diff --git a/Source/core/dom/StyleSheetCollection.cpp b/Source/core/dom/StyleSheetCollection.cpp
index 8a2b102..1edd2b8 100644
--- a/Source/core/dom/StyleSheetCollection.cpp
+++ b/Source/core/dom/StyleSheetCollection.cpp
@@ -39,7 +39,7 @@
 
 namespace WebCore {
 
-StyleSheetCollection::StyleSheetCollection(TreeScope* treeScope)
+StyleSheetCollection::StyleSheetCollection(TreeScope& treeScope)
     : m_treeScope(treeScope)
     , m_hadActiveLoadingStylesheet(false)
 {
@@ -160,7 +160,7 @@
         for (ListHashSet<Node*, 4>::iterator it = removedNodes->begin(); it != removedNodes->end(); ++it)
             styleResolver->resetAuthorStyle(toContainerNode(*it));
     }
-    styleResolver->resetAuthorStyle(toContainerNode(m_treeScope->rootNode()));
+    styleResolver->resetAuthorStyle(toContainerNode(m_treeScope.rootNode()));
 }
 
 static bool styleSheetsUseRemUnits(const Vector<RefPtr<CSSStyleSheet> >& sheets)
diff --git a/Source/core/dom/StyleSheetCollection.h b/Source/core/dom/StyleSheetCollection.h
index 5fc6111..0a89677 100644
--- a/Source/core/dom/StyleSheetCollection.h
+++ b/Source/core/dom/StyleSheetCollection.h
@@ -68,9 +68,9 @@
     ListHashSet<Node*, 4>* scopingNodesRemoved() { return m_scopingNodesForStyleScoped.scopingNodesRemoved(); }
 
 protected:
-    explicit StyleSheetCollection(TreeScope*);
+    explicit StyleSheetCollection(TreeScope&);
 
-    Document* document() { return m_treeScope->documentScope(); }
+    Document* document() { return m_treeScope.documentScope(); }
 
     enum StyleResolverUpdateType {
         Reconstruct,
@@ -89,7 +89,7 @@
     Vector<RefPtr<StyleSheet> > m_styleSheetsForStyleSheetList;
     Vector<RefPtr<CSSStyleSheet> > m_activeAuthorStyleSheets;
 
-    TreeScope* m_treeScope;
+    TreeScope& m_treeScope;
     bool m_hadActiveLoadingStylesheet;
     bool m_usesRemUnits;
 
diff --git a/Source/core/dom/StyleSheetCollections.cpp b/Source/core/dom/StyleSheetCollections.cpp
index 7a4ae2e..665c240 100644
--- a/Source/core/dom/StyleSheetCollections.cpp
+++ b/Source/core/dom/StyleSheetCollections.cpp
@@ -52,7 +52,7 @@
 
 using namespace HTMLNames;
 
-StyleSheetCollections::StyleSheetCollections(Document* document)
+StyleSheetCollections::StyleSheetCollections(Document& document)
     : m_document(document)
     , m_pendingStylesheets(0)
     , m_injectedStyleSheetCacheValid(false)
@@ -97,7 +97,7 @@
     do {
         --it;
         TreeScope* n = *it;
-        unsigned short position = n->comparePosition(treeScope);
+        unsigned short position = n->comparePosition(*treeScope);
         if (position & Node::DOCUMENT_POSITION_FOLLOWING) {
             treeScopes.insertBefore(followingTreeScope, treeScope);
             return;
@@ -108,23 +108,23 @@
     treeScopes.insertBefore(followingTreeScope, treeScope);
 }
 
-StyleSheetCollection* StyleSheetCollections::ensureStyleSheetCollectionFor(TreeScope* treeScope)
+StyleSheetCollection* StyleSheetCollections::ensureStyleSheetCollectionFor(TreeScope& treeScope)
 {
-    if (treeScope == m_document)
+    if (&treeScope == &m_document)
         return &m_documentStyleSheetCollection;
 
-    HashMap<TreeScope*, OwnPtr<StyleSheetCollection> >::AddResult result = m_styleSheetCollectionMap.add(treeScope, nullptr);
+    HashMap<TreeScope*, OwnPtr<StyleSheetCollection> >::AddResult result = m_styleSheetCollectionMap.add(&treeScope, nullptr);
     if (result.isNewEntry)
         result.iterator->value = adoptPtr(new ShadowTreeStyleSheetCollection(toShadowRoot(treeScope)));
     return result.iterator->value.get();
 }
 
-StyleSheetCollection* StyleSheetCollections::styleSheetCollectionFor(TreeScope* treeScope)
+StyleSheetCollection* StyleSheetCollections::styleSheetCollectionFor(TreeScope& treeScope)
 {
-    if (treeScope == m_document)
+    if (&treeScope == &m_document)
         return &m_documentStyleSheetCollection;
 
-    HashMap<TreeScope*, OwnPtr<StyleSheetCollection> >::iterator it = m_styleSheetCollectionMap.find(treeScope);
+    HashMap<TreeScope*, OwnPtr<StyleSheetCollection> >::iterator it = m_styleSheetCollectionMap.find(&treeScope);
     if (it == m_styleSheetCollectionMap.end())
         return 0;
     return it->value.get();
@@ -171,7 +171,7 @@
     if (m_pageUserSheet)
         return m_pageUserSheet.get();
 
-    Page* owningPage = m_document->page();
+    Page* owningPage = m_document.page();
     if (!owningPage)
         return 0;
 
@@ -180,7 +180,7 @@
         return 0;
 
     // Parse the sheet and cache it.
-    m_pageUserSheet = CSSStyleSheet::createInline(m_document, m_document->settings()->userStyleSheetLocation());
+    m_pageUserSheet = CSSStyleSheet::createInline(&m_document, m_document.settings()->userStyleSheetLocation());
     m_pageUserSheet->contents()->setIsUserStyleSheet(true);
     m_pageUserSheet->contents()->parseString(userSheetText);
     return m_pageUserSheet.get();
@@ -191,7 +191,7 @@
     if (m_pageUserSheet) {
         RefPtr<StyleSheet> removedSheet = m_pageUserSheet;
         m_pageUserSheet = 0;
-        m_document->removedStyleSheet(removedSheet.get());
+        m_document.removedStyleSheet(removedSheet.get());
     }
 }
 
@@ -200,7 +200,7 @@
     clearPageUserSheet();
     // FIXME: Why is this immediately and not defer?
     if (StyleSheet* addedSheet = pageUserSheet())
-        m_document->addedStyleSheet(addedSheet, RecalcStyleImmediately);
+        m_document.addedStyleSheet(addedSheet, RecalcStyleImmediately);
 }
 
 const Vector<RefPtr<CSSStyleSheet> >& StyleSheetCollections::injectedUserStyleSheets() const
@@ -223,7 +223,7 @@
     m_injectedUserStyleSheets.clear();
     m_injectedAuthorStyleSheets.clear();
 
-    Page* owningPage = m_document->page();
+    Page* owningPage = m_document.page();
     if (!owningPage)
         return;
 
@@ -231,11 +231,11 @@
     const UserStyleSheetVector& sheets = pageGroup.userStyleSheets();
     for (unsigned i = 0; i < sheets.size(); ++i) {
         const UserStyleSheet* sheet = sheets[i].get();
-        if (sheet->injectedFrames() == InjectInTopFrameOnly && m_document->ownerElement())
+        if (sheet->injectedFrames() == InjectInTopFrameOnly && m_document.ownerElement())
             continue;
-        if (!UserContentURLPattern::matchesPatterns(m_document->url(), sheet->whitelist(), sheet->blacklist()))
+        if (!UserContentURLPattern::matchesPatterns(m_document.url(), sheet->whitelist(), sheet->blacklist()))
             continue;
-        RefPtr<CSSStyleSheet> groupSheet = CSSStyleSheet::createInline(const_cast<Document*>(m_document), sheet->url());
+        RefPtr<CSSStyleSheet> groupSheet = CSSStyleSheet::createInline(const_cast<Document*>(&m_document), sheet->url());
         bool isUserStyleSheet = sheet->level() == UserStyleUserLevel;
         if (isUserStyleSheet)
             m_injectedUserStyleSheets.append(groupSheet);
@@ -252,22 +252,22 @@
     m_needsDocumentStyleSheetsUpdate = true;
     // FIXME: updateInjectedStyleSheetCache is called inside StyleSheetCollection::updateActiveStyleSheets
     // and batch updates lots of sheets so we can't call addedStyleSheet() or removedStyleSheet().
-    m_document->styleResolverChanged(RecalcStyleDeferred);
+    m_document.styleResolverChanged(RecalcStyleDeferred);
 }
 
 void StyleSheetCollections::addAuthorSheet(PassRefPtr<StyleSheetContents> authorSheet)
 {
     ASSERT(!authorSheet->isUserStyleSheet());
-    m_authorStyleSheets.append(CSSStyleSheet::create(authorSheet, m_document));
-    m_document->addedStyleSheet(m_authorStyleSheets.last().get(), RecalcStyleImmediately);
+    m_authorStyleSheets.append(CSSStyleSheet::create(authorSheet, &m_document));
+    m_document.addedStyleSheet(m_authorStyleSheets.last().get(), RecalcStyleImmediately);
     m_needsDocumentStyleSheetsUpdate = true;
 }
 
 void StyleSheetCollections::addUserSheet(PassRefPtr<StyleSheetContents> userSheet)
 {
     ASSERT(userSheet->isUserStyleSheet());
-    m_userStyleSheets.append(CSSStyleSheet::create(userSheet, m_document));
-    m_document->addedStyleSheet(m_userStyleSheets.last().get(), RecalcStyleImmediately);
+    m_userStyleSheets.append(CSSStyleSheet::create(userSheet, &m_document));
+    m_document.addedStyleSheet(m_userStyleSheets.last().get(), RecalcStyleImmediately);
     m_needsDocumentStyleSheetsUpdate = true;
 }
 
@@ -279,8 +279,8 @@
 
     m_pendingStylesheets--;
 
-    TreeScope* treeScope = isHTMLStyleElement(styleSheetCandidateNode) ? styleSheetCandidateNode->treeScope() : m_document;
-    if (treeScope == m_document)
+    TreeScope* treeScope = isHTMLStyleElement(styleSheetCandidateNode) ? &styleSheetCandidateNode->treeScope() : &m_document;
+    if (treeScope == &m_document)
         m_needsDocumentStyleSheetsUpdate = true;
     else
         m_dirtyTreeScopes.add(treeScope);
@@ -289,13 +289,13 @@
         return;
 
     if (notification == RemovePendingSheetNotifyLater) {
-        m_document->setNeedsNotifyRemoveAllPendingStylesheet();
+        m_document.setNeedsNotifyRemoveAllPendingStylesheet();
         return;
     }
 
     // FIXME: We can't call addedStyleSheet or removedStyleSheet here because we don't know
     // what's new. We should track that to tell the style system what changed.
-    m_document->didRemoveAllPendingStylesheet();
+    m_document.didRemoveAllPendingStylesheet();
 }
 
 void StyleSheetCollections::addStyleSheetCandidateNode(Node* node, bool createdByParser)
@@ -303,37 +303,37 @@
     if (!node->inDocument())
         return;
 
-    TreeScope* treeScope = isHTMLStyleElement(node) ? node->treeScope() : m_document;
-    ASSERT(isHTMLStyleElement(node) || treeScope == m_document);
+    TreeScope& treeScope = isHTMLStyleElement(node) ? node->treeScope() : m_document;
+    ASSERT(isHTMLStyleElement(node) || &treeScope == &m_document);
 
     StyleSheetCollection* collection = ensureStyleSheetCollectionFor(treeScope);
     ASSERT(collection);
     collection->addStyleSheetCandidateNode(node, createdByParser);
 
-    if (treeScope == m_document) {
+    if (&treeScope == &m_document) {
         m_needsDocumentStyleSheetsUpdate = true;
         return;
     }
 
-    insertTreeScopeInDocumentOrder(m_activeTreeScopes, treeScope);
-    m_dirtyTreeScopes.add(treeScope);
+    insertTreeScopeInDocumentOrder(m_activeTreeScopes, &treeScope);
+    m_dirtyTreeScopes.add(&treeScope);
 }
 
 void StyleSheetCollections::removeStyleSheetCandidateNode(Node* node, ContainerNode* scopingNode)
 {
-    TreeScope* treeScope = scopingNode ? scopingNode->treeScope() : m_document;
-    ASSERT(isHTMLStyleElement(node) || treeScope == m_document);
+    TreeScope& treeScope = scopingNode ? scopingNode->treeScope() : m_document;
+    ASSERT(isHTMLStyleElement(node) || &treeScope == &m_document);
 
     StyleSheetCollection* collection = styleSheetCollectionFor(treeScope);
     ASSERT(collection);
     collection->removeStyleSheetCandidateNode(node, scopingNode);
 
-    if (treeScope == m_document) {
+    if (&treeScope == &m_document) {
         m_needsDocumentStyleSheetsUpdate = true;
         return;
     }
-    m_dirtyTreeScopes.add(treeScope);
-    m_activeTreeScopes.remove(treeScope);
+    m_dirtyTreeScopes.add(&treeScope);
+    m_activeTreeScopes.remove(&treeScope);
 }
 
 void StyleSheetCollections::modifiedStyleSheetCandidateNode(Node* node)
@@ -341,13 +341,13 @@
     if (!node->inDocument())
         return;
 
-    TreeScope* treeScope = isHTMLStyleElement(node) ? node->treeScope() : m_document;
-    ASSERT(isHTMLStyleElement(node) || treeScope == m_document);
-    if (treeScope == m_document) {
+    TreeScope& treeScope = isHTMLStyleElement(node) ? node->treeScope() : m_document;
+    ASSERT(isHTMLStyleElement(node) || &treeScope == &m_document);
+    if (&treeScope == &m_document) {
         m_needsDocumentStyleSheetsUpdate = true;
         return;
     }
-    m_dirtyTreeScopes.add(treeScope);
+    m_dirtyTreeScopes.add(&treeScope);
 }
 
 bool StyleSheetCollections::shouldUpdateShadowTreeStyleSheetCollection(StyleResolverUpdateMode updateMode)
@@ -357,7 +357,7 @@
 
 bool StyleSheetCollections::updateActiveStyleSheets(StyleResolverUpdateMode updateMode)
 {
-    if (m_document->inStyleRecalc()) {
+    if (m_document.inStyleRecalc()) {
         // SVG <use> element may manage to invalidate style selector in the middle of a style recalc.
         // https://bugs.webkit.org/show_bug.cgi?id=54344
         // FIXME: This should be fixed in SVG and the call site replaced by ASSERT(!m_inStyleRecalc).
@@ -365,7 +365,7 @@
         return false;
 
     }
-    if (!m_document->renderer() || !m_document->attached())
+    if (!m_document.renderer() || !m_document.attached())
         return false;
 
     bool requiresFullStyleRecalc = false;
@@ -378,8 +378,8 @@
 
         for (TreeScopeSet::iterator it = treeScopes.begin(); it != treeScopes.end(); ++it) {
             TreeScope* treeScope = *it;
-            ASSERT(treeScope != m_document);
-            ShadowTreeStyleSheetCollection* collection = static_cast<ShadowTreeStyleSheetCollection*>(styleSheetCollectionFor(treeScope));
+            ASSERT(treeScope != &m_document);
+            ShadowTreeStyleSheetCollection* collection = static_cast<ShadowTreeStyleSheetCollection*>(styleSheetCollectionFor(*treeScope));
             ASSERT(collection);
             collection->updateActiveStyleSheets(this, updateMode);
             if (!collection->hasStyleSheetCandidateNodes())
@@ -391,7 +391,7 @@
         m_dirtyTreeScopes.clear();
     }
 
-    if (StyleResolver* styleResolver = m_document->styleResolverIfExists()) {
+    if (StyleResolver* styleResolver = m_document.styleResolverIfExists()) {
         styleResolver->finishAppendAuthorStyleSheets();
         resetCSSFeatureFlags(styleResolver->ruleFeatureSet());
     }
@@ -401,7 +401,7 @@
     m_usesRemUnits = m_documentStyleSheetCollection.usesRemUnits();
 
     if (m_needsDocumentStyleSheetsUpdate || updateMode == FullStyleUpdate) {
-        m_document->notifySeamlessChildDocumentsOfStylesheetUpdate();
+        m_document.notifySeamlessChildDocumentsOfStylesheetUpdate();
         m_needsDocumentStyleSheetsUpdate = false;
     }
 
@@ -411,7 +411,7 @@
 void StyleSheetCollections::activeStyleSheetsUpdatedForInspector()
 {
     if (m_activeTreeScopes.isEmpty()) {
-        InspectorInstrumentation::activeStyleSheetsUpdated(m_document, m_documentStyleSheetCollection.styleSheetsForStyleSheetList());
+        InspectorInstrumentation::activeStyleSheetsUpdated(&m_document, m_documentStyleSheetCollection.styleSheetsForStyleSheetList());
         return;
     }
     Vector<RefPtr<StyleSheet> > activeStyleSheets;
@@ -428,7 +428,7 @@
     // FIXME: Inspector needs a vector which has all active stylesheets.
     // However, creating such a large vector might cause performance regression.
     // Need to implement some smarter solution.
-    InspectorInstrumentation::activeStyleSheetsUpdated(m_document, activeStyleSheets);
+    InspectorInstrumentation::activeStyleSheetsUpdated(&m_document, activeStyleSheets);
 }
 
 void StyleSheetCollections::didRemoveShadowRoot(ShadowRoot* shadowRoot)
diff --git a/Source/core/dom/StyleSheetCollections.h b/Source/core/dom/StyleSheetCollections.h
index e934e51..978d1b0 100644
--- a/Source/core/dom/StyleSheetCollections.h
+++ b/Source/core/dom/StyleSheetCollections.h
@@ -51,7 +51,7 @@
 class StyleSheetCollections {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    static PassOwnPtr<StyleSheetCollections> create(Document* document) { return adoptPtr(new StyleSheetCollections(document)); }
+    static PassOwnPtr<StyleSheetCollections> create(Document& document) { return adoptPtr(new StyleSheetCollections(document)); }
 
     ~StyleSheetCollections();
 
@@ -112,17 +112,17 @@
     void getActiveAuthorStyleSheets(Vector<const Vector<RefPtr<CSSStyleSheet> >*>& activeAuthorStyleSheets) const;
 
 private:
-    StyleSheetCollections(Document*);
+    StyleSheetCollections(Document&);
 
-    StyleSheetCollection* ensureStyleSheetCollectionFor(TreeScope*);
-    StyleSheetCollection* styleSheetCollectionFor(TreeScope*);
+    StyleSheetCollection* ensureStyleSheetCollectionFor(TreeScope&);
+    StyleSheetCollection* styleSheetCollectionFor(TreeScope&);
     void activeStyleSheetsUpdatedForInspector();
     bool shouldUpdateShadowTreeStyleSheetCollection(StyleResolverUpdateMode);
 
     typedef ListHashSet<TreeScope*, 16> TreeScopeSet;
     static void insertTreeScopeInDocumentOrder(TreeScopeSet&, TreeScope*);
 
-    Document* m_document;
+    Document& m_document;
 
     // Track the number of currently loading top-level stylesheets needed for rendering.
     // Sheets loaded using the @import directive are not included in this count.
@@ -161,4 +161,3 @@
 }
 
 #endif
-
diff --git a/Source/core/dom/TemplateContentDocumentFragment.h b/Source/core/dom/TemplateContentDocumentFragment.h
index 6ede6f3..6c44e60 100644
--- a/Source/core/dom/TemplateContentDocumentFragment.h
+++ b/Source/core/dom/TemplateContentDocumentFragment.h
@@ -33,16 +33,17 @@
 
 class TemplateContentDocumentFragment FINAL : public DocumentFragment {
 public:
-    static PassRefPtr<TemplateContentDocumentFragment> create(Document* document, const Element* host)
+    static PassRefPtr<TemplateContentDocumentFragment> create(Document& document, const Element* host)
     {
         return adoptRef(new TemplateContentDocumentFragment(document, host));
     }
 
     const Element* host() const { return m_host; }
+    void clearHost() { m_host = 0; }
 
 private:
-    TemplateContentDocumentFragment(Document* document, const Element* host)
-        : DocumentFragment(document, CreateDocumentFragment)
+    TemplateContentDocumentFragment(Document& document, const Element* host)
+        : DocumentFragment(&document, CreateDocumentFragment)
         , m_host(host)
     {
     }
diff --git a/Source/core/dom/Text.cpp b/Source/core/dom/Text.cpp
index 425aabd..90446f1 100644
--- a/Source/core/dom/Text.cpp
+++ b/Source/core/dom/Text.cpp
@@ -23,6 +23,7 @@
 #include "core/dom/Text.h"
 
 #include "SVGNames.h"
+#include "bindings/v8/ExceptionMessages.h"
 #include "bindings/v8/ExceptionState.h"
 #include "bindings/v8/ExceptionStatePlaceholder.h"
 #include "core/css/resolver/StyleResolver.h"
@@ -41,12 +42,12 @@
 
 namespace WebCore {
 
-PassRefPtr<Text> Text::create(Document* document, const String& data)
+PassRefPtr<Text> Text::create(Document& document, const String& data)
 {
     return adoptRef(new Text(document, data, CreateText));
 }
 
-PassRefPtr<Text> Text::createEditingText(Document* document, const String& data)
+PassRefPtr<Text> Text::createEditingText(Document& document, const String& data)
 {
     return adoptRef(new Text(document, data, CreateEditingText));
 }
@@ -56,7 +57,7 @@
     // IndexSizeError: Raised if the specified offset is negative or greater than
     // the number of 16-bit units in data.
     if (offset > length()) {
-        es.throwDOMException(IndexSizeError);
+        es.throwDOMException(IndexSizeError, ExceptionMessages::failedToExecute("splitText", "Text", "The offset " + String::number(offset) + " is larger than the Text node's length."));
         return 0;
     }
 
@@ -72,12 +73,12 @@
     if (es.hadException())
         return 0;
 
-    if (parentNode())
-        document()->textNodeSplit(this);
-
     if (renderer())
         toRenderText(renderer())->setTextWithOffset(dataImpl(), 0, oldStr.length());
 
+    if (parentNode())
+        document().textNodeSplit(this);
+
     return newText.release();
 }
 
@@ -87,7 +88,7 @@
     while ((n = n->previousSibling())) {
         Node::NodeType type = n->nodeType();
         if (type == Node::TEXT_NODE || type == Node::CDATA_SECTION_NODE) {
-            t = static_cast<const Text*>(n);
+            t = toText(n);
             continue;
         }
 
@@ -102,7 +103,7 @@
     while ((n = n->nextSibling())) {
         Node::NodeType type = n->nodeType();
         if (type == Node::TEXT_NODE || type == Node::CDATA_SECTION_NODE) {
-            t = static_cast<const Text*>(n);
+            t = toText(n);
             continue;
         }
 
@@ -121,8 +122,7 @@
     for (const Node* n = startText; n != onePastEndText; n = n->nextSibling()) {
         if (!n->isTextNode())
             continue;
-        const Text* t = static_cast<const Text*>(n);
-        const String& data = t->data();
+        const String& data = toText(n)->data();
         if (std::numeric_limits<unsigned>::max() - data.length() < resultLength)
             CRASH();
         resultLength += data.length();
@@ -132,8 +132,7 @@
     for (const Node* n = startText; n != onePastEndText; n = n->nextSibling()) {
         if (!n->isTextNode())
             continue;
-        const Text* t = static_cast<const Text*>(n);
-        result.append(t->data());
+        result.append(toText(n)->data());
     }
     ASSERT(result.length() == resultLength);
 
@@ -238,12 +237,6 @@
     return true;
 }
 
-static bool isSVGShadowText(Text* text)
-{
-    Node* parentNode = text->parentNode();
-    return parentNode->isShadowRoot() && toShadowRoot(parentNode)->host()->hasTagName(SVGNames::trefTag);
-}
-
 static bool isSVGText(Text* text)
 {
     Node* parentOrShadowHostNode = text->parentOrShadowHostNode();
@@ -252,7 +245,7 @@
 
 RenderText* Text::createTextRenderer(RenderStyle* style)
 {
-    if (isSVGText(this) || isSVGShadowText(this))
+    if (isSVGText(this))
         return new RenderSVGInlineText(this, dataImpl());
 
     if (style->hasTextCombine())
@@ -267,11 +260,11 @@
     CharacterData::attach(context);
 }
 
-bool Text::recalcTextStyle(StyleChange change)
+bool Text::recalcTextStyle(StyleRecalcChange change)
 {
     if (RenderText* renderer = toRenderText(this->renderer())) {
         if (change != NoChange || needsStyleRecalc())
-            renderer->setStyle(document()->styleResolver()->styleForText(this));
+            renderer->setStyle(document().styleResolver()->styleForText(this));
         if (needsStyleRecalc())
             renderer->setText(dataImpl());
         clearNeedsStyleRecalc();
@@ -292,16 +285,16 @@
     return false;
 }
 
-void Text::updateTextRenderer(unsigned offsetOfReplacedData, unsigned lengthOfReplacedData, AttachBehavior attachBehavior)
+void Text::updateTextRenderer(unsigned offsetOfReplacedData, unsigned lengthOfReplacedData, RecalcStyleBehavior recalcStyleBehavior)
 {
     if (!attached())
         return;
     RenderText* textRenderer = toRenderText(renderer());
     if (!textRenderer || !textRendererIsNeeded(NodeRenderingContext(this, textRenderer->style()))) {
-        if (attachBehavior == DeprecatedAttachNow)
-            reattach();
-        else
-            lazyReattach();
+        lazyReattach();
+        // FIXME: Editing should be updated so this is not neccesary.
+        if (recalcStyleBehavior == DeprecatedRecalcStyleImmediatlelyForEditing)
+            document().updateStyleIfNeeded();
         return;
     }
     textRenderer->setTextWithOffset(dataImpl(), offsetOfReplacedData, lengthOfReplacedData);
@@ -317,7 +310,7 @@
     return create(document(), data);
 }
 
-PassRefPtr<Text> Text::createWithLengthLimit(Document* document, const String& data, unsigned start, unsigned lengthLimit)
+PassRefPtr<Text> Text::createWithLengthLimit(Document& document, const String& data, unsigned start, unsigned lengthLimit)
 {
     unsigned dataLength = data.length();
 
diff --git a/Source/core/dom/Text.h b/Source/core/dom/Text.h
index 33a459a..b9929c9 100644
--- a/Source/core/dom/Text.h
+++ b/Source/core/dom/Text.h
@@ -35,9 +35,9 @@
 public:
     static const unsigned defaultLengthLimit = 1 << 16;
 
-    static PassRefPtr<Text> create(Document*, const String&);
-    static PassRefPtr<Text> createWithLengthLimit(Document*, const String&, unsigned positionInString, unsigned lengthLimit = defaultLengthLimit);
-    static PassRefPtr<Text> createEditingText(Document*, const String&);
+    static PassRefPtr<Text> create(Document&, const String&);
+    static PassRefPtr<Text> createWithLengthLimit(Document&, const String&, unsigned positionInString, unsigned lengthLimit = defaultLengthLimit);
+    static PassRefPtr<Text> createEditingText(Document&, const String&);
 
     PassRefPtr<Text> splitText(unsigned offset, ExceptionState&);
 
@@ -46,10 +46,10 @@
     String wholeText() const;
     PassRefPtr<Text> replaceWholeText(const String&);
 
-    bool recalcTextStyle(StyleChange);
+    bool recalcTextStyle(StyleRecalcChange);
     bool textRendererIsNeeded(const NodeRenderingContext&);
     virtual RenderText* createTextRenderer(RenderStyle*);
-    void updateTextRenderer(unsigned offsetOfReplacedData, unsigned lengthOfReplacedData, AttachBehavior = AttachLazily);
+    void updateTextRenderer(unsigned offsetOfReplacedData, unsigned lengthOfReplacedData, RecalcStyleBehavior = DoNotRecalcStyle);
 
     virtual void attach(const AttachContext& = AttachContext()) OVERRIDE FINAL;
 
@@ -57,7 +57,7 @@
     virtual NodeType nodeType() const OVERRIDE;
 
 protected:
-    Text(TreeScope* treeScope, const String& data, ConstructionType type)
+    Text(TreeScope& treeScope, const String& data, ConstructionType type)
         : CharacterData(treeScope, data, type)
     {
         ScriptWrappable::init(this);
@@ -83,6 +83,12 @@
     return static_cast<Text*>(node);
 }
 
+inline const Text* toText(const Node* node)
+{
+    ASSERT_WITH_SECURITY_IMPLICATION(!node || node->isTextNode());
+    return static_cast<const Text*>(node);
+}
+
 } // namespace WebCore
 
 #endif // Text_h
diff --git a/Source/core/dom/TextLinkColors.cpp b/Source/core/dom/TextLinkColors.cpp
index a48f731..42b61c7 100644
--- a/Source/core/dom/TextLinkColors.cpp
+++ b/Source/core/dom/TextLinkColors.cpp
@@ -44,17 +44,17 @@
 
 void TextLinkColors::resetLinkColor()
 {
-    m_linkColor = StyleColor(0, 0, 238);
+    m_linkColor = Color(0, 0, 238);
 }
 
 void TextLinkColors::resetVisitedLinkColor()
 {
-    m_visitedLinkColor = StyleColor(85, 26, 139);
+    m_visitedLinkColor = Color(85, 26, 139);
 }
 
 void TextLinkColors::resetActiveLinkColor()
 {
-    m_activeLinkColor = StyleColor(255, 0, 0);
+    m_activeLinkColor.setNamedColor("red");
 }
 
 static Color colorForCSSValue(CSSValueID cssValueId)
@@ -94,10 +94,10 @@
     return RenderTheme::theme().systemColor(cssValueId);
 }
 
-StyleColor TextLinkColors::colorFromPrimitiveValue(const CSSPrimitiveValue* value, bool forVisitedLink) const
+Color TextLinkColors::colorFromPrimitiveValue(const CSSPrimitiveValue* value, Color currentColor, bool forVisitedLink) const
 {
     if (value->isRGBColor())
-        return StyleColor(value->getRGBA32Value());
+        return Color(value->getRGBA32Value());
 
     CSSValueID valueID = value->getValueID();
     switch (valueID) {
@@ -112,7 +112,7 @@
     case CSSValueWebkitFocusRingColor:
         return RenderTheme::focusRingColor();
     case CSSValueCurrentcolor:
-        return StyleColor::currentColor();
+        return currentColor;
     default:
         return colorForCSSValue(valueID);
     }
diff --git a/Source/core/dom/TextLinkColors.h b/Source/core/dom/TextLinkColors.h
index fb223e8..6d2728c 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/css/StyleColor.h"
+#include "core/platform/graphics/Color.h"
 #include "wtf/Noncopyable.h"
 
 namespace WebCore {
@@ -41,25 +41,25 @@
 public:
     TextLinkColors();
 
-    void setTextColor(const StyleColor& color) { m_textColor = color; }
-    StyleColor textColor() const { return m_textColor; }
+    void setTextColor(const Color& color) { m_textColor = color; }
+    Color textColor() const { return m_textColor; }
 
-    const StyleColor& linkColor() const { return m_linkColor; }
-    const StyleColor& visitedLinkColor() const { return m_visitedLinkColor; }
-    const StyleColor& activeLinkColor() const { return m_activeLinkColor; }
+    const Color& linkColor() const { return m_linkColor; }
+    const Color& visitedLinkColor() const { return m_visitedLinkColor; }
+    const Color& activeLinkColor() const { return m_activeLinkColor; }
     void setLinkColor(const Color& color) { m_linkColor = color; }
     void setVisitedLinkColor(const Color& color) { m_visitedLinkColor = color; }
     void setActiveLinkColor(const Color& color) { m_activeLinkColor = color; }
     void resetLinkColor();
     void resetVisitedLinkColor();
     void resetActiveLinkColor();
-    StyleColor colorFromPrimitiveValue(const CSSPrimitiveValue*, bool forVisitedLink = false) const;
+    Color colorFromPrimitiveValue(const CSSPrimitiveValue*, Color currentColor, bool forVisitedLink = false) const;
 private:
 
-    StyleColor m_textColor;
-    StyleColor m_linkColor;
-    StyleColor m_visitedLinkColor;
-    StyleColor m_activeLinkColor;
+    Color m_textColor;
+    Color m_linkColor;
+    Color m_visitedLinkColor;
+    Color m_activeLinkColor;
 };
 
 }
diff --git a/Source/core/dom/TreeScope.cpp b/Source/core/dom/TreeScope.cpp
index 2a4ae34..e20240f 100644
--- a/Source/core/dom/TreeScope.cpp
+++ b/Source/core/dom/TreeScope.cpp
@@ -170,7 +170,7 @@
 Node* TreeScope::ancestorInThisScope(Node* node) const
 {
     while (node) {
-        if (node->treeScope() == this)
+        if (&node->treeScope() == this)
             return node;
         if (!node->isInShadowTree())
             return 0;
@@ -209,7 +209,7 @@
         return 0;
     size_t hashPos = url.find('#');
     String name = (hashPos == notFound ? url : url.substring(hashPos + 1)).impl();
-    if (rootNode()->document()->isHTMLDocument())
+    if (rootNode()->document().isHTMLDocument())
         return toHTMLMapElement(m_imageMapsByName->getElementByLowercasedMapName(AtomicString(name.lower()).impl(), this));
     return toHTMLMapElement(m_imageMapsByName->getElementByMapName(AtomicString(name).impl(), this));
 }
@@ -242,7 +242,7 @@
 
 Element* TreeScope::elementFromPoint(int x, int y) const
 {
-    Node* node = nodeFromPoint(rootNode()->document(), x, y);
+    Node* node = nodeFromPoint(&rootNode()->document(), x, y);
     if (node && node->isTextNode())
         node = node->parentNode();
     ASSERT(!node || node->isElementNode() || node->isShadowRoot());
@@ -287,7 +287,7 @@
 
 DOMSelection* TreeScope::getSelection() const
 {
-    if (!rootNode()->document()->frame())
+    if (!rootNode()->document().frame())
         return 0;
 
     if (m_selection)
@@ -309,7 +309,7 @@
     for (Element* element = ElementTraversal::firstWithin(rootNode()); element; element = ElementTraversal::next(element)) {
         if (isHTMLAnchorElement(element)) {
             HTMLAnchorElement* anchor = toHTMLAnchorElement(element);
-            if (rootNode()->document()->inQuirksMode()) {
+            if (rootNode()->document().inQuirksMode()) {
                 // Quirks mode, case insensitive comparison of names.
                 if (equalIgnoringCase(anchor->name(), name))
                     return anchor;
@@ -350,10 +350,10 @@
 
 Element* TreeScope::adjustedFocusedElement()
 {
-    Document* document = rootNode()->document();
-    Element* element = document->focusedElement();
-    if (!element && document->page())
-        element = focusedFrameOwnerElement(document->page()->focusController().focusedFrame(), document->frame());
+    Document& document = rootNode()->document();
+    Element* element = document.focusedElement();
+    if (!element && document.page())
+        element = focusedFrameOwnerElement(document.page()->focusController().focusedFrame(), document.frame());
     if (!element)
         return 0;
     Vector<Node*> targetStack;
@@ -379,12 +379,9 @@
     return 0;
 }
 
-unsigned short TreeScope::comparePosition(const TreeScope* otherScope) const
+unsigned short TreeScope::comparePosition(const TreeScope& otherScope) const
 {
-    if (!otherScope)
-        return Node::DOCUMENT_POSITION_DISCONNECTED;
-
-    if (otherScope == this)
+    if (&otherScope == this)
         return Node::DOCUMENT_POSITION_EQUIVALENT;
 
     Vector<const TreeScope*, 16> chain1;
@@ -392,7 +389,7 @@
     const TreeScope* current;
     for (current = this; current; current = current->parentTreeScope())
         chain1.append(current);
-    for (current = otherScope; current; current = current->parentTreeScope())
+    for (current = &otherScope; current; current = current->parentTreeScope())
         chain2.append(current);
 
     unsigned index1 = chain1.size();
@@ -427,7 +424,7 @@
 static void listTreeScopes(Node* node, Vector<TreeScope*, 5>& treeScopes)
 {
     while (true) {
-        treeScopes.append(node->treeScope());
+        treeScopes.append(&node->treeScope());
         Element* ancestor = node->shadowHost();
         if (!ancestor)
             break;
@@ -440,8 +437,8 @@
     if (!nodeA || !nodeB)
         return 0;
 
-    if (nodeA->treeScope() == nodeB->treeScope())
-        return nodeA->treeScope();
+    if (&nodeA->treeScope() == &nodeB->treeScope())
+        return &nodeA->treeScope();
 
     Vector<TreeScope*, 5> treeScopesA;
     listTreeScopes(nodeA, treeScopesA);
@@ -477,11 +474,10 @@
     return 0;
 }
 
-bool TreeScope::isInclusiveAncestorOf(const TreeScope* scope) const
+bool TreeScope::isInclusiveAncestorOf(const TreeScope& scope) const
 {
-    ASSERT(scope);
-    for (; scope; scope = scope->parentTreeScope()) {
-        if (scope == this)
+    for (const TreeScope* current = &scope; current; current = current->parentTreeScope()) {
+        if (current == this)
             return true;
     }
     return false;
diff --git a/Source/core/dom/TreeScope.h b/Source/core/dom/TreeScope.h
index 9f2d412..ecfc830 100644
--- a/Source/core/dom/TreeScope.h
+++ b/Source/core/dom/TreeScope.h
@@ -124,8 +124,8 @@
 
     void removedLastRefToScope();
 
-    bool isInclusiveAncestorOf(const TreeScope*) const;
-    unsigned short comparePosition(const TreeScope*) const;
+    bool isInclusiveAncestorOf(const TreeScope&) const;
+    unsigned short comparePosition(const TreeScope&) const;
 
     Element* getElementByAccessKey(const String& key) const;
 
diff --git a/Source/core/dom/TreeScopeAdopter.cpp b/Source/core/dom/TreeScopeAdopter.cpp
index 0c3387c..be8670b 100644
--- a/Source/core/dom/TreeScopeAdopter.cpp
+++ b/Source/core/dom/TreeScopeAdopter.cpp
@@ -104,7 +104,7 @@
 inline void TreeScopeAdopter::updateTreeScope(Node* node) const
 {
     ASSERT(!node->isTreeScope());
-    ASSERT(node->treeScope() == m_oldScope);
+    ASSERT(&node->treeScope() == m_oldScope);
     m_newScope->guardRef();
     m_oldScope->guardDeref();
     node->setTreeScope(m_newScope);
diff --git a/Source/core/dom/TreeScopeAdopter.h b/Source/core/dom/TreeScopeAdopter.h
index a629e9d..4ad9760 100644
--- a/Source/core/dom/TreeScopeAdopter.h
+++ b/Source/core/dom/TreeScopeAdopter.h
@@ -55,10 +55,11 @@
     TreeScope* m_oldScope;
 };
 
+// FIXME: Should take |TreeScope&| instead of |TreeScope*|.
 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/TreeWalker.cpp b/Source/core/dom/TreeWalker.cpp
index bc0b775..bec5c19 100644
--- a/Source/core/dom/TreeWalker.cpp
+++ b/Source/core/dom/TreeWalker.cpp
@@ -25,6 +25,7 @@
 #include "config.h"
 #include "core/dom/TreeWalker.h"
 
+#include "bindings/v8/ExceptionMessages.h"
 #include "bindings/v8/ExceptionState.h"
 #include "bindings/v8/ScriptState.h"
 #include "core/dom/ContainerNode.h"
@@ -45,7 +46,7 @@
 void TreeWalker::setCurrentNode(PassRefPtr<Node> node, ExceptionState& es)
 {
     if (!node) {
-        es.throwDOMException(NotSupportedError);
+        es.throwDOMException(NotSupportedError, ExceptionMessages::failedToExecute("setCurrentNode", "TreeWalker", "The Node provided is invalid."));
         return;
     }
     m_current = node;
diff --git a/Source/core/dom/ViewportArguments.cpp b/Source/core/dom/ViewportArguments.cpp
index 0a2708d..48d56e4 100644
--- a/Source/core/dom/ViewportArguments.cpp
+++ b/Source/core/dom/ViewportArguments.cpp
@@ -29,6 +29,8 @@
 #include "core/dom/ViewportArguments.h"
 
 #include "core/dom/Document.h"
+#include "core/page/Page.h"
+#include "core/page/Settings.h"
 #include "wtf/text/WTFString.h"
 
 using namespace std;
@@ -48,9 +50,6 @@
 
 static inline float clampLengthValue(float value)
 {
-    ASSERT(value != ViewportArguments::ValueDeviceWidth);
-    ASSERT(value != ViewportArguments::ValueDeviceHeight);
-
     // Limits as defined in the css-device-adapt spec.
     if (value != ViewportArguments::ValueAuto)
         return min(float(10000), max(value, float(1)));
@@ -59,203 +58,142 @@
 
 static inline float clampScaleValue(float value)
 {
-    ASSERT(value != ViewportArguments::ValueDeviceWidth);
-    ASSERT(value != ViewportArguments::ValueDeviceHeight);
-
     // Limits as defined in the css-device-adapt spec.
     if (value != ViewportArguments::ValueAuto)
         return min(float(10), max(value, float(0.1)));
     return value;
 }
 
-PageScaleConstraints ViewportArguments::resolve(const FloatSize& initialViewportSize, int defaultWidth) const
+float ViewportArguments::resolveViewportLength(const Length& length, const FloatSize& initialViewportSize, Direction direction)
 {
-    float resultWidth = width;
-    float resultMaxWidth = maxWidth;
-    float resultMinWidth = minWidth;
-    float resultHeight = height;
-    float resultMinHeight = minHeight;
-    float resultMaxHeight = maxHeight;
+    if (length.isAuto())
+        return ViewportArguments::ValueAuto;
+
+    if (length.isFixed())
+        return length.getFloatValue();
+
+    if (length.type() == ExtendToZoom)
+        return ViewportArguments::ValueExtendToZoom;
+
+    if ((length.type() == Percent && direction == Horizontal) || length.type() == ViewportPercentageWidth)
+        return initialViewportSize.width() * length.getFloatValue() / 100.0f;
+
+    if ((length.type() == Percent && direction == Vertical) || length.type() == ViewportPercentageHeight)
+        return initialViewportSize.height() * length.getFloatValue() / 100.0f;
+
+    if (length.type() == ViewportPercentageMin)
+        return min(initialViewportSize.width(), initialViewportSize.height()) * length.viewportPercentageLength() / 100.0f;
+
+    if (length.type() == ViewportPercentageMax)
+        return max(initialViewportSize.width(), initialViewportSize.height()) * length.viewportPercentageLength() / 100.0f;
+
+    ASSERT_NOT_REACHED();
+    return ViewportArguments::ValueAuto;
+}
+
+PageScaleConstraints ViewportArguments::resolve(const FloatSize& initialViewportSize) const
+{
+    float resultWidth = ValueAuto;
+    float resultMaxWidth = resolveViewportLength(maxWidth, initialViewportSize, Horizontal);
+    float resultMinWidth = resolveViewportLength(minWidth, initialViewportSize, Horizontal);
+    float resultHeight = ValueAuto;
+    float resultMaxHeight = resolveViewportLength(maxHeight, initialViewportSize, Vertical);
+    float resultMinHeight = resolveViewportLength(minHeight, initialViewportSize, Vertical);
 
     float resultZoom = zoom;
     float resultMinZoom = minZoom;
     float resultMaxZoom = maxZoom;
     float resultUserZoom = userZoom;
 
-    if (type == ViewportArguments::CSSDeviceAdaptation) {
+    // 1. Resolve min-zoom and max-zoom values.
+    if (resultMinZoom != ViewportArguments::ValueAuto && resultMaxZoom != ViewportArguments::ValueAuto)
+        resultMaxZoom = max(resultMinZoom, resultMaxZoom);
 
-        // device-width/device-height not supported for @viewport.
-        ASSERT(resultMinWidth != ViewportArguments::ValueDeviceWidth);
-        ASSERT(resultMinWidth != ViewportArguments::ValueDeviceHeight);
-        ASSERT(resultMaxWidth != ViewportArguments::ValueDeviceWidth);
-        ASSERT(resultMaxWidth != ViewportArguments::ValueDeviceHeight);
-        ASSERT(resultMinHeight != ViewportArguments::ValueDeviceWidth);
-        ASSERT(resultMinHeight != ViewportArguments::ValueDeviceHeight);
-        ASSERT(resultMaxHeight != ViewportArguments::ValueDeviceWidth);
-        ASSERT(resultMaxHeight != ViewportArguments::ValueDeviceHeight);
+    // 2. Constrain zoom value to the [min-zoom, max-zoom] range.
+    if (resultZoom != ViewportArguments::ValueAuto)
+        resultZoom = compareIgnoringAuto(resultMinZoom, compareIgnoringAuto(resultMaxZoom, resultZoom, min), max);
 
-        // 1. Resolve min-zoom and max-zoom values.
-        if (resultMinZoom != ViewportArguments::ValueAuto && resultMaxZoom != ViewportArguments::ValueAuto)
-            resultMaxZoom = max(resultMinZoom, resultMaxZoom);
+    float extendZoom = compareIgnoringAuto(resultZoom, resultMaxZoom, min);
 
-        // 2. Constrain zoom value to the [min-zoom, max-zoom] range.
-        if (resultZoom != ViewportArguments::ValueAuto)
-            resultZoom = compareIgnoringAuto(resultMinZoom, compareIgnoringAuto(resultMaxZoom, resultZoom, min), max);
+    // 3. Resolve non-"auto" lengths to pixel lengths.
+    if (extendZoom == ViewportArguments::ValueAuto) {
+        if (resultMaxWidth == ViewportArguments::ValueExtendToZoom)
+            resultMaxWidth = ViewportArguments::ValueAuto;
 
-        float extendZoom = compareIgnoringAuto(resultZoom, resultMaxZoom, min);
+        if (resultMaxHeight == ViewportArguments::ValueExtendToZoom)
+            resultMaxHeight = ViewportArguments::ValueAuto;
 
-        if (extendZoom == ViewportArguments::ValueAuto) {
-            if (resultMaxWidth == ViewportArguments::ValueExtendToZoom)
-                resultMaxWidth = ViewportArguments::ValueAuto;
+        if (resultMinWidth == ViewportArguments::ValueExtendToZoom)
+            resultMinWidth = resultMaxWidth;
 
-            if (resultMaxHeight == ViewportArguments::ValueExtendToZoom)
-                resultMaxHeight = ViewportArguments::ValueAuto;
+        if (resultMinHeight == ViewportArguments::ValueExtendToZoom)
+            resultMinHeight = resultMaxHeight;
+    } else {
+        float extendWidth = initialViewportSize.width() / extendZoom;
+        float extendHeight = initialViewportSize.height() / extendZoom;
 
-            if (resultMinWidth == ViewportArguments::ValueExtendToZoom)
-                resultMinWidth = resultMaxWidth;
+        if (resultMaxWidth == ViewportArguments::ValueExtendToZoom)
+            resultMaxWidth = extendWidth;
 
-            if (resultMinHeight == ViewportArguments::ValueExtendToZoom)
-                resultMinHeight = resultMaxHeight;
-        } else {
-            float extendWidth = initialViewportSize.width() / extendZoom;
-            float extendHeight = initialViewportSize.height() / extendZoom;
+        if (resultMaxHeight == ViewportArguments::ValueExtendToZoom)
+            resultMaxHeight = extendHeight;
 
-            if (resultMaxWidth == ViewportArguments::ValueExtendToZoom)
-                resultMaxWidth = extendWidth;
+        if (resultMinWidth == ViewportArguments::ValueExtendToZoom)
+            resultMinWidth = compareIgnoringAuto(extendWidth, resultMaxWidth, max);
 
-            if (resultMaxHeight == ViewportArguments::ValueExtendToZoom)
-                resultMaxHeight = extendHeight;
-
-            if (resultMinWidth == ViewportArguments::ValueExtendToZoom)
-                resultMinWidth = compareIgnoringAuto(extendWidth, resultMaxWidth, max);
-
-            if (resultMinHeight == ViewportArguments::ValueExtendToZoom)
-                resultMinHeight = compareIgnoringAuto(extendHeight, resultMaxHeight, max);
-        }
-
-        // 4. Resolve initial width from min/max descriptors.
-        if (resultMinWidth != ViewportArguments::ValueAuto || resultMaxWidth != ViewportArguments::ValueAuto)
-            resultWidth = compareIgnoringAuto(resultMinWidth, compareIgnoringAuto(resultMaxWidth, initialViewportSize.width(), min), max);
-
-        // 5. Resolve initial height from min/max descriptors.
-        if (resultMinHeight != ViewportArguments::ValueAuto || resultMaxHeight != ViewportArguments::ValueAuto)
-            resultHeight = compareIgnoringAuto(resultMinHeight, compareIgnoringAuto(resultMaxHeight, initialViewportSize.height(), min), max);
-
-        // 6-7. Resolve width value.
-        if (resultWidth == ViewportArguments::ValueAuto) {
-            if (resultHeight == ViewportArguments::ValueAuto || !initialViewportSize .height())
-                resultWidth = initialViewportSize.width();
-            else
-                resultWidth = resultHeight * (initialViewportSize.width() / initialViewportSize.height());
-        }
-
-        // 8. Resolve height value.
-        if (resultHeight == ViewportArguments::ValueAuto) {
-            if (!initialViewportSize.width())
-                resultHeight = initialViewportSize.height();
-            else
-                resultHeight = resultWidth * initialViewportSize.height() / initialViewportSize.width();
-        }
-
-        PageScaleConstraints result;
-        result.minimumScale = resultMinZoom;
-        result.maximumScale = resultMaxZoom;
-        result.initialScale = resultZoom;
-        result.layoutSize.setWidth(resultWidth);
-        result.layoutSize.setHeight(resultHeight);
-        return result;
+        if (resultMinHeight == ViewportArguments::ValueExtendToZoom)
+            resultMinHeight = compareIgnoringAuto(extendHeight, resultMaxHeight, max);
     }
 
-    switch (static_cast<int>(resultWidth)) {
-    case ViewportArguments::ValueDeviceWidth:
-        resultWidth = initialViewportSize.width();
-        break;
-    case ViewportArguments::ValueDeviceHeight:
-        resultWidth = initialViewportSize.height();
-        break;
+    // 4. Resolve initial width from min/max descriptors.
+    if (resultMinWidth != ViewportArguments::ValueAuto || resultMaxWidth != ViewportArguments::ValueAuto)
+        resultWidth = compareIgnoringAuto(resultMinWidth, compareIgnoringAuto(resultMaxWidth, initialViewportSize.width(), min), max);
+
+    // 5. Resolve initial height from min/max descriptors.
+    if (resultMinHeight != ViewportArguments::ValueAuto || resultMaxHeight != ViewportArguments::ValueAuto)
+        resultHeight = compareIgnoringAuto(resultMinHeight, compareIgnoringAuto(resultMaxHeight, initialViewportSize.height(), min), max);
+
+    // 6-7. Resolve width value.
+    if (resultWidth == ViewportArguments::ValueAuto) {
+        if (resultHeight == ViewportArguments::ValueAuto || !initialViewportSize.height())
+            resultWidth = initialViewportSize.width();
+        else
+            resultWidth = resultHeight * (initialViewportSize.width() / initialViewportSize.height());
     }
 
-    switch (static_cast<int>(resultHeight)) {
-    case ViewportArguments::ValueDeviceWidth:
-        resultHeight = initialViewportSize.width();
-        break;
-    case ViewportArguments::ValueDeviceHeight:
-        resultHeight = initialViewportSize.height();
-        break;
+    // 8. Resolve height value.
+    if (resultHeight == ViewportArguments::ValueAuto) {
+        if (!initialViewportSize.width())
+            resultHeight = initialViewportSize.height();
+        else
+            resultHeight = resultWidth * initialViewportSize.height() / initialViewportSize.width();
     }
 
-    if (type != ViewportArguments::Implicit) {
-        // Clamp values to a valid range, but not for @viewport since is
-        // not mandated by the specification.
-        resultWidth = clampLengthValue(resultWidth);
-        resultHeight = clampLengthValue(resultHeight);
-        resultZoom = clampScaleValue(resultZoom);
-        resultMinZoom = clampScaleValue(resultMinZoom);
-        resultMaxZoom = clampScaleValue(resultMaxZoom);
-    }
-
-    PageScaleConstraints result;
-
-    // Resolve minimum-scale and maximum-scale values according to spec.
-    if (resultMinZoom == ViewportArguments::ValueAuto)
-        result.minimumScale = float(0.25);
-    else
-        result.minimumScale = resultMinZoom;
-
-    if (resultMaxZoom == ViewportArguments::ValueAuto) {
-        result.maximumScale = float(5.0);
-        result.minimumScale = min(float(5.0), result.minimumScale);
-    } else
-        result.maximumScale = resultMaxZoom;
-    result.maximumScale = max(result.minimumScale, result.maximumScale);
-
     // Resolve initial-scale value.
-    result.initialScale = resultZoom;
     if (resultZoom == ViewportArguments::ValueAuto) {
-        result.initialScale = initialViewportSize.width() / defaultWidth;
         if (resultWidth != ViewportArguments::ValueAuto && resultWidth > 0)
-            result.initialScale = initialViewportSize.width() / resultWidth;
+            resultZoom = initialViewportSize.width() / resultWidth;
         if (resultHeight != ViewportArguments::ValueAuto && resultHeight > 0) {
             // if 'auto', the initial-scale will be negative here and thus ignored.
-            result.initialScale = max<float>(result.initialScale, initialViewportSize.height() / resultHeight);
+            resultZoom = max<float>(resultZoom, initialViewportSize.height() / resultHeight);
         }
     }
 
-    // Constrain initial-scale value to minimum-scale/maximum-scale range.
-    result.initialScale = min(result.maximumScale, max(result.minimumScale, result.initialScale));
-
-    // Resolve width value.
-    if (resultWidth == ViewportArguments::ValueAuto) {
-        if (resultZoom == ViewportArguments::ValueAuto)
-            resultWidth = defaultWidth;
-        else if (resultHeight != ViewportArguments::ValueAuto)
-            resultWidth = resultHeight * (initialViewportSize.width() / initialViewportSize.height());
-        else
-            resultWidth = initialViewportSize.width() / result.initialScale;
-    }
-
-    // Resolve height value.
-    if (resultHeight == ViewportArguments::ValueAuto)
-        resultHeight = resultWidth * (initialViewportSize.height() / initialViewportSize.width());
-
-    if (type == ViewportArguments::ViewportMeta) {
-        // Extend width and height to fill the visual viewport for the resolved initial-scale.
-        resultWidth = max<float>(resultWidth, initialViewportSize.width() / result.initialScale);
-        resultHeight = max<float>(resultHeight, initialViewportSize.height() / result.initialScale);
-    }
-
-    result.layoutSize.setWidth(resultWidth);
-    result.layoutSize.setHeight(resultHeight);
-
     // If user-scalable = no, lock the min/max scale to the computed initial
     // scale.
     if (!resultUserZoom)
-        result.maximumScale = result.minimumScale = result.initialScale;
+        resultMinZoom = resultMaxZoom = resultZoom;
 
     // Only set initialScale to a value if it was explicitly set.
-    if (resultZoom == ViewportArguments::ValueAuto)
-        result.initialScale = ViewportArguments::ValueAuto;
+    if (zoom == ViewportArguments::ValueAuto)
+        resultZoom = ViewportArguments::ValueAuto;
 
+    PageScaleConstraints result;
+    result.minimumScale = resultMinZoom;
+    result.maximumScale = resultMaxZoom;
+    result.initialScale = resultZoom;
+    result.layoutSize.setWidth(resultWidth);
+    result.layoutSize.setHeight(resultHeight);
     return result;
 }
 
@@ -280,7 +218,7 @@
     return value;
 }
 
-static float findSizeValue(const String& keyString, const String& valueString, Document* document)
+static Length findSizeValue(const String& keyString, const String& valueString, Document* document)
 {
     // 1) Non-negative number values are translated to px lengths.
     // 2) Negative number values are translated to auto.
@@ -288,16 +226,23 @@
     // 4) Other keywords and unknown values translate to 0.0.
 
     if (equalIgnoringCase(valueString, "device-width"))
-        return ViewportArguments::ValueDeviceWidth;
+        return Length(100, ViewportPercentageWidth);
     if (equalIgnoringCase(valueString, "device-height"))
-        return ViewportArguments::ValueDeviceHeight;
+        return Length(100, ViewportPercentageHeight);
 
     float value = numericPrefix(keyString, valueString, document);
 
     if (value < 0)
-        return ViewportArguments::ValueAuto;
+        return Length(); // auto
 
-    return value;
+    if (!static_cast<int>(value) && document->page() && document->page()->settings().viewportMetaZeroValuesQuirk()) {
+        if (keyString == "width")
+            return Length(100, ViewportPercentageWidth);
+        if (keyString == "height")
+            return Length(100, ViewportPercentageHeight);
+    }
+
+    return Length(clampLengthValue(value), Fixed);
 }
 
 static float findScaleValue(const String& keyString, const String& valueString, Document* document)
@@ -325,7 +270,10 @@
     if (value > 10.0)
         reportViewportWarning(document, MaximumScaleTooLargeError, String(), String());
 
-    return value;
+    if (!static_cast<int>(value) && document->page() && document->page()->settings().viewportMetaZeroValuesQuirk() && (keyString == "minimum-scale" || keyString == "maximum-scale"))
+        return ViewportArguments::ValueAuto;
+
+    return clampScaleValue(value);
 }
 
 static float findUserScalableValue(const String& keyString, const String& valueString, Document* document)
@@ -374,29 +322,37 @@
 {
     ViewportArguments* arguments = static_cast<ViewportArguments*>(data);
 
-    if (keyString == "width")
-        arguments->width = findSizeValue(keyString, valueString, document);
-    else if (keyString == "height")
-        arguments->height = findSizeValue(keyString, valueString, document);
-    else if (keyString == "initial-scale")
+    if (keyString == "width") {
+        const Length& width = findSizeValue(keyString, valueString, document);
+        if (!width.isAuto()) {
+            arguments->minWidth = Length(ExtendToZoom);
+            arguments->maxWidth = width;
+        }
+    } else if (keyString == "height") {
+        const Length& height = findSizeValue(keyString, valueString, document);
+        if (!height.isAuto()) {
+            arguments->minHeight = Length(ExtendToZoom);
+            arguments->maxHeight = height;
+        }
+    } else if (keyString == "initial-scale") {
         arguments->zoom = findScaleValue(keyString, valueString, document);
-    else if (keyString == "minimum-scale")
+    } else if (keyString == "minimum-scale") {
         arguments->minZoom = findScaleValue(keyString, valueString, document);
-    else if (keyString == "maximum-scale")
+    } else if (keyString == "maximum-scale") {
         arguments->maxZoom = findScaleValue(keyString, valueString, document);
-    else if (keyString == "user-scalable")
+    } else if (keyString == "user-scalable") {
         arguments->userZoom = findUserScalableValue(keyString, valueString, document);
-    else if (keyString == "target-densitydpi") {
+    } else if (keyString == "target-densitydpi") {
         arguments->deprecatedTargetDensityDPI = findTargetDensityDPIValue(keyString, valueString, document);
         reportViewportWarning(document, TargetDensityDpiUnsupported, String(), String());
-    } else
+    } else {
         reportViewportWarning(document, UnrecognizedViewportArgumentKeyError, keyString, String());
+    }
 }
 
 static const char* viewportErrorMessageTemplate(ViewportErrorCode errorCode)
 {
     static const char* const errors[] = {
-        "Note that ';' is not a key-value pair separator. The list should be comma-separated.",
         "The key \"%replacement1\" is not recognized and ignored.",
         "The value \"%replacement1\" for key \"%replacement2\" is invalid, and has been ignored.",
         "The value \"%replacement1\" for key \"%replacement2\" was truncated to its numeric prefix.",
@@ -410,7 +366,6 @@
 static MessageLevel viewportErrorMessageLevel(ViewportErrorCode errorCode)
 {
     switch (errorCode) {
-    case InvalidKeyValuePairSeparatorError:
     case TruncatedViewportArgumentValueError:
     case TargetDensityDpiUnsupported:
         return WarningMessageLevel;
diff --git a/Source/core/dom/ViewportArguments.h b/Source/core/dom/ViewportArguments.h
index 6533441..e0722b8 100644
--- a/Source/core/dom/ViewportArguments.h
+++ b/Source/core/dom/ViewportArguments.h
@@ -29,6 +29,7 @@
 #define ViewportArguments_h
 
 #include "core/page/PageScaleConstraints.h"
+#include "core/platform/Length.h"
 #include "core/platform/graphics/FloatSize.h"
 #include "wtf/Forward.h"
 
@@ -37,7 +38,6 @@
 class Document;
 
 enum ViewportErrorCode {
-    InvalidKeyValuePairSeparatorError,
     UnrecognizedViewportArgumentKeyError,
     UnrecognizedViewportArgumentValueError,
     TruncatedViewportArgumentValueError,
@@ -49,12 +49,11 @@
 
     enum Type {
         // These are ordered in increasing importance.
-        Implicit,
-        XHTMLMobileProfile,
+        UserAgentStyleSheet,
         HandheldFriendlyMeta,
         MobileOptimizedMeta,
         ViewportMeta,
-        CSSDeviceAdaptation
+        AuthorStyleSheet
     } type;
 
     enum {
@@ -70,14 +69,8 @@
         ValueExtendToZoom = -10
     };
 
-    ViewportArguments(Type type = Implicit)
+    ViewportArguments(Type type = UserAgentStyleSheet)
         : type(type)
-        , width(ValueAuto)
-        , minWidth(ValueAuto)
-        , maxWidth(ValueAuto)
-        , height(ValueAuto)
-        , minHeight(ValueAuto)
-        , maxHeight(ValueAuto)
         , zoom(ValueAuto)
         , minZoom(ValueAuto)
         , maxZoom(ValueAuto)
@@ -88,14 +81,12 @@
     }
 
     // All arguments are in CSS units.
-    PageScaleConstraints resolve(const FloatSize& initialViewportSize, int defaultWidth) const;
+    PageScaleConstraints resolve(const FloatSize& initialViewportSize) const;
 
-    float width;
-    float minWidth;
-    float maxWidth;
-    float height;
-    float minHeight;
-    float maxHeight;
+    Length minWidth;
+    Length maxWidth;
+    Length minHeight;
+    Length maxHeight;
     float zoom;
     float minZoom;
     float maxZoom;
@@ -107,10 +98,8 @@
     {
         // Used for figuring out whether to reset the viewport or not,
         // thus we are not taking type into account.
-        return width == other.width
-            && minWidth == other.minWidth
+        return minWidth == other.minWidth
             && maxWidth == other.maxWidth
-            && height == other.height
             && minHeight == other.minHeight
             && maxHeight == other.maxHeight
             && zoom == other.zoom
@@ -125,6 +114,12 @@
     {
         return !(*this == other);
     }
+
+    bool isLegacyViewportType() const { return type >= HandheldFriendlyMeta && type <= ViewportMeta; }
+
+private:
+    enum Direction { Horizontal, Vertical };
+    static float resolveViewportLength(const Length&, const FloatSize& initialViewportSize, Direction);
 };
 
 void setViewportFeature(const String& keyString, const String& valueString, Document*, void* data);
diff --git a/Source/core/dom/WebKitNamedFlow.idl b/Source/core/dom/WebKitNamedFlow.idl
index a8f68dd..33cff65 100644
--- a/Source/core/dom/WebKitNamedFlow.idl
+++ b/Source/core/dom/WebKitNamedFlow.idl
@@ -29,7 +29,7 @@
 
 [
     NoInterfaceObject,
-    EnabledAtRuntime=cssRegions,
+    EnabledAtRuntime=CSSRegions,
     ImplementedAs=NamedFlow,
     GenerateIsReachable=ownerNode
 ] interface WebKitNamedFlow : EventTarget {
diff --git a/Source/core/dom/WebKitNamedFlowCollection.idl b/Source/core/dom/WebKitNamedFlowCollection.idl
index 65aa56d..92aec8e 100644
--- a/Source/core/dom/WebKitNamedFlowCollection.idl
+++ b/Source/core/dom/WebKitNamedFlowCollection.idl
@@ -29,7 +29,7 @@
 
 [
     NoInterfaceObject,
-    EnabledAtRuntime=cssRegions,
+    EnabledAtRuntime=CSSRegions,
     ImplementedAs=DOMNamedFlowCollection
 ] interface WebKitNamedFlowCollection {
     readonly attribute unsigned long length;
diff --git a/Source/core/dom/WheelController.cpp b/Source/core/dom/WheelController.cpp
new file mode 100644
index 0000000..48c14a7
--- /dev/null
+++ b/Source/core/dom/WheelController.cpp
@@ -0,0 +1,121 @@
+/*
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/dom/WheelController.h"
+
+#include "core/dom/Document.h"
+#include "core/dom/EventNames.h"
+#include "core/dom/WheelEvent.h"
+#include "core/page/Frame.h"
+#include "core/page/Page.h"
+#include "core/page/scrolling/ScrollingCoordinator.h"
+
+namespace WebCore {
+
+WheelController::WheelController(Document* document)
+    : DOMWindowLifecycleObserver(document->domWindow())
+    , m_wheelEventHandlerCount(0)
+{
+}
+
+WheelController::~WheelController()
+{
+}
+
+const char* WheelController::supplementName()
+{
+    return "WheelController";
+}
+
+WheelController* WheelController::from(Document* document)
+{
+    WheelController* controller = static_cast<WheelController*>(Supplement<ScriptExecutionContext>::from(document, supplementName()));
+    if (!controller) {
+        controller = new WheelController(document);
+        Supplement<ScriptExecutionContext>::provideTo(document, supplementName(), adoptPtr(controller));
+    }
+    return controller;
+}
+
+static void wheelEventHandlerCountChanged(Document* document)
+{
+    Page* page = document->page();
+    if (!page)
+        return;
+
+    ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator();
+    if (!scrollingCoordinator)
+        return;
+
+    FrameView* frameView = document->view();
+    if (!frameView)
+        return;
+
+    scrollingCoordinator->frameViewWheelEventHandlerCountChanged(frameView);
+}
+
+void WheelController::didAddWheelEventHandler(Document* document)
+{
+    ++m_wheelEventHandlerCount;
+    Page* page = document->page();
+    Frame* mainFrame = page ? page->mainFrame() : 0;
+    if (mainFrame)
+        mainFrame->notifyChromeClientWheelEventHandlerCountChanged();
+
+    wheelEventHandlerCountChanged(document);
+}
+
+void WheelController::didRemoveWheelEventHandler(Document* document)
+{
+    ASSERT(m_wheelEventHandlerCount > 0);
+    --m_wheelEventHandlerCount;
+    Page* page = document->page();
+    Frame* mainFrame = page ? page->mainFrame() : 0;
+    if (mainFrame)
+        mainFrame->notifyChromeClientWheelEventHandlerCountChanged();
+
+    wheelEventHandlerCountChanged(document);
+}
+
+void WheelController::didAddEventListener(DOMWindow* window, const AtomicString& eventType)
+{
+    if (eventType != eventNames().wheelEvent && eventType != eventNames().mousewheelEvent)
+        return;
+
+    Document* document = window->document();
+    didAddWheelEventHandler(document);
+}
+
+void WheelController::didRemoveEventListener(DOMWindow* window, const AtomicString& eventType)
+{
+    if (eventType != eventNames().wheelEvent && eventType != eventNames().mousewheelEvent)
+        return;
+
+    Document* document = window->document();
+    didRemoveWheelEventHandler(document);
+}
+
+} // namespace WebCore
diff --git a/Source/core/dom/WheelController.h b/Source/core/dom/WheelController.h
new file mode 100644
index 0000000..13406ee
--- /dev/null
+++ b/Source/core/dom/WheelController.h
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WheelController_h
+#define WheelController_h
+
+#include "core/dom/Event.h"
+#include "core/page/DOMWindowLifecycleObserver.h"
+#include "core/platform/Supplementable.h"
+
+namespace WebCore {
+
+class DOMWindow;
+
+class WheelController : public Supplement<ScriptExecutionContext>, public DOMWindowLifecycleObserver {
+
+public:
+    virtual ~WheelController();
+
+    static const char* supplementName();
+    static WheelController* from(Document*);
+
+    unsigned wheelEventHandlerCount() { return m_wheelEventHandlerCount; }
+
+    void didAddWheelEventHandler(Document*);
+    void didRemoveWheelEventHandler(Document*);
+
+    // Inherited from DOMWindowLifecycleObserver
+    virtual void didAddEventListener(DOMWindow*, const AtomicString&) OVERRIDE;
+    virtual void didRemoveEventListener(DOMWindow*, const AtomicString&) OVERRIDE;
+
+private:
+    explicit WheelController(Document*);
+
+    unsigned m_wheelEventHandlerCount;
+};
+
+} // namespace WebCore
+
+#endif // WheelController_h
diff --git a/Source/core/dom/shadow/ComposedTreeWalker.cpp b/Source/core/dom/shadow/ComposedTreeWalker.cpp
index 86f97ed..1e19ddc 100644
--- a/Source/core/dom/shadow/ComposedTreeWalker.cpp
+++ b/Source/core/dom/shadow/ComposedTreeWalker.cpp
@@ -60,14 +60,9 @@
 Node* ComposedTreeWalker::traverseChild(const Node* node, TraversalDirection direction) const
 {
     ASSERT(node);
-    if (canCrossUpperBoundary()) {
-        ElementShadow* shadow = shadowFor(node);
-        return shadow ? traverseLightChildren(shadow->youngestShadowRoot(), direction)
+    ElementShadow* shadow = shadowFor(node);
+    return shadow ? traverseLightChildren(shadow->youngestShadowRoot(), direction)
             : traverseLightChildren(node, direction);
-    }
-    if (isShadowHost(node))
-        return 0;
-    return traverseLightChildren(node, direction);
 }
 
 Node* ComposedTreeWalker::traverseLightChildren(const Node* node, TraversalDirection direction)
@@ -170,11 +165,6 @@
     if (node->isPseudoElement())
         return node->parentOrShadowHostNode();
 
-    if (!canCrossUpperBoundary() && node->isShadowRoot()) {
-        ASSERT(toShadowRoot(node)->isYoungest());
-        return 0;
-    }
-
     if (nodeCanBeDistributed(node)) {
         if (InsertionPoint* insertionPoint = resolveReprojection(node)) {
             if (details)
@@ -202,13 +192,9 @@
     ASSERT(!shadowRoot->insertionPoint());
 
     if (shadowRoot->isYoungest()) {
-        if (canCrossUpperBoundary()) {
-            if (details)
-                details->didTraverseShadowRoot(shadowRoot);
-            return shadowRoot->host();
-        }
-
-        return const_cast<ShadowRoot*>(shadowRoot);
+        if (details)
+            details->didTraverseShadowRoot(shadowRoot);
+        return shadowRoot->host();
     }
 
     return 0;
diff --git a/Source/core/dom/shadow/ComposedTreeWalker.h b/Source/core/dom/shadow/ComposedTreeWalker.h
index a75ac9e..2fb9cf3 100644
--- a/Source/core/dom/shadow/ComposedTreeWalker.h
+++ b/Source/core/dom/shadow/ComposedTreeWalker.h
@@ -42,17 +42,12 @@
 public:
     typedef NodeRenderingTraversal::ParentDetails ParentTraversalDetails;
 
-    enum Policy {
-        CrossUpperBoundary,
-        DoNotCrossUpperBoundary,
-    };
-
     enum StartPolicy {
         CanStartFromShadowBoundary,
         CannotStartFromShadowBoundary
     };
 
-    ComposedTreeWalker(const Node*, Policy = CrossUpperBoundary, StartPolicy = CannotStartFromShadowBoundary);
+    ComposedTreeWalker(const Node*, StartPolicy = CannotStartFromShadowBoundary);
 
     Node* get() const { return const_cast<Node*>(m_node); }
 
@@ -77,16 +72,11 @@
         TraversalDirectionBackward
     };
 
-    bool canCrossUpperBoundary() const { return m_policy == CrossUpperBoundary; }
-
     void assertPrecondition() const
     {
 #ifndef NDEBUG
         ASSERT(m_node);
-        if (canCrossUpperBoundary())
-            ASSERT(!m_node->isShadowRoot());
-        else
-            ASSERT(!m_node->isShadowRoot() || toShadowRoot(m_node)->isYoungest());
+        ASSERT(!m_node->isShadowRoot());
         ASSERT(!isActiveInsertionPoint(m_node));
 #endif
     }
@@ -123,12 +113,10 @@
     Node* traverseParentBackToYoungerShadowRootOrHost(const ShadowRoot*, ParentTraversalDetails* = 0) const;
 
     const Node* m_node;
-    Policy m_policy;
 };
 
-inline ComposedTreeWalker::ComposedTreeWalker(const Node* node, Policy policy, StartPolicy startPolicy)
+inline ComposedTreeWalker::ComposedTreeWalker(const Node* node, StartPolicy startPolicy)
     : m_node(node)
-    , m_policy(policy)
 {
     UNUSED_PARAM(startPolicy);
 #ifndef NDEBUG
diff --git a/Source/core/dom/shadow/ElementShadow.cpp b/Source/core/dom/shadow/ElementShadow.cpp
index 1224962..455ad32 100644
--- a/Source/core/dom/shadow/ElementShadow.cpp
+++ b/Source/core/dom/shadow/ElementShadow.cpp
@@ -57,10 +57,10 @@
 
 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->setParentTreeScope(&shadowHost->treeScope());
     m_shadowRoots.push(shadowRoot.get());
     ChildNodeInsertionNotifier(shadowHost).notify(shadowRoot.get());
     setNeedsDistributionRecalc();
@@ -70,6 +70,7 @@
     // 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());
 
     return shadowRoot.get();
@@ -82,14 +83,14 @@
 
     while (RefPtr<ShadowRoot> oldRoot = m_shadowRoots.head()) {
         InspectorInstrumentation::willPopShadowRoot(shadowHost, oldRoot.get());
-        shadowHost->document()->removeFocusedElementOfSubtree(oldRoot.get());
+        shadowHost->document().removeFocusedElementOfSubtree(oldRoot.get());
 
         if (oldRoot->attached())
             oldRoot->detach();
 
         m_shadowRoots.removeHead();
         oldRoot->setParentOrShadowHostNode(0);
-        oldRoot->setParentTreeScope(shadowHost->document());
+        oldRoot->setParentTreeScope(&shadowHost->document());
         oldRoot->setPrev(0);
         oldRoot->setNext(0);
         ChildNodeRemovalNotifier(shadowHost).notify(oldRoot.get());
diff --git a/Source/core/dom/shadow/InsertionPoint.cpp b/Source/core/dom/shadow/InsertionPoint.cpp
index 5d01a73..4c2b26d 100644
--- a/Source/core/dom/shadow/InsertionPoint.cpp
+++ b/Source/core/dom/shadow/InsertionPoint.cpp
@@ -41,7 +41,7 @@
 
 using namespace HTMLNames;
 
-InsertionPoint::InsertionPoint(const QualifiedName& tagName, Document* document)
+InsertionPoint::InsertionPoint(const QualifiedName& tagName, Document& document)
     : HTMLElement(tagName, document, CreateInsertionPoint)
     , m_registeredWithShadowRoot(false)
 {
@@ -114,7 +114,7 @@
     HTMLElement::detach(context);
 }
 
-void InsertionPoint::willRecalcStyle(StyleChange change)
+void InsertionPoint::willRecalcStyle(StyleRecalcChange change)
 {
     if (change < Inherit)
         return;
@@ -143,7 +143,7 @@
 
 PassRefPtr<NodeList> InsertionPoint::getDistributedNodes()
 {
-    document()->updateDistributionForNodeIfNeeded(this);
+    document().updateDistributionForNodeIfNeeded(this);
 
     Vector<RefPtr<Node> > nodes;
     for (size_t i = 0; i < m_distribution.size(); ++i)
@@ -152,9 +152,9 @@
     return StaticNodeList::adopt(nodes);
 }
 
-bool InsertionPoint::rendererIsNeeded(const NodeRenderingContext& context)
+bool InsertionPoint::rendererIsNeeded(const RenderStyle& style)
 {
-    return !isActive() && HTMLElement::rendererIsNeeded(context);
+    return !isActive() && HTMLElement::rendererIsNeeded(style);
 }
 
 void InsertionPoint::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
@@ -173,7 +173,7 @@
     if (ShadowRoot* root = containingShadowRoot()) {
         if (ElementShadow* rootOwner = root->owner()) {
             rootOwner->setNeedsDistributionRecalc();
-            if (isActive() && !m_registeredWithShadowRoot && insertionPoint->treeScope()->rootNode() == root) {
+            if (isActive() && !m_registeredWithShadowRoot && insertionPoint->treeScope().rootNode() == root) {
                 m_registeredWithShadowRoot = true;
                 root->addInsertionPoint(this);
                 rootOwner->didAffectApplyAuthorStyles();
@@ -203,7 +203,7 @@
     // Since this insertion point is no longer visible from the shadow subtree, it need to clean itself up.
     clearDistribution();
 
-    if (m_registeredWithShadowRoot && insertionPoint->treeScope()->rootNode() == root) {
+    if (m_registeredWithShadowRoot && insertionPoint->treeScope().rootNode() == root) {
         ASSERT(root);
         m_registeredWithShadowRoot = false;
         root->removeInsertionPoint(this);
diff --git a/Source/core/dom/shadow/InsertionPoint.h b/Source/core/dom/shadow/InsertionPoint.h
index aeb3243..d12423b 100644
--- a/Source/core/dom/shadow/InsertionPoint.h
+++ b/Source/core/dom/shadow/InsertionPoint.h
@@ -67,13 +67,13 @@
     Node* previousTo(const Node* node) const { return m_distribution.previousTo(node); }
 
 protected:
-    InsertionPoint(const QualifiedName&, Document*);
-    virtual bool rendererIsNeeded(const NodeRenderingContext&) OVERRIDE;
+    InsertionPoint(const QualifiedName&, Document&);
+    virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
     virtual void childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) OVERRIDE;
     virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
     virtual void removedFrom(ContainerNode*) OVERRIDE;
     virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
-    virtual void willRecalcStyle(StyleChange) OVERRIDE;
+    virtual void willRecalcStyle(StyleRecalcChange) OVERRIDE;
 
 private:
 
diff --git a/Source/core/dom/shadow/ShadowRoot.cpp b/Source/core/dom/shadow/ShadowRoot.cpp
index 6269a5c..fa21b00 100644
--- a/Source/core/dom/shadow/ShadowRoot.cpp
+++ b/Source/core/dom/shadow/ShadowRoot.cpp
@@ -27,6 +27,7 @@
 #include "config.h"
 #include "core/dom/shadow/ShadowRoot.h"
 
+#include "bindings/v8/ExceptionMessages.h"
 #include "bindings/v8/ExceptionState.h"
 #include "core/css/resolver/StyleResolver.h"
 #include "core/dom/ElementTraversal.h"
@@ -123,7 +124,7 @@
 
 PassRefPtr<Node> ShadowRoot::cloneNode(bool, ExceptionState& es)
 {
-    es.throwDOMException(DataCloneError);
+    es.throwDOMException(DataCloneError, ExceptionMessages::failedToExecute("cloneNode", "ShadowRoot", "ShadowRoot nodes are not clonable."));
     return 0;
 }
 
@@ -135,7 +136,7 @@
 void ShadowRoot::setInnerHTML(const String& markup, ExceptionState& es)
 {
     if (isOrphan()) {
-        es.throwDOMException(InvalidAccessError);
+        es.throwDOMException(InvalidAccessError, ExceptionMessages::failedToExecute("setInnerHTML", "ShadowRoot", "The ShadowRoot does not have a host."));
         return;
     }
 
@@ -157,13 +158,13 @@
     }
 }
 
-void ShadowRoot::recalcStyle(StyleChange change)
+void ShadowRoot::recalcStyle(StyleRecalcChange change)
 {
     // ShadowRoot doesn't support custom callbacks.
     ASSERT(!hasCustomStyleCallbacks());
 
-    StyleResolver* styleResolver = document()->styleResolver();
-    styleResolver->pushParentShadowRoot(this);
+    StyleResolver* styleResolver = document().styleResolver();
+    styleResolver->pushParentShadowRoot(*this);
 
     if (!attached()) {
         attach();
@@ -196,7 +197,7 @@
         forceReattachOfAnyWhitespaceSibling = didReattach || forceReattachOfAnyWhitespaceSibling;
     }
 
-    styleResolver->popParentShadowRoot(this);
+    styleResolver->popParentShadowRoot(*this);
     clearNeedsStyleRecalc();
     clearChildNeedsStyleRecalc();
 }
@@ -252,10 +253,10 @@
 
 void ShadowRoot::attach(const AttachContext& context)
 {
-    StyleResolver* styleResolver = document()->styleResolver();
-    styleResolver->pushParentShadowRoot(this);
+    StyleResolver* styleResolver = document().styleResolver();
+    styleResolver->pushParentShadowRoot(*this);
     DocumentFragment::attach(context);
-    styleResolver->popParentShadowRoot(this);
+    styleResolver->popParentShadowRoot(*this);
 }
 
 Node::InsertionNotificationRequest ShadowRoot::insertedInto(ContainerNode* insertionPoint)
diff --git a/Source/core/dom/shadow/ShadowRoot.h b/Source/core/dom/shadow/ShadowRoot.h
index 018f8e8..99bdf97 100644
--- a/Source/core/dom/shadow/ShadowRoot.h
+++ b/Source/core/dom/shadow/ShadowRoot.h
@@ -58,7 +58,7 @@
         return adoptRef(new ShadowRoot(document, type));
     }
 
-    void recalcStyle(StyleChange);
+    void recalcStyle(StyleRecalcChange);
 
     bool applyAuthorStyles() const { return m_applyAuthorStyles; }
     void setApplyAuthorStyles(bool);
@@ -145,7 +145,7 @@
 
 inline Element* ShadowRoot::activeElement() const
 {
-    if (Element* element = treeScope()->adjustedFocusedElement())
+    if (Element* element = treeScope().adjustedFocusedElement())
         return element;
     return 0;
 }
@@ -161,6 +161,12 @@
     return const_cast<ShadowRoot*>(toShadowRoot(static_cast<const Node*>(node)));
 }
 
+inline const ShadowRoot& toShadowRoot(const Node& node)
+{
+    ASSERT_WITH_SECURITY_IMPLICATION(node.isShadowRoot());
+    return static_cast<const ShadowRoot&>(node);
+}
+
 inline const ShadowRoot* toShadowRoot(const TreeScope* treeScope)
 {
     ASSERT_WITH_SECURITY_IMPLICATION(!treeScope || (treeScope->rootNode() && treeScope->rootNode()->isShadowRoot()));
@@ -172,6 +178,12 @@
     return const_cast<ShadowRoot*>(toShadowRoot(static_cast<const TreeScope*>(treeScope)));
 }
 
+inline ShadowRoot& toShadowRoot(TreeScope& treeScope)
+{
+    ASSERT_WITH_SECURITY_IMPLICATION(treeScope.rootNode() && treeScope.rootNode()->isShadowRoot());
+    return static_cast<ShadowRoot&>(treeScope);
+}
+
 } // namespace
 
 #endif