Merge from Chromium at DEPS revision r220549

This commit was generated by merge_to_master.py.

Change-Id: I0d3288f5db2b121c1681ea8d4a70c964cbed1fbd
diff --git a/Source/core/dom/ActiveDOMObject.cpp b/Source/core/dom/ActiveDOMObject.cpp
index de838fe..1614288 100644
--- a/Source/core/dom/ActiveDOMObject.cpp
+++ b/Source/core/dom/ActiveDOMObject.cpp
@@ -38,10 +38,7 @@
     , m_suspendIfNeededCalled(false)
 #endif
 {
-    if (!m_scriptExecutionContext)
-        return;
-
-    ASSERT(m_scriptExecutionContext->isContextThread());
+    ASSERT(!scriptExecutionContext || scriptExecutionContext->isContextThread());
 }
 
 ActiveDOMObject::~ActiveDOMObject()
@@ -52,12 +49,11 @@
     // ContextLifecycleObserver::contextDestroyed() (which we implement /
     // inherit). Hence, we should ensure that this is not 0 before use it
     // here.
-    if (!m_scriptExecutionContext)
+    if (!scriptExecutionContext())
         return;
 
     ASSERT(m_suspendIfNeededCalled);
-    ASSERT(m_scriptExecutionContext->isContextThread());
-    observeContext(0, ActiveDOMObjectType);
+    ASSERT(scriptExecutionContext()->isContextThread());
 }
 
 void ActiveDOMObject::suspendIfNeeded()
@@ -66,10 +62,8 @@
     ASSERT(!m_suspendIfNeededCalled);
     m_suspendIfNeededCalled = true;
 #endif
-    if (!m_scriptExecutionContext)
-        return;
-
-    m_scriptExecutionContext->suspendActiveDOMObjectIfNeeded(this);
+    if (ScriptExecutionContext* context = scriptExecutionContext())
+        scriptExecutionContext()->suspendActiveDOMObjectIfNeeded(this);
 }
 
 bool ActiveDOMObject::hasPendingActivity() const
diff --git a/Source/core/dom/AnimationEvent.h b/Source/core/dom/AnimationEvent.h
deleted file mode 100644
index 3eadf3d..0000000
--- a/Source/core/dom/AnimationEvent.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef AnimationEvent_h
-#define AnimationEvent_h
-
-#include "core/dom/Event.h"
-
-namespace WebCore {
-
-struct AnimationEventInit : public EventInit {
-    AnimationEventInit();
-
-    String animationName;
-    double elapsedTime;
-};
-
-class AnimationEvent : public Event {
-public:
-    static PassRefPtr<AnimationEvent> create()
-    {
-        return adoptRef(new AnimationEvent);
-    }
-    static PassRefPtr<AnimationEvent> create(const AtomicString& type, const String& animationName, double elapsedTime)
-    {
-        return adoptRef(new AnimationEvent(type, animationName, elapsedTime));
-    }
-    static PassRefPtr<AnimationEvent> create(const AtomicString& type, const AnimationEventInit& initializer)
-    {
-        return adoptRef(new AnimationEvent(type, initializer));
-    }
-
-    virtual ~AnimationEvent();
-
-    const String& animationName() const;
-    double elapsedTime() const;
-
-    virtual const AtomicString& interfaceName() const;
-
-private:
-    AnimationEvent();
-    AnimationEvent(const AtomicString& type, const String& animationName, double elapsedTime);
-    AnimationEvent(const AtomicString&, const AnimationEventInit&);
-
-    String m_animationName;
-    double m_elapsedTime;
-};
-
-} // namespace WebCore
-
-#endif // AnimationEvent_h
diff --git a/Source/core/dom/BeforeUnloadEvent.cpp b/Source/core/dom/BeforeUnloadEvent.cpp
index 25f7b0e..a22374c 100644
--- a/Source/core/dom/BeforeUnloadEvent.cpp
+++ b/Source/core/dom/BeforeUnloadEvent.cpp
@@ -1,8 +1,9 @@
-/**
+/*
  * Copyright (C) 2001 Peter Kelly (pmk@post.com)
  * Copyright (C) 2001 Tobias Anton (anton@stud.fbi.fh-darmstadt.de)
  * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
  * Copyright (C) 2003, 2005, 2006 Apple Computer, Inc.
+ * Copyright (C) 2013 Samsung Electronics.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -30,20 +31,16 @@
 BeforeUnloadEvent::BeforeUnloadEvent()
     : Event(eventNames().beforeunloadEvent, false, true)
 {
+    ScriptWrappable::init(this);
 }
 
 BeforeUnloadEvent::~BeforeUnloadEvent()
 {
 }
 
-bool BeforeUnloadEvent::storesResultAsString() const
+bool BeforeUnloadEvent::isBeforeUnloadEvent() const
 {
     return true;
 }
 
-void BeforeUnloadEvent::storeResult(const String& s)
-{
-    m_result = s;
-}
-
 } // namespace WebCore
diff --git a/Source/core/dom/BeforeUnloadEvent.h b/Source/core/dom/BeforeUnloadEvent.h
index c3be346..a76ad52 100644
--- a/Source/core/dom/BeforeUnloadEvent.h
+++ b/Source/core/dom/BeforeUnloadEvent.h
@@ -3,6 +3,7 @@
  * Copyright (C) 2001 Tobias Anton (anton@stud.fbi.fh-darmstadt.de)
  * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
  * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc.
+ * Copyright (C) 2013 Samsung Electronics.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -25,28 +26,37 @@
 #define BeforeUnloadEvent_h
 
 #include "core/dom/Event.h"
+#include "core/dom/EventNames.h"
 
 namespace WebCore {
 
-    class BeforeUnloadEvent : public Event {
-    public:
-        virtual ~BeforeUnloadEvent();
+class BeforeUnloadEvent : public Event {
+public:
+    virtual ~BeforeUnloadEvent();
 
-        static PassRefPtr<BeforeUnloadEvent> create()
-        {
-            return adoptRef(new BeforeUnloadEvent);
-        }
+    static PassRefPtr<BeforeUnloadEvent> create()
+    {
+        return adoptRef(new BeforeUnloadEvent);
+    }
 
-        virtual bool storesResultAsString() const;
-        virtual void storeResult(const String&);
+    virtual bool isBeforeUnloadEvent() const OVERRIDE;
 
-        String result() const { return m_result; }
+    void setReturnValue(const String& returnValue) { m_returnValue = returnValue; }
+    String returnValue() const { return m_returnValue; }
 
-    private:
-        BeforeUnloadEvent();
+    virtual const AtomicString& interfaceName() const OVERRIDE { return eventNames().interfaceForBeforeUnloadEvent; }
 
-        String m_result;
-    };
+private:
+    BeforeUnloadEvent();
+
+    String m_returnValue;
+};
+
+inline BeforeUnloadEvent* toBeforeUnloadEvent(Event* event)
+{
+    ASSERT_WITH_SECURITY_IMPLICATION(!event || event->isBeforeUnloadEvent());
+    return static_cast<BeforeUnloadEvent*>(event);
+}
 
 } // namespace WebCore
 
diff --git a/Source/core/dom/BeforeUnloadEvent.idl b/Source/core/dom/BeforeUnloadEvent.idl
new file mode 100644
index 0000000..618d558
--- /dev/null
+++ b/Source/core/dom/BeforeUnloadEvent.idl
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2013 Samsung Electronics. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * 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.
+ */
+
+interface BeforeUnloadEvent : Event {
+    attribute DOMString returnValue;
+};
diff --git a/Source/core/dom/ContainerNode.cpp b/Source/core/dom/ContainerNode.cpp
index c184a5e..94c37e5 100644
--- a/Source/core/dom/ContainerNode.cpp
+++ b/Source/core/dom/ContainerNode.cpp
@@ -48,7 +48,7 @@
 
 static void dispatchChildInsertionEvents(Node*);
 static void dispatchChildRemovalEvents(Node*);
-static void updateTreeAfterInsertion(ContainerNode*, Node*, AttachBehavior);
+static void updateTreeAfterInsertion(ContainerNode*, Node*);
 
 typedef pair<NodeCallback, RefPtr<Node> > CallbackInfo;
 typedef Vector<CallbackInfo> NodeCallbackQueue;
@@ -63,6 +63,17 @@
 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) {
@@ -106,13 +117,11 @@
             children[i]->detach();
         // FIXME: We need a no mutation event version of adoptNode.
         RefPtr<Node> child = document()->adoptNode(children[i].release(), ASSERT_NO_EXCEPTION);
-        parserAppendChild(child.get());
         // 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());
-        if (attached() && !child->attached())
-            child->attach();
+        parserAppendChild(child.get(), DeprecatedAttachNow);
     }
 }
 
@@ -214,7 +223,7 @@
     return checkAcceptChild(newParent, newChild, oldChild, es);
 }
 
-void ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionState& es, AttachBehavior attachBehavior)
+void ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionState& es)
 {
     // Check that this node is not "floating".
     // If it is, it can be deleted as a side effect of sending mutation events.
@@ -224,7 +233,7 @@
 
     // insertBefore(node, 0) is equivalent to appendChild(node)
     if (!refChild) {
-        appendChild(newChild, es, attachBehavior);
+        appendChild(newChild, es);
         return;
     }
 
@@ -273,7 +282,7 @@
 
         insertBeforeCommon(next.get(), child);
 
-        updateTreeAfterInsertion(this, child, attachBehavior);
+        updateTreeAfterInsertion(this, child);
     }
 
     dispatchSubtreeModifiedEvent();
@@ -305,7 +314,7 @@
     newChild->setNextSibling(nextChild);
 }
 
-void ContainerNode::parserInsertBefore(PassRefPtr<Node> newChild, Node* nextChild)
+void ContainerNode::parserInsertBefore(PassRefPtr<Node> newChild, Node* nextChild, AttachBehavior attachBehavior)
 {
     ASSERT(newChild);
     ASSERT(nextChild);
@@ -326,10 +335,13 @@
     ChildListMutationScope(this).childAdded(newChild.get());
 
     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, AttachBehavior attachBehavior)
+void ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionState& es)
 {
     // Check that this node is not "floating".
     // If it is, it can be deleted as a side effect of sending mutation events.
@@ -407,7 +419,7 @@
                 appendChildToContainer(child, this);
         }
 
-        updateTreeAfterInsertion(this, child, attachBehavior);
+        updateTreeAfterInsertion(this, child);
     }
 
     dispatchSubtreeModifiedEvent();
@@ -587,7 +599,7 @@
     dispatchSubtreeModifiedEvent();
 }
 
-void ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionState& es, AttachBehavior attachBehavior)
+void ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionState& es)
 {
     RefPtr<ContainerNode> protect(this);
 
@@ -635,13 +647,13 @@
             appendChildToContainer(child, this);
         }
 
-        updateTreeAfterInsertion(this, child, attachBehavior);
+        updateTreeAfterInsertion(this, child);
     }
 
     dispatchSubtreeModifiedEvent();
 }
 
-void ContainerNode::parserAppendChild(PassRefPtr<Node> newChild)
+void ContainerNode::parserAppendChild(PassRefPtr<Node> newChild, AttachBehavior attachBehavior)
 {
     ASSERT(newChild);
     ASSERT(!newChild->parentNode()); // Use appendChild if you need to handle reparenting (and want DOM mutation events).
@@ -665,6 +677,8 @@
 
     childrenChanged(true, last, 0, 1);
     ChildNodeInsertionNotifier(this).notify(newChild.get());
+
+    attachAfterInsertion(newChild.get(), attachBehavior);
 }
 
 void ContainerNode::suspendPostAttachCallbacks()
@@ -891,7 +905,7 @@
         if (renderStyle()->affectedByActive() || (isElementNode() && toElement(this)->childrenAffectedByActive()))
             setNeedsStyleRecalc();
         if (renderStyle()->hasAppearance())
-            renderer()->theme()->stateChanged(renderer(), PressedState);
+            RenderTheme::theme().stateChanged(renderer(), PressedState);
     }
 }
 
@@ -919,7 +933,7 @@
         if (renderStyle()->affectedByHover() || (isElementNode() && toElement(this)->childrenAffectedByHover()))
             setNeedsStyleRecalc();
         if (renderer() && renderer()->style()->hasAppearance())
-            renderer()->theme()->stateChanged(renderer(), HoverState);
+            RenderTheme::theme().stateChanged(renderer(), HoverState);
     }
 }
 
@@ -1015,7 +1029,7 @@
     }
 }
 
-static void updateTreeAfterInsertion(ContainerNode* parent, Node* child, AttachBehavior attachBehavior)
+static void updateTreeAfterInsertion(ContainerNode* parent, Node* child)
 {
     ASSERT(parent->refCount());
     ASSERT(child->refCount());
@@ -1026,14 +1040,8 @@
 
     ChildNodeInsertionNotifier(parent).notify(child);
 
-    // FIXME: Attachment should be the first operation in this function, but some code
-    // (for example, HTMLFormControlElement's autofocus support) requires this ordering.
-    if (parent->attached() && !child->attached() && child->parentNode() == parent) {
-        if (attachBehavior == AttachLazily)
-            child->lazyAttach();
-        else
-            child->attach();
-    }
+    // 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 f795436..7ed7733 100644
--- a/Source/core/dom/ContainerNode.h
+++ b/Source/core/dom/ContainerNode.h
@@ -99,17 +99,17 @@
     unsigned childNodeCount() const;
     Node* childNode(unsigned index) const;
 
-    void insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionState& = ASSERT_NO_EXCEPTION, AttachBehavior = AttachLazily);
-    void replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionState& = ASSERT_NO_EXCEPTION, AttachBehavior = AttachLazily);
+    void insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionState& = ASSERT_NO_EXCEPTION);
+    void replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionState& = ASSERT_NO_EXCEPTION);
     void removeChild(Node* child, ExceptionState& = ASSERT_NO_EXCEPTION);
-    void appendChild(PassRefPtr<Node> newChild, ExceptionState& = ASSERT_NO_EXCEPTION, AttachBehavior = AttachLazily);
+    void appendChild(PassRefPtr<Node> newChild, ExceptionState& = ASSERT_NO_EXCEPTION);
 
     // 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>);
+    void parserAppendChild(PassRefPtr<Node>, AttachBehavior = AttachLazily);
     void parserRemoveChild(Node*);
-    void parserInsertBefore(PassRefPtr<Node> newChild, Node* refChild);
+    void parserInsertBefore(PassRefPtr<Node> newChild, Node* refChild, AttachBehavior = AttachLazily);
 
     void removeChildren();
     void takeAllChildrenFrom(ContainerNode*);
diff --git a/Source/core/dom/ContextLifecycleNotifier.cpp b/Source/core/dom/ContextLifecycleNotifier.cpp
index f00e431..205380d 100644
--- a/Source/core/dom/ContextLifecycleNotifier.cpp
+++ b/Source/core/dom/ContextLifecycleNotifier.cpp
@@ -42,23 +42,23 @@
 {
 }
 
-void ContextLifecycleNotifier::addObserver(LifecycleObserver* observer, LifecycleObserver::Type type)
+void ContextLifecycleNotifier::addObserver(LifecycleObserver* observer)
 {
-    LifecycleNotifier::addObserver(observer, type);
+    LifecycleNotifier::addObserver(observer);
 
     RELEASE_ASSERT(m_iterating != IteratingOverContextObservers);
-    if (type == LifecycleObserver::ActiveDOMObjectType) {
+    if (observer->observerType() == LifecycleObserver::ActiveDOMObjectType) {
         RELEASE_ASSERT(m_iterating != IteratingOverActiveDOMObjects);
         m_activeDOMObjects.add(static_cast<ActiveDOMObject*>(observer));
     }
 }
 
-void ContextLifecycleNotifier::removeObserver(LifecycleObserver* observer, LifecycleObserver::Type type)
+void ContextLifecycleNotifier::removeObserver(LifecycleObserver* observer)
 {
-    LifecycleNotifier::removeObserver(observer, type);
+    LifecycleNotifier::removeObserver(observer);
 
     RELEASE_ASSERT(m_iterating != IteratingOverContextObservers);
-    if (type == LifecycleObserver::ActiveDOMObjectType) {
+    if (observer->observerType() == LifecycleObserver::ActiveDOMObjectType) {
         RELEASE_ASSERT(m_iterating != IteratingOverActiveDOMObjects);
         m_activeDOMObjects.remove(static_cast<ActiveDOMObject*>(observer));
     }
diff --git a/Source/core/dom/ContextLifecycleNotifier.h b/Source/core/dom/ContextLifecycleNotifier.h
index 04801e4..42a61f3 100644
--- a/Source/core/dom/ContextLifecycleNotifier.h
+++ b/Source/core/dom/ContextLifecycleNotifier.h
@@ -48,8 +48,8 @@
 
     const ActiveDOMObjectSet& activeDOMObjects() const { return m_activeDOMObjects; }
 
-    virtual void addObserver(LifecycleObserver*, LifecycleObserver::Type) OVERRIDE;
-    virtual void removeObserver(LifecycleObserver*, LifecycleObserver::Type) OVERRIDE;
+    virtual void addObserver(LifecycleObserver*) OVERRIDE;
+    virtual void removeObserver(LifecycleObserver*) OVERRIDE;
 
     void notifyResumingActiveDOMObjects();
     void notifySuspendingActiveDOMObjects(ActiveDOMObject::ReasonForSuspension);
diff --git a/Source/core/dom/ContextLifecycleObserver.cpp b/Source/core/dom/ContextLifecycleObserver.cpp
index baaa37c..be2d6c4 100644
--- a/Source/core/dom/ContextLifecycleObserver.cpp
+++ b/Source/core/dom/ContextLifecycleObserver.cpp
@@ -32,39 +32,17 @@
 namespace WebCore {
 
 ContextLifecycleObserver::ContextLifecycleObserver(ScriptExecutionContext* scriptExecutionContext, Type type)
-    : LifecycleObserver(scriptExecutionContext)
-    , m_scriptExecutionContext(0)
+    : LifecycleObserver(scriptExecutionContext, type)
 {
-    observeContext(scriptExecutionContext, type);
 }
 
 ContextLifecycleObserver::~ContextLifecycleObserver()
 {
-    if (m_scriptExecutionContext)
-        observeContext(0, GenericType);
 }
 
-void ContextLifecycleObserver::observeContext(ScriptExecutionContext* scriptExecutionContext, Type as)
+ScriptExecutionContext* ContextLifecycleObserver::scriptExecutionContext() const
 {
-    if (m_scriptExecutionContext) {
-        ASSERT(m_scriptExecutionContext->isContextThread());
-        m_scriptExecutionContext->wasUnobservedBy(this, as);
-    }
-
-    m_scriptExecutionContext = scriptExecutionContext;
-    m_lifecycleContext = scriptExecutionContext;
-
-    if (m_scriptExecutionContext) {
-        ASSERT(m_scriptExecutionContext->isContextThread());
-        m_scriptExecutionContext->wasObservedBy(this, as);
-    }
-}
-
-void ContextLifecycleObserver::contextDestroyed()
-{
-    m_scriptExecutionContext = 0;
-
-    LifecycleObserver::contextDestroyed();
+    return static_cast<ScriptExecutionContext*>(m_lifecycleContext);
 }
 
 } // namespace WebCore
diff --git a/Source/core/dom/ContextLifecycleObserver.h b/Source/core/dom/ContextLifecycleObserver.h
index a56b91c..c48a1ed 100644
--- a/Source/core/dom/ContextLifecycleObserver.h
+++ b/Source/core/dom/ContextLifecycleObserver.h
@@ -36,17 +36,10 @@
 class ContextLifecycleObserver : public LifecycleObserver {
 public:
     explicit ContextLifecycleObserver(ScriptExecutionContext*, Type = GenericType);
-
-    virtual void contextDestroyed() OVERRIDE;
-
-    ScriptExecutionContext* scriptExecutionContext() const { return m_scriptExecutionContext; }
+    ScriptExecutionContext* scriptExecutionContext() const;
 
 protected:
     virtual ~ContextLifecycleObserver();
-
-    void observeContext(ScriptExecutionContext*, Type);
-
-    ScriptExecutionContext* m_scriptExecutionContext;
 };
 
 } // namespace WebCore
diff --git a/Source/core/dom/CrossThreadTask.h b/Source/core/dom/CrossThreadTask.h
index 7a8761c..22864b8 100644
--- a/Source/core/dom/CrossThreadTask.h
+++ b/Source/core/dom/CrossThreadTask.h
@@ -31,7 +31,6 @@
 #ifndef CrossThreadTask_h
 #define CrossThreadTask_h
 
-#include <memory>
 #include "core/dom/ScriptExecutionContext.h"
 #include "core/platform/CrossThreadCopier.h"
 #include "wtf/PassOwnPtr.h"
diff --git a/Source/core/dom/DecodedDataDocumentParser.cpp b/Source/core/dom/DecodedDataDocumentParser.cpp
index 7ceaabe..53c846b 100644
--- a/Source/core/dom/DecodedDataDocumentParser.cpp
+++ b/Source/core/dom/DecodedDataDocumentParser.cpp
@@ -26,60 +26,11 @@
 #include "config.h"
 #include "core/dom/DecodedDataDocumentParser.h"
 
-#include "bindings/v8/ExceptionStatePlaceholder.h"
 #include "core/dom/Document.h"
-#include "core/dom/Element.h"
 #include "core/loader/TextResourceDecoder.h"
-#include "wtf/text/TextEncodingRegistry.h"
 
 namespace WebCore {
 
-namespace {
-
-class TitleEncodingFixer {
-public:
-    explicit TitleEncodingFixer(Document* document)
-        : m_document(document)
-        , m_firstEncoding(document->decoder()->encoding())
-    {
-    }
-
-    // It's possible for the encoding of the document to change while we're decoding
-    // data. That can only occur while we're processing the <head> portion of the
-    // document. There isn't much user-visible content in the <head>, but there is
-    // the <title> element. This function detects that situation and re-decodes the
-    // document's title so that the user doesn't see an incorrectly decoded title
-    // in the title bar.
-    inline void fixTitleEncodingIfNeeded()
-    {
-        if (m_firstEncoding == m_document->decoder()->encoding())
-            return; // In the common case, the encoding doesn't change and there isn't any work to do.
-        fixTitleEncoding();
-    }
-
-private:
-    void fixTitleEncoding();
-
-    Document* m_document;
-    WTF::TextEncoding m_firstEncoding;
-};
-
-void TitleEncodingFixer::fixTitleEncoding()
-{
-    RefPtr<Element> titleElement = m_document->titleElement();
-    if (!titleElement
-        || titleElement->firstElementChild()
-        || m_firstEncoding != Latin1Encoding()
-        || !titleElement->textContent().containsOnlyLatin1())
-        return; // Either we don't have a title yet or something bizzare as happened and we give up.
-    CString originalBytes = titleElement->textContent().latin1();
-    OwnPtr<TextCodec> codec = newTextCodec(m_document->decoder()->encoding());
-    String correctlyDecodedTitle = codec->decode(originalBytes.data(), originalBytes.length(), true);
-    titleElement->setTextContent(correctlyDecodedTitle, IGNORE_EXCEPTION);
-}
-
-}
-
 DecodedDataDocumentParser::DecodedDataDocumentParser(Document* document)
     : DocumentParser(document)
 {
@@ -90,11 +41,8 @@
     if (!length)
         return 0;
 
-    TitleEncodingFixer encodingFixer(document());
-
     String decoded = document()->decoder()->decode(data, length);
-
-    encodingFixer.fixTitleEncodingIfNeeded();
+    document()->setEncoding(document()->decoder()->encoding());
 
     if (decoded.isEmpty())
         return 0;
@@ -113,6 +61,7 @@
     if (!decoder)
         return 0;
     String remainingData = decoder->flush();
+    document()->setEncoding(document()->decoder()->encoding());
     if (remainingData.isEmpty())
         return 0;
 
diff --git a/Source/core/dom/Document.cpp b/Source/core/dom/Document.cpp
index 9dfe1b6..bc0bd80 100644
--- a/Source/core/dom/Document.cpp
+++ b/Source/core/dom/Document.cpp
@@ -64,7 +64,6 @@
 #include "core/dom/DocumentLifecycleObserver.h"
 #include "core/dom/DocumentMarkerController.h"
 #include "core/dom/DocumentSharedObjectPool.h"
-#include "core/dom/DocumentStyleSheetCollection.h"
 #include "core/dom/DocumentType.h"
 #include "core/dom/Element.h"
 #include "core/dom/ElementTraversal.h"
@@ -90,6 +89,7 @@
 #include "core/dom/ScriptRunner.h"
 #include "core/dom/ScriptedAnimationController.h"
 #include "core/dom/SelectorQuery.h"
+#include "core/dom/StyleSheetCollections.h"
 #include "core/dom/TouchList.h"
 #include "core/dom/TransformSource.h"
 #include "core/dom/TreeWalker.h"
@@ -105,6 +105,7 @@
 #include "core/html/HTMLAnchorElement.h"
 #include "core/html/HTMLCanvasElement.h"
 #include "core/html/HTMLCollection.h"
+#include "core/html/HTMLDialogElement.h"
 #include "core/html/HTMLDocument.h"
 #include "core/html/HTMLFrameOwnerElement.h"
 #include "core/html/HTMLHeadElement.h"
@@ -176,6 +177,7 @@
 #include "wtf/StdLibExtras.h"
 #include "wtf/UnusedParam.h"
 #include "wtf/text/StringBuffer.h"
+#include "wtf/text/TextEncodingRegistry.h"
 
 using namespace std;
 using namespace WTF;
@@ -300,7 +302,7 @@
     if (!frame || !root)
         return false;
 
-    return frame->editor()->shouldBeginEditing(rangeOfContents(root).get());
+    return frame->editor().shouldBeginEditing(rangeOfContents(root).get());
 }
 
 static bool canAccessAncestor(const SecurityOrigin* activeSecurityOrigin, Frame* targetFrame)
@@ -396,7 +398,7 @@
     , m_domTreeVersion(++s_globalTreeVersion)
     , m_listenerTypes(0)
     , m_mutationObserverTypes(0)
-    , m_styleSheetCollection(DocumentStyleSheetCollection::create(this))
+    , m_styleSheetCollections(StyleSheetCollections::create(this))
     , m_visitedLinkState(VisitedLinkState::create(this))
     , m_visuallyOrdered(false)
     , m_readyState(Complete)
@@ -536,7 +538,7 @@
     if (this == topDocument())
         clearAXObjectCache();
 
-    m_decoder = 0;
+    setDecoder(PassRefPtr<TextResourceDecoder>());
 
     if (m_styleSheetList)
         m_styleSheetList->detachFromDocument();
@@ -546,7 +548,7 @@
         m_import = 0;
     }
 
-    m_styleSheetCollection.clear();
+    m_styleSheetCollections.clear();
 
     if (m_elemSheet)
         m_elemSheet->clearOwnerNode();
@@ -587,6 +589,7 @@
     m_documentElement = 0;
     m_contextFeatures = ContextFeatures::defaultSwitch();
     m_userActionElements.documentDidRemoveLastRef();
+    m_associatedFormControls.clear();
 
     detachParser();
 
@@ -647,8 +650,8 @@
     selectorQueryCache()->invalidate();
     if (inQuirksMode() != wasInQuirksMode) {
         // All user stylesheets have to reparse using the different mode.
-        m_styleSheetCollection->clearPageUserSheet();
-        m_styleSheetCollection->invalidateInjectedStyleSheetCache();
+        m_styleSheetCollections->clearPageUserSheet();
+        m_styleSheetCollections->invalidateInjectedStyleSheetCache();
     }
 }
 
@@ -657,7 +660,7 @@
     return inQuirksMode() ? "BackCompat" : "CSS1Compat";
 }
 
-void Document::setDocType(PassRefPtr<DocumentType> docType)
+void Document::setDoctype(PassRefPtr<DocumentType> docType)
 {
     // This should never be called more than once.
     ASSERT(!m_docType || !docType);
@@ -806,6 +809,10 @@
         es.throwDOMException(NotSupportedError);
         return 0;
     }
+    if (data.find("]]>") != WTF::notFound) {
+        es.throwDOMException(InvalidCharacterError, "String cannot contain ']]>' since that is the end delimiter of a CData section.");
+        return 0;
+    }
     return CDATASection::create(this, data);
 }
 
@@ -1101,17 +1108,15 @@
     }
 
     m_readyState = readyState;
-    dispatchEvent(Event::create(eventNames().readystatechangeEvent, false, false));
+    dispatchEvent(Event::create(eventNames().readystatechangeEvent));
 }
 
-String Document::encoding() const
+String Document::encodingName() const
 {
     // TextEncoding::domName() returns a char*, no need to allocate a new
     // String for it each time.
     // FIXME: We should fix TextEncoding to speak AtomicString anyway.
-    if (TextResourceDecoder* d = decoder())
-        return AtomicString(d->encoding().domName());
-    return String();
+    return AtomicString(m_encoding.domName());
 }
 
 String Document::defaultCharset() const
@@ -1126,6 +1131,7 @@
     if (!decoder())
         return;
     decoder()->setEncoding(charset, TextResourceDecoder::UserChosenEncoding);
+    setEncoding(m_decoder->encoding());
 }
 
 void Document::setContentLanguage(const String& language)
@@ -1238,9 +1244,8 @@
  *  3. Collapse internal whitespace.
  */
 template <typename CharacterType>
-static inline StringWithDirection canonicalizedTitle(Document* document, const StringWithDirection& titleWithDirection)
+static inline String canonicalizedTitle(Document* document, const String& title)
 {
-    const String& title = titleWithDirection.string();
     const CharacterType* characters = title.getCharacters<CharacterType>();
     unsigned length = title.length();
     unsigned i;
@@ -1256,7 +1261,7 @@
     }
 
     if (i == length)
-        return StringWithDirection();
+        return String();
 
     // Replace control characters with spaces, and backslashes with currency symbols, and collapse whitespace.
     bool previousCharWasWS = false;
@@ -1281,32 +1286,30 @@
     }
 
     if (!builderIndex && buffer[builderIndex] == ' ')
-        return StringWithDirection();
+        return String();
 
     buffer.shrink(builderIndex + 1);
 
     // Replace the backslashes with currency symbols if the encoding requires it.
     document->displayBufferModifiedByEncoding(buffer.characters(), buffer.length());
 
-    return StringWithDirection(String::adopt(buffer), titleWithDirection.direction());
+    return String::adopt(buffer);
 }
 
-void Document::updateTitle(const StringWithDirection& title)
+void Document::updateTitle(const String& title)
 {
     if (m_rawTitle == title)
         return;
 
     m_rawTitle = title;
 
-    StringWithDirection oldTitle = m_title;
-    if (m_rawTitle.string().isEmpty())
-        m_title = StringWithDirection();
-    else {
-        if (m_rawTitle.string().is8Bit())
-            m_title = canonicalizedTitle<LChar>(this, m_rawTitle);
-        else
-            m_title = canonicalizedTitle<UChar>(this, m_rawTitle);
-    }
+    String oldTitle = m_title;
+    if (m_rawTitle.isEmpty())
+        m_title = String();
+    else if (m_rawTitle.is8Bit())
+        m_title = canonicalizedTitle<LChar>(this, m_rawTitle);
+    else
+        m_title = canonicalizedTitle<UChar>(this, m_rawTitle);
 
     if (!m_frame || oldTitle == m_title)
         return;
@@ -1327,8 +1330,7 @@
         }
     }
 
-    // The DOM API has no method of specifying direction, so assume LTR.
-    updateTitle(StringWithDirection(title, LTR));
+    updateTitle(title);
 
     if (m_titleElement) {
         ASSERT(isHTMLTitleElement(m_titleElement.get()));
@@ -1337,7 +1339,7 @@
     }
 }
 
-void Document::setTitleElement(const StringWithDirection& title, Element* titleElement)
+void Document::setTitleElement(const String& title, Element* titleElement)
 {
     if (titleElement != m_titleElement) {
         if (m_titleElement || m_titleSetExplicitly)
@@ -1357,19 +1359,20 @@
     m_titleElement = 0;
     m_titleSetExplicitly = false;
 
+    // FIXME: This is broken for SVG.
     // Update title based on first title element in the head, if one exists.
     if (HTMLElement* headElement = head()) {
-        for (Node* e = headElement->firstChild(); e; e = e->nextSibling()) {
-            if (isHTMLTitleElement(e)) {
-                HTMLTitleElement* titleElement = toHTMLTitleElement(e);
-                setTitleElement(titleElement->textWithDirection(), titleElement);
-                break;
-            }
+        for (Element* element = headElement->firstElementChild(); element; element = element->nextElementSibling()) {
+            if (!isHTMLTitleElement(element))
+                continue;
+            HTMLTitleElement* title = toHTMLTitleElement(element);
+            setTitleElement(title->text(), title);
+            break;
         }
     }
 
     if (!m_titleElement)
-        updateTitle(StringWithDirection());
+        updateTitle(String());
 }
 
 PageVisibilityState Document::visibilityState() const
@@ -1395,7 +1398,7 @@
 
 void Document::dispatchVisibilityStateChangeEvent()
 {
-    dispatchEvent(Event::create(eventNames().webkitvisibilitychangeEvent, false, false));
+    dispatchEvent(Event::create(eventNames().webkitvisibilitychangeEvent));
 }
 
 DOMSecurityPolicy* Document::securityPolicy()
@@ -1620,13 +1623,13 @@
     // re-attaching our containing iframe, which when asked HTMLFrameElementBase::isURLAllowed
     // hits a null-dereference due to security code always assuming the document has a SecurityOrigin.
 
-    if (m_styleSheetCollection->needsUpdateActiveStylesheetsOnStyleRecalc())
-        m_styleSheetCollection->updateActiveStyleSheets(FullStyleUpdate);
+    if (m_styleSheetCollections->needsUpdateActiveStylesheetsOnStyleRecalc())
+        m_styleSheetCollections->updateActiveStyleSheets(FullStyleUpdate);
 
     InspectorInstrumentationCookie cookie = InspectorInstrumentation::willRecalculateStyle(this);
 
     if (m_elemSheet && m_elemSheet->contents()->usesRemUnits())
-        m_styleSheetCollection->setUsesRemUnit(true);
+        m_styleSheetCollections->setUsesRemUnit(true);
 
     m_inStyleRecalc = true;
     {
@@ -1673,15 +1676,15 @@
         unscheduleStyleRecalc();
 
         // FIXME: SVG <use> element can schedule a recalc in the middle of an already running one.
-        // See DocumentStyleSheetCollection::updateActiveStyleSheets.
-        if (m_styleSheetCollection->needsUpdateActiveStylesheetsOnStyleRecalc())
+        // See StyleSheetCollections::updateActiveStyleSheets.
+        if (m_styleSheetCollections->needsUpdateActiveStylesheetsOnStyleRecalc())
             setNeedsStyleRecalc();
 
         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)
-            m_styleSheetCollection->resetCSSFeatureFlags(m_styleResolver->ruleFeatureSet());
+            m_styleSheetCollections->resetCSSFeatureFlags(m_styleResolver->ruleFeatureSet());
 
         if (frameView) {
             frameView->resumeScheduledEvents();
@@ -1741,8 +1744,6 @@
 
     updateStyleIfNeeded();
 
-    StackStats::LayoutCheckPoint layoutCheckPoint;
-
     // Only do a layout if changes have occurred that make it necessary.
     if (frameView && renderer() && (frameView->layoutPending() || renderer()->needsLayout()))
         frameView->layout();
@@ -1865,7 +1866,7 @@
     if (Settings* docSettings = settings())
         matchAuthorAndUserStyles = docSettings->authorAndUserStylesEnabled();
     m_styleResolver = adoptPtr(new StyleResolver(this, matchAuthorAndUserStyles));
-    m_styleSheetCollection->combineCSSFeatureFlags(m_styleResolver->ruleFeatureSet());
+    m_styleSheetCollections->combineCSSFeatureFlags(m_styleResolver->ruleFeatureSet());
 }
 
 void Document::clearStyleResolver()
@@ -2340,7 +2341,7 @@
     m_loadEventProgress = BeforeUnloadEventCompleted;
     if (!beforeUnloadEvent->defaultPrevented())
         defaultEventHandler(beforeUnloadEvent.get());
-    if (beforeUnloadEvent->result().isNull())
+    if (beforeUnloadEvent->returnValue().isNull())
         return true;
 
     if (navigatingDocument->m_didAllowNavigationViaBeforeUnloadConfirmationPanel) {
@@ -2348,7 +2349,7 @@
         return true;
     }
 
-    String text = displayStringModifiedByEncoding(beforeUnloadEvent->result());
+    String text = displayStringModifiedByEncoding(beforeUnloadEvent->returnValue());
     if (chrome.runBeforeUnloadConfirmPanel(text, m_frame)) {
         navigatingDocument->m_didAllowNavigationViaBeforeUnloadConfirmationPanel = true;
         return true;
@@ -2377,7 +2378,7 @@
             // time into freed memory.
             RefPtr<DocumentLoader> documentLoader =  m_frame->loader()->provisionalDocumentLoader();
             m_loadEventProgress = UnloadEventInProgress;
-            RefPtr<Event> unloadEvent(Event::create(eventNames().unloadEvent, false, false));
+            RefPtr<Event> unloadEvent(Event::create(eventNames().unloadEvent));
             if (documentLoader && !documentLoader->timing()->unloadEventStart() && !documentLoader->timing()->unloadEventEnd()) {
                 DocumentLoadTiming* timing = documentLoader->timing();
                 ASSERT(timing->navigationStart());
@@ -2704,7 +2705,7 @@
 
 void Document::seamlessParentUpdatedStylesheets()
 {
-    m_styleSheetCollection->didModifySeamlessParentStyleSheet();
+    m_styleSheetCollections->didModifySeamlessParentStyleSheet();
     styleResolverChanged(RecalcStyleImmediately);
 }
 
@@ -2780,8 +2781,8 @@
     // For more info, see the test at:
     // http://www.hixie.ch/tests/evil/css/import/main/preferred.html
     // -dwh
-    m_styleSheetCollection->setSelectedStylesheetSetName(content);
-    m_styleSheetCollection->setPreferredStylesheetSetName(content);
+    m_styleSheetCollections->setSelectedStylesheetSetName(content);
+    m_styleSheetCollections->setPreferredStylesheetSetName(content);
     styleResolverChanged(RecalcStyleDeferred);
 }
 
@@ -3104,17 +3105,17 @@
 
 String Document::preferredStylesheetSet() const
 {
-    return m_styleSheetCollection->preferredStylesheetSetName();
+    return m_styleSheetCollections->preferredStylesheetSetName();
 }
 
 String Document::selectedStylesheetSet() const
 {
-    return m_styleSheetCollection->selectedStylesheetSetName();
+    return m_styleSheetCollections->selectedStylesheetSetName();
 }
 
 void Document::setSelectedStylesheetSet(const String& aString)
 {
-    m_styleSheetCollection->setSelectedStylesheetSetName(aString);
+    m_styleSheetCollections->setSelectedStylesheetSetName(aString);
     styleResolverChanged(RecalcStyleDeferred);
 }
 
@@ -3134,14 +3135,14 @@
     }
     m_didCalculateStyleResolver = true;
 
-    bool needsRecalc = m_styleSheetCollection->updateActiveStyleSheets(updateMode);
+    bool needsRecalc = m_styleSheetCollections->updateActiveStyleSheets(updateMode);
 
     if (updateType >= RecalcStyleDeferred) {
         setNeedsStyleRecalc();
         return;
     }
 
-    if (didLayoutWithPendingStylesheets() && !m_styleSheetCollection->hasPendingSheets()) {
+    if (didLayoutWithPendingStylesheets() && !m_styleSheetCollections->hasPendingSheets()) {
         m_pendingSheetLayout = IgnoreLayoutWithPendingSheets;
         if (renderer())
             renderView()->repaintViewAndCompositedLayers();
@@ -3313,7 +3314,7 @@
         }
 
         if (oldFocusedElement->isRootEditableElement())
-            frame()->editor()->didEndEditing();
+            frame()->editor().didEndEditing();
 
         if (view()) {
             Widget* oldWidget = widgetForElement(oldFocusedElement.get());
@@ -3362,7 +3363,7 @@
         m_focusedElement->setFocus(true);
 
         if (m_focusedElement->isRootEditableElement())
-            frame()->editor()->didBeginEditing(m_focusedElement.get());
+            frame()->editor().didBeginEditing(m_focusedElement.get());
 
         // eww, I suck. set the qt focus correctly
         // ### find a better place in the code for this
@@ -3389,7 +3390,7 @@
             cache->handleFocusedUIElementChanged(oldFocusedElement.get(), newFocusedElement.get());
     }
 
-    if (!focusChangeBlocked)
+    if (!focusChangeBlocked && page())
         page()->chrome().focusedNodeChanged(m_focusedElement.get());
 
 SetFocusedElementDone:
@@ -3629,11 +3630,11 @@
         addMutationEventListenerTypeIfEnabled(DOMCHARACTERDATAMODIFIED_LISTENER);
     else if (eventType == eventNames().overflowchangedEvent)
         addListenerType(OVERFLOWCHANGED_LISTENER);
-    else if (eventType == eventNames().webkitAnimationStartEvent)
+    else if (eventType == eventNames().webkitAnimationStartEvent || (RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled() && eventType == eventNames().animationstartEvent))
         addListenerType(ANIMATIONSTART_LISTENER);
-    else if (eventType == eventNames().webkitAnimationEndEvent)
+    else if (eventType == eventNames().webkitAnimationEndEvent || (RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled() && eventType == eventNames().animationendEvent))
         addListenerType(ANIMATIONEND_LISTENER);
-    else if (eventType == eventNames().webkitAnimationIterationEvent)
+    else if (eventType == eventNames().webkitAnimationIterationEvent || (RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled() && eventType == eventNames().animationiterationEvent))
         addListenerType(ANIMATIONITERATION_LISTENER);
     else if (eventType == eventNames().webkitTransitionEndEvent || eventType == eventNames().transitionendEvent)
         addListenerType(TRANSITIONEND_LISTENER);
@@ -3939,6 +3940,32 @@
 void Document::setDecoder(PassRefPtr<TextResourceDecoder> decoder)
 {
     m_decoder = decoder;
+    setEncoding(m_decoder ? m_decoder->encoding() : WTF::TextEncoding());
+}
+
+void Document::setEncoding(const WTF::TextEncoding& encoding)
+{
+    if (m_encoding == encoding)
+        return;
+
+    // It's possible for the encoding of the document to change while we're decoding
+    // data. That can only occur while we're processing the <head> portion of the
+    // document. There isn't much user-visible content in the <head>, but there is
+    // the <title> element. This function detects that situation and re-decodes the
+    // document's title so that the user doesn't see an incorrectly decoded title
+    // in the title bar.
+    if (m_titleElement
+        && !m_titleElement->firstElementChild()
+        && m_encoding == Latin1Encoding()
+        && m_titleElement->textContent().containsOnlyLatin1()) {
+
+        CString originalBytes = m_titleElement->textContent().latin1();
+        OwnPtr<TextCodec> codec = newTextCodec(encoding);
+        String correctlyDecodedTitle = codec->decode(originalBytes.data(), originalBytes.length(), true);
+        m_titleElement->setTextContent(correctlyDecodedTitle, IGNORE_EXCEPTION);
+    }
+
+    m_encoding = encoding;
 }
 
 KURL Document::completeURL(const String& url, const KURL& baseURLOverride) const
@@ -3974,9 +4001,7 @@
         return Editor::Command();
 
     document->updateStyleIfNeeded();
-
-    return frame->editor()->command(commandName,
-        userInterface ? CommandFromDOMWithUserInterface : CommandFromDOM);
+    return frame->editor().command(commandName, userInterface ? CommandFromDOMWithUserInterface : CommandFromDOM);
 }
 
 bool Document::execCommand(const String& commandName, bool userInterface, const String& value)
@@ -4227,7 +4252,7 @@
     setParsing(false);
     if (!m_documentTiming.domContentLoadedEventStart)
         m_documentTiming.domContentLoadedEventStart = monotonicallyIncreasingTime();
-    dispatchEvent(Event::create(eventNames().DOMContentLoadedEvent, true, false));
+    dispatchEvent(Event::createBubble(eventNames().DOMContentLoadedEvent));
     if (!m_documentTiming.domContentLoadedEventEnd)
         m_documentTiming.domContentLoadedEventEnd = monotonicallyIncreasingTime();
 
@@ -4441,6 +4466,25 @@
     contentSecurityPolicy()->didReceiveHeaders(headers);
 }
 
+bool Document::allowInlineEventHandlers(Node* node, EventListener* listener, const String& contextURL, const WTF::OrdinalNumber& contextLine)
+{
+    if (!contentSecurityPolicy()->allowInlineEventHandlers(contextURL, contextLine))
+        return false;
+
+    // HTML says that inline script needs browsing context to create its execution environment.
+    // http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#event-handler-attributes
+    // Also, if the listening node came from other document, which happens on context-less event dispatching,
+    // we also need to ask the owner document of the node.
+    if (!m_frame)
+        return false;
+    if (!m_frame->script()->canExecuteScripts(NotAboutToExecuteScript))
+        return false;
+    if (node && node->document() != this && !node->document()->allowInlineEventHandlers(node, listener, contextURL, contextLine))
+        return false;
+
+    return true;
+}
+
 void Document::didUpdateSecurityOrigin()
 {
     if (!m_frame)
@@ -4742,6 +4786,13 @@
     element->setIsInTopLayer(false);
 }
 
+HTMLDialogElement* Document::activeModalDialog() const
+{
+    if (m_topLayerElements.isEmpty())
+        return 0;
+    return static_cast<HTMLDialogElement*>(m_topLayerElements.last().get());
+}
+
 void Document::webkitExitPointerLock()
 {
     if (!page())
@@ -4874,9 +4925,7 @@
 {
     if (!m_touchEventTargets.get())
         return;
-    // TODO(rbyers): Re-enable this ASSERT - http://crbug.com/254203.
-    // The known failure is benign, but the fix somehow causes a perf regression.
-    // ASSERT(m_touchEventTargets->contains(handler));
+    ASSERT(m_touchEventTargets->contains(handler));
     m_touchEventTargets->remove(handler);
     if (Document* parent = parentDocument()) {
         parent->didRemoveTouchEventHandler(this);
@@ -4899,9 +4948,12 @@
 
 void Document::didRemoveEventTargetNode(Node* handler)
 {
-    if (m_touchEventTargets) {
-        m_touchEventTargets->removeAll(handler);
-        if ((handler == this || m_touchEventTargets->isEmpty()) && parentDocument())
+    if (m_touchEventTargets && !m_touchEventTargets->isEmpty()) {
+        if (handler == this)
+            m_touchEventTargets->clear();
+        else
+            m_touchEventTargets->removeAll(handler);
+        if (m_touchEventTargets->isEmpty() && parentDocument())
             parentDocument()->didRemoveEventTargetNode(this);
     }
 }
@@ -5180,7 +5232,7 @@
 
 bool Document::haveStylesheetsLoaded() const
 {
-    return !m_styleSheetCollection->hasPendingSheets() || m_ignorePendingStylesheets;
+    return !m_styleSheetCollections->hasPendingSheets() || m_ignorePendingStylesheets;
 }
 
 Locale& Document::getCachedLocale(const AtomicString& locale)
diff --git a/Source/core/dom/Document.h b/Source/core/dom/Document.h
index f0145de..b5fc9e6 100644
--- a/Source/core/dom/Document.h
+++ b/Source/core/dom/Document.h
@@ -48,7 +48,6 @@
 #include "core/page/PageVisibilityState.h"
 #include "weborigin/ReferrerPolicy.h"
 #include "core/platform/Timer.h"
-#include "core/platform/text/StringWithDirection.h"
 #include "core/rendering/HitTestRequest.h"
 #include "wtf/Deque.h"
 #include "wtf/HashSet.h"
@@ -88,7 +87,6 @@
 class DocumentMarkerController;
 class DocumentParser;
 class DocumentSharedObjectPool;
-class DocumentStyleSheetCollection;
 class DocumentTimeline;
 class DocumentType;
 class Element;
@@ -103,6 +101,7 @@
 class HTMLAllCollection;
 class HTMLCanvasElement;
 class HTMLCollection;
+class HTMLDialogElement;
 class HTMLDocument;
 class HTMLElement;
 class HTMLFrameOwnerElement;
@@ -147,6 +146,7 @@
 class Settings;
 class StyleResolver;
 class StyleSheet;
+class StyleSheetCollections;
 class StyleSheetContents;
 class StyleSheetList;
 class Text;
@@ -290,7 +290,7 @@
     DEFINE_ATTRIBUTE_EVENT_LISTENER(securitypolicyviolation);
 
     void setViewportArguments(const ViewportArguments& viewportArguments) { m_viewportArguments = viewportArguments; }
-    ViewportArguments viewportArguments() const { return m_viewportArguments; }
+    const ViewportArguments& viewportArguments() const { return m_viewportArguments; }
 #ifndef NDEBUG
     bool didDispatchViewportPropertiesChanged() const { return m_didDispatchViewportPropertiesChanged; }
 #endif
@@ -298,6 +298,7 @@
     void setReferrerPolicy(ReferrerPolicy referrerPolicy) { m_referrerPolicy = referrerPolicy; }
     ReferrerPolicy referrerPolicy() const { return m_referrerPolicy; }
 
+    void setDoctype(PassRefPtr<DocumentType>);
     DocumentType* doctype() const { return m_docType.get(); }
 
     DOMImplementation* implementation();
@@ -351,11 +352,11 @@
 
     String defaultCharset() const;
 
-    String inputEncoding() const { return Document::encoding(); }
-    String charset() const { return Document::encoding(); }
-    String characterSet() const { return Document::encoding(); }
+    String inputEncoding() const { return Document::encodingName(); }
+    String charset() const { return Document::encodingName(); }
+    String characterSet() const { return Document::encodingName(); }
 
-    String encoding() const;
+    String encodingName() const;
 
     void setCharset(const String&);
 
@@ -439,7 +440,7 @@
     // This is a DOM function.
     StyleSheetList* styleSheets();
 
-    DocumentStyleSheetCollection* styleSheetCollection() { return m_styleSheetCollection.get(); }
+    StyleSheetCollections* styleSheetCollections() { return m_styleSheetCollections.get(); }
 
     bool gotoAnchorNeededAfterStylesheetsLoad() { return m_gotoAnchorNeededAfterStylesheetsLoad; }
     void setGotoAnchorNeededAfterStylesheetsLoad(bool b) { m_gotoAnchorNeededAfterStylesheetsLoad = b; }
@@ -762,14 +763,11 @@
     HTMLIFrameElement* seamlessParentIFrame() const;
     bool shouldDisplaySeamlesslyWithParent() const;
 
-    // Used by DOM bindings; no direction known.
-    String title() const { return m_title.string(); }
+    String title() const { return m_title; }
     void setTitle(const String&);
 
-    const StringWithDirection& titleWithDirection() const { return m_title; }
-
     Element* titleElement() const { return m_titleElement.get(); }
-    void setTitleElement(const StringWithDirection&, Element* titleElement);
+    void setTitleElement(const String& title, Element* titleElement);
     void removeTitle(Element* titleElement);
 
     String cookie(ExceptionState&) const;
@@ -857,8 +855,6 @@
     void incDOMTreeVersion() { m_domTreeVersion = ++s_globalTreeVersion; }
     uint64_t domTreeVersion() const { return m_domTreeVersion; }
 
-    void setDocType(PassRefPtr<DocumentType>);
-
     enum PendingSheetLayout { NoLayoutWithPendingSheets, DidLayoutWithPendingSheets, IgnoreLayoutWithPendingSheets };
 
     bool didLayoutWithPendingStylesheets() const { return m_pendingSheetLayout == DidLayoutWithPendingSheets; }
@@ -894,6 +890,9 @@
     void setDecoder(PassRefPtr<TextResourceDecoder>);
     TextResourceDecoder* decoder() const { return m_decoder.get(); }
 
+    void setEncoding(const WTF::TextEncoding&);
+    const WTF::TextEncoding& encoding() const { return m_encoding; }
+
     String displayStringModifiedByEncoding(const String&) const;
     PassRefPtr<StringImpl> displayStringModifiedByEncoding(PassRefPtr<StringImpl>) const;
     void displayBufferModifiedByEncoding(LChar* buffer, unsigned len) const
@@ -921,6 +920,8 @@
     void initSecurityContext(const DocumentInit&);
     void initContentSecurityPolicy(const ContentSecurityPolicyResponseHeaders&);
 
+    bool allowInlineEventHandlers(Node*, EventListener*, const String& contextURL, const WTF::OrdinalNumber& contextLine);
+
     void statePopped(PassRefPtr<SerializedScriptValue>);
 
     enum LoadEventProgress {
@@ -1008,8 +1009,7 @@
     PassRefPtr<Element> createElement(const AtomicString& localName, const AtomicString& typeExtension, ExceptionState&);
     PassRefPtr<Element> createElementNS(const AtomicString& namespaceURI, const String& qualifiedName, const AtomicString& typeExtension, ExceptionState&);
     ScriptValue registerElement(WebCore::ScriptState*, const AtomicString& name, ExceptionState&);
-    // FIXME: When embedders switch to using WebDocument::registerEmbedderCustomElement, make the default name set StandardNames.
-    ScriptValue registerElement(WebCore::ScriptState*, const AtomicString& name, const Dictionary& options, ExceptionState&, CustomElement::NameSet validNames = CustomElement::AllNames);
+    ScriptValue registerElement(WebCore::ScriptState*, const AtomicString& name, const Dictionary& options, ExceptionState&, CustomElement::NameSet validNames = CustomElement::StandardNames);
     CustomElementRegistrationContext* registrationContext() { return m_registrationContext.get(); }
 
     void setImport(HTMLImport*);
@@ -1045,7 +1045,7 @@
     void addToTopLayer(Element*, const Element* before = 0);
     void removeFromTopLayer(Element*);
     const Vector<RefPtr<Element> >& topLayerElements() const { return m_topLayerElements; }
-    Element* activeModalDialog() const { return !m_topLayerElements.isEmpty() ? m_topLayerElements.last().get() : 0; }
+    HTMLDialogElement* activeModalDialog() const;
 
     const Document* templateDocument() const;
     Document* ensureTemplateDocument();
@@ -1109,7 +1109,7 @@
 
     virtual double timerAlignmentInterval() const;
 
-    void updateTitle(const StringWithDirection&);
+    void updateTitle(const String&);
     void updateFocusAppearanceTimerFired(Timer<Document>*);
     void updateBaseURL();
 
@@ -1224,7 +1224,7 @@
 
     MutationObserverOptions m_mutationObserverTypes;
 
-    OwnPtr<DocumentStyleSheetCollection> m_styleSheetCollection;
+    OwnPtr<StyleSheetCollections> m_styleSheetCollections;
     RefPtr<StyleSheetList> m_styleSheetList;
 
     OwnPtr<FormController> m_formController;
@@ -1249,8 +1249,8 @@
     // http://www.whatwg.org/specs/web-apps/current-work/#ignore-destructive-writes-counter
     unsigned m_ignoreDestructiveWriteCount;
 
-    StringWithDirection m_title;
-    StringWithDirection m_rawTitle;
+    String m_title;
+    String m_rawTitle;
     bool m_titleSetExplicitly;
     RefPtr<Element> m_titleElement;
 
@@ -1282,6 +1282,7 @@
     String m_contentLanguage;
 
     RefPtr<TextResourceDecoder> m_decoder;
+    WTF::TextEncoding m_encoding;
 
     InheritedBool m_designMode;
 
diff --git a/Source/core/dom/DocumentLifecycleObserver.cpp b/Source/core/dom/DocumentLifecycleObserver.cpp
index ee45688..497d2ea 100644
--- a/Source/core/dom/DocumentLifecycleObserver.cpp
+++ b/Source/core/dom/DocumentLifecycleObserver.cpp
@@ -38,7 +38,6 @@
 
 DocumentLifecycleObserver::~DocumentLifecycleObserver()
 {
-    observeContext(0, DocumentLifecycleObserverType);
 }
 
 DocumentLifecycleNotifier::DocumentLifecycleNotifier(ScriptExecutionContext* context)
@@ -46,24 +45,24 @@
 {
 }
 
-void DocumentLifecycleNotifier::addObserver(LifecycleObserver* observer, LifecycleObserver::Type type)
+void DocumentLifecycleNotifier::addObserver(LifecycleObserver* observer)
 {
-    if (type == LifecycleObserver::DocumentLifecycleObserverType) {
+    if (observer->observerType() == LifecycleObserver::DocumentLifecycleObserverType) {
         RELEASE_ASSERT(m_iterating != IteratingOverDocumentObservers);
         m_documentObservers.add(static_cast<DocumentLifecycleObserver*>(observer));
     }
 
-    ContextLifecycleNotifier::addObserver(observer, type);
+    ContextLifecycleNotifier::addObserver(observer);
 }
 
-void DocumentLifecycleNotifier::removeObserver(LifecycleObserver* observer, LifecycleObserver::Type type)
+void DocumentLifecycleNotifier::removeObserver(LifecycleObserver* observer)
 {
-    if (type == LifecycleObserver::DocumentLifecycleObserverType) {
+    if (observer->observerType() == LifecycleObserver::DocumentLifecycleObserverType) {
         RELEASE_ASSERT(m_iterating != IteratingOverDocumentObservers);
         m_documentObservers.remove(static_cast<DocumentLifecycleObserver*>(observer));
     }
 
-    ContextLifecycleNotifier::removeObserver(observer, type);
+    ContextLifecycleNotifier::removeObserver(observer);
 }
 
 } // namespace WebCore
diff --git a/Source/core/dom/DocumentLifecycleObserver.h b/Source/core/dom/DocumentLifecycleObserver.h
index dd7d521..27f1a68 100644
--- a/Source/core/dom/DocumentLifecycleObserver.h
+++ b/Source/core/dom/DocumentLifecycleObserver.h
@@ -51,8 +51,8 @@
     void notifyDocumentWasDetached();
     void notifyDocumentWasDisposed();
 
-    virtual void addObserver(LifecycleObserver*, LifecycleObserver::Type) OVERRIDE;
-    virtual void removeObserver(LifecycleObserver*, LifecycleObserver::Type) OVERRIDE;
+    virtual void addObserver(LifecycleObserver*) OVERRIDE;
+    virtual void removeObserver(LifecycleObserver*) OVERRIDE;
 
 private:
     explicit DocumentLifecycleNotifier(ScriptExecutionContext*);
diff --git a/Source/core/dom/DocumentStyleSheetCollection.cpp b/Source/core/dom/DocumentStyleSheetCollection.cpp
index bbcbe43..3fa1ce5 100644
--- a/Source/core/dom/DocumentStyleSheetCollection.cpp
+++ b/Source/core/dom/DocumentStyleSheetCollection.cpp
@@ -3,11 +3,10 @@
  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
  *           (C) 2001 Dirk Mueller (mueller@kde.org)
  *           (C) 2006 Alexey Proskuryakov (ap@webkit.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All rights reserved.
  * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
- * Copyright (C) 2008, 2009, 2011, 2012 Google Inc. All rights reserved.
  * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
- * Copyright (C) Research In Motion Limited 2010-2011. All rights reserved.
+ * Copyright (C) 2013 Google Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -31,432 +30,157 @@
 #include "HTMLNames.h"
 #include "SVGNames.h"
 #include "core/css/CSSStyleSheet.h"
-#include "core/css/StyleInvalidationAnalysis.h"
-#include "core/css/StyleSheetContents.h"
 #include "core/css/resolver/StyleResolver.h"
 #include "core/dom/Document.h"
 #include "core/dom/Element.h"
 #include "core/dom/ProcessingInstruction.h"
-#include "core/dom/ShadowTreeStyleSheetCollection.h"
-#include "core/dom/shadow/ShadowRoot.h"
+#include "core/dom/StyleSheetCollections.h"
 #include "core/html/HTMLIFrameElement.h"
 #include "core/html/HTMLLinkElement.h"
 #include "core/html/HTMLStyleElement.h"
-#include "core/page/Page.h"
-#include "core/page/PageGroup.h"
 #include "core/page/Settings.h"
-#include "core/page/UserContentURLPattern.h"
 #include "core/svg/SVGStyleElement.h"
 
 namespace WebCore {
 
 using namespace HTMLNames;
 
-DocumentStyleSheetCollection::DocumentStyleSheetCollection(Document* document)
-    : m_document(document)
-    , m_pendingStylesheets(0)
-    , m_injectedStyleSheetCacheValid(false)
-    , m_needsUpdateActiveStylesheetsOnStyleRecalc(false)
-    , m_usesSiblingRules(false)
-    , m_usesSiblingRulesOverride(false)
-    , m_usesFirstLineRules(false)
-    , m_usesFirstLetterRules(false)
-    , m_usesBeforeAfterRules(false)
-    , m_usesBeforeAfterRulesOverride(false)
-    , m_usesRemUnits(false)
-    , m_collectionForDocument(document)
-    , m_needsDocumentStyleSheetsUpdate(true)
+DocumentStyleSheetCollection::DocumentStyleSheetCollection(TreeScope* treeScope)
+    : StyleSheetCollection(treeScope)
 {
+    ASSERT(treeScope->rootNode() == treeScope->rootNode()->document());
 }
 
-DocumentStyleSheetCollection::~DocumentStyleSheetCollection()
+void DocumentStyleSheetCollection::collectStyleSheets(StyleSheetCollections* collections, Vector<RefPtr<StyleSheet> >& styleSheets, Vector<RefPtr<CSSStyleSheet> >& activeSheets)
 {
-    if (m_pageUserSheet)
-        m_pageUserSheet->clearOwnerNode();
-    for (unsigned i = 0; i < m_injectedUserStyleSheets.size(); ++i)
-        m_injectedUserStyleSheets[i]->clearOwnerNode();
-    for (unsigned i = 0; i < m_injectedAuthorStyleSheets.size(); ++i)
-        m_injectedAuthorStyleSheets[i]->clearOwnerNode();
-    for (unsigned i = 0; i < m_userStyleSheets.size(); ++i)
-        m_userStyleSheets[i]->clearOwnerNode();
-    for (unsigned i = 0; i < m_authorStyleSheets.size(); ++i)
-        m_authorStyleSheets[i]->clearOwnerNode();
-}
-
-void DocumentStyleSheetCollection::insertTreeScopeInDocumentOrder(TreeScopeSet& treeScopes, TreeScope* treeScope)
-{
-    if (treeScopes.isEmpty()) {
-        treeScopes.add(treeScope);
-        return;
-    }
-    if (treeScopes.contains(treeScope))
+    if (document()->settings() && !document()->settings()->authorAndUserStylesEnabled())
         return;
 
-    TreeScopeSet::iterator begin = treeScopes.begin();
-    TreeScopeSet::iterator end = treeScopes.end();
-    TreeScopeSet::iterator it = end;
-    TreeScope* followingTreeScope = 0;
-    do {
-        --it;
-        TreeScope* n = *it;
-        unsigned short position = n->comparePosition(treeScope);
-        if (position & Node::DOCUMENT_POSITION_FOLLOWING) {
-            treeScopes.insertBefore(followingTreeScope, treeScope);
-            return;
+    DocumentOrderedList::iterator begin = m_styleSheetCandidateNodes.begin();
+    DocumentOrderedList::iterator end = m_styleSheetCandidateNodes.end();
+    for (DocumentOrderedList::iterator it = begin; it != end; ++it) {
+        Node* n = *it;
+        StyleSheet* sheet = 0;
+        CSSStyleSheet* activeSheet = 0;
+        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);
+            // 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.
+                if (!document()->parsing() && !pi->isLoading())
+                    document()->applyXSLTransform(pi);
+                return;
+            }
+            sheet = pi->sheet();
+            if (sheet && !sheet->disabled() && sheet->isCSSStyleSheet())
+                activeSheet = static_cast<CSSStyleSheet*>(sheet);
+        } else if ((n->isHTMLElement() && (n->hasTagName(linkTag) || n->hasTagName(styleTag))) || (n->isSVGElement() && n->hasTagName(SVGNames::styleTag))) {
+            Element* e = toElement(n);
+            AtomicString title = e->getAttribute(titleAttr);
+            bool enabledViaScript = false;
+            if (e->hasLocalName(linkTag)) {
+                // <LINK> element
+                HTMLLinkElement* linkElement = toHTMLLinkElement(n);
+                enabledViaScript = linkElement->isEnabledViaScript();
+                if (!linkElement->isDisabled() && linkElement->styleSheetIsLoading()) {
+                    // it is loading but we should still decide which style sheet set to use
+                    if (!enabledViaScript && !title.isEmpty() && collections->preferredStylesheetSetName().isEmpty()) {
+                        const AtomicString& rel = e->getAttribute(relAttr);
+                        if (!rel.contains("alternate")) {
+                            collections->setPreferredStylesheetSetName(title);
+                            collections->setSelectedStylesheetSetName(title);
+                        }
+                    }
+
+                    continue;
+                }
+                sheet = linkElement->sheet();
+                if (!sheet)
+                    title = nullAtom;
+            } else if (n->isSVGElement() && n->hasTagName(SVGNames::styleTag)) {
+                sheet = static_cast<SVGStyleElement*>(n)->sheet();
+            } else {
+                sheet = static_cast<HTMLStyleElement*>(n)->sheet();
+            }
+
+            if (sheet && !sheet->disabled() && sheet->isCSSStyleSheet())
+                activeSheet = static_cast<CSSStyleSheet*>(sheet);
+
+            // Check to see if this sheet belongs to a styleset
+            // (thus making it PREFERRED or ALTERNATE rather than
+            // PERSISTENT).
+            AtomicString rel = e->getAttribute(relAttr);
+            if (!enabledViaScript && sheet && !title.isEmpty()) {
+                // Yes, we have a title.
+                if (collections->preferredStylesheetSetName().isEmpty()) {
+                    // No preferred set has been established. If
+                    // we are NOT an alternate sheet, then establish
+                    // us as the preferred set. Otherwise, just ignore
+                    // this sheet.
+                    if (e->hasLocalName(styleTag) || !rel.contains("alternate")) {
+                        collections->setPreferredStylesheetSetName(title);
+                        collections->setSelectedStylesheetSetName(title);
+                    }
+                }
+                if (title != collections->preferredStylesheetSetName())
+                    activeSheet = 0;
+            }
+
+            if (rel.contains("alternate") && title.isEmpty())
+                activeSheet = 0;
         }
-        followingTreeScope = n;
-    } while (it != begin);
-
-    treeScopes.insertBefore(followingTreeScope, treeScope);
-}
-
-StyleSheetCollection* DocumentStyleSheetCollection::ensureStyleSheetCollectionFor(TreeScope* treeScope)
-{
-    if (treeScope == m_document)
-        return &m_collectionForDocument;
-
-    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* DocumentStyleSheetCollection::styleSheetCollectionFor(TreeScope* treeScope)
-{
-    if (treeScope == m_document)
-        return &m_collectionForDocument;
-
-    HashMap<TreeScope*, OwnPtr<StyleSheetCollection> >::iterator it = m_styleSheetCollectionMap.find(treeScope);
-    if (it == m_styleSheetCollectionMap.end())
-        return 0;
-    return it->value.get();
-}
-
-const Vector<RefPtr<StyleSheet> >& DocumentStyleSheetCollection::styleSheetsForStyleSheetList()
-{
-    return m_collectionForDocument.styleSheetsForStyleSheetList();
-}
-
-const Vector<RefPtr<CSSStyleSheet> >& DocumentStyleSheetCollection::activeAuthorStyleSheets() const
-{
-    return m_collectionForDocument.activeAuthorStyleSheets();
-}
-
-void DocumentStyleSheetCollection::getActiveAuthorStyleSheets(Vector<const Vector<RefPtr<CSSStyleSheet> >*>& activeAuthorStyleSheets) const
-{
-    activeAuthorStyleSheets.append(&m_collectionForDocument.activeAuthorStyleSheets());
-
-    HashMap<TreeScope*, OwnPtr<StyleSheetCollection> >::const_iterator::Values begin = m_styleSheetCollectionMap.values().begin();
-    HashMap<TreeScope*, OwnPtr<StyleSheetCollection> >::const_iterator::Values end = m_styleSheetCollectionMap.values().end();
-    HashMap<TreeScope*, OwnPtr<StyleSheetCollection> >::const_iterator::Values it = begin;
-    for (; it != end; ++it) {
-        const StyleSheetCollection* collection = it->get();
-        activeAuthorStyleSheets.append(&collection->activeAuthorStyleSheets());
+        if (sheet)
+            styleSheets.append(sheet);
+        if (activeSheet)
+            activeSheets.append(activeSheet);
     }
 }
 
-void DocumentStyleSheetCollection::combineCSSFeatureFlags(const RuleFeatureSet& features)
+static void collectActiveCSSStyleSheetsFromSeamlessParents(Vector<RefPtr<CSSStyleSheet> >& sheets, Document* document)
 {
-    // Delay resetting the flags until after next style recalc since unapplying the style may not work without these set (this is true at least with before/after).
-    m_usesSiblingRules = m_usesSiblingRules || features.usesSiblingRules();
-    m_usesFirstLineRules = m_usesFirstLineRules || features.usesFirstLineRules();
-    m_usesBeforeAfterRules = m_usesBeforeAfterRules || features.usesBeforeAfterRules();
-}
-
-void DocumentStyleSheetCollection::resetCSSFeatureFlags(const RuleFeatureSet& features)
-{
-    m_usesSiblingRules = features.usesSiblingRules();
-    m_usesFirstLineRules = features.usesFirstLineRules();
-    m_usesBeforeAfterRules = features.usesBeforeAfterRules();
-}
-
-CSSStyleSheet* DocumentStyleSheetCollection::pageUserSheet()
-{
-    if (m_pageUserSheet)
-        return m_pageUserSheet.get();
-
-    Page* owningPage = m_document->page();
-    if (!owningPage)
-        return 0;
-
-    String userSheetText = owningPage->userStyleSheet();
-    if (userSheetText.isEmpty())
-        return 0;
-
-    // Parse the sheet and cache it.
-    m_pageUserSheet = CSSStyleSheet::createInline(m_document, m_document->settings()->userStyleSheetLocation());
-    m_pageUserSheet->contents()->setIsUserStyleSheet(true);
-    m_pageUserSheet->contents()->parseString(userSheetText);
-    return m_pageUserSheet.get();
-}
-
-void DocumentStyleSheetCollection::clearPageUserSheet()
-{
-    if (m_pageUserSheet) {
-        RefPtr<StyleSheet> removedSheet = m_pageUserSheet;
-        m_pageUserSheet = 0;
-        m_document->removedStyleSheet(removedSheet.get());
-    }
-}
-
-void DocumentStyleSheetCollection::updatePageUserSheet()
-{
-    clearPageUserSheet();
-    // FIXME: Why is this immediately and not defer?
-    if (StyleSheet* addedSheet = pageUserSheet())
-        m_document->addedStyleSheet(addedSheet, RecalcStyleImmediately);
-}
-
-const Vector<RefPtr<CSSStyleSheet> >& DocumentStyleSheetCollection::injectedUserStyleSheets() const
-{
-    updateInjectedStyleSheetCache();
-    return m_injectedUserStyleSheets;
-}
-
-const Vector<RefPtr<CSSStyleSheet> >& DocumentStyleSheetCollection::injectedAuthorStyleSheets() const
-{
-    updateInjectedStyleSheetCache();
-    return m_injectedAuthorStyleSheets;
-}
-
-void DocumentStyleSheetCollection::updateInjectedStyleSheetCache() const
-{
-    if (m_injectedStyleSheetCacheValid)
+    HTMLIFrameElement* seamlessParentIFrame = document->seamlessParentIFrame();
+    if (!seamlessParentIFrame)
         return;
-    m_injectedStyleSheetCacheValid = true;
-    m_injectedUserStyleSheets.clear();
-    m_injectedAuthorStyleSheets.clear();
-
-    Page* owningPage = m_document->page();
-    if (!owningPage)
-        return;
-
-    const PageGroup& pageGroup = owningPage->group();
-    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())
-            continue;
-        if (!UserContentURLPattern::matchesPatterns(m_document->url(), sheet->whitelist(), sheet->blacklist()))
-            continue;
-        RefPtr<CSSStyleSheet> groupSheet = CSSStyleSheet::createInline(const_cast<Document*>(m_document), sheet->url());
-        bool isUserStyleSheet = sheet->level() == UserStyleUserLevel;
-        if (isUserStyleSheet)
-            m_injectedUserStyleSheets.append(groupSheet);
-        else
-            m_injectedAuthorStyleSheets.append(groupSheet);
-        groupSheet->contents()->setIsUserStyleSheet(isUserStyleSheet);
-        groupSheet->contents()->parseString(sheet->source());
-    }
+    sheets.append(seamlessParentIFrame->document()->styleSheetCollections()->activeAuthorStyleSheets());
 }
 
-void DocumentStyleSheetCollection::invalidateInjectedStyleSheetCache()
+bool DocumentStyleSheetCollection::updateActiveStyleSheets(StyleSheetCollections* collections, StyleResolverUpdateMode updateMode)
 {
-    m_injectedStyleSheetCacheValid = false;
-    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);
-}
+    Vector<RefPtr<StyleSheet> > styleSheets;
+    Vector<RefPtr<CSSStyleSheet> > activeCSSStyleSheets;
+    activeCSSStyleSheets.append(collections->injectedAuthorStyleSheets());
+    activeCSSStyleSheets.append(collections->documentAuthorStyleSheets());
+    collectActiveCSSStyleSheetsFromSeamlessParents(activeCSSStyleSheets, document());
+    collectStyleSheets(collections, styleSheets, activeCSSStyleSheets);
 
-void DocumentStyleSheetCollection::addAuthorSheet(PassRefPtr<StyleSheetContents> authorSheet)
-{
-    ASSERT(!authorSheet->isUserStyleSheet());
-    m_authorStyleSheets.append(CSSStyleSheet::create(authorSheet, m_document));
-    m_document->addedStyleSheet(m_authorStyleSheets.last().get(), RecalcStyleImmediately);
-    m_needsDocumentStyleSheetsUpdate = true;
-}
+    StyleResolverUpdateType styleResolverUpdateType;
+    bool requiresFullStyleRecalc;
+    analyzeStyleSheetChange(updateMode, activeAuthorStyleSheets(), activeCSSStyleSheets, styleResolverUpdateType, requiresFullStyleRecalc);
 
-void DocumentStyleSheetCollection::addUserSheet(PassRefPtr<StyleSheetContents> userSheet)
-{
-    ASSERT(userSheet->isUserStyleSheet());
-    m_userStyleSheets.append(CSSStyleSheet::create(userSheet, m_document));
-    m_document->addedStyleSheet(m_userStyleSheets.last().get(), RecalcStyleImmediately);
-    m_needsDocumentStyleSheetsUpdate = true;
-}
-
-// This method is called whenever a top-level stylesheet has finished loading.
-void DocumentStyleSheetCollection::removePendingSheet(Node* styleSheetCandidateNode, RemovePendingSheetNotificationType notification)
-{
-    // Make sure we knew this sheet was pending, and that our count isn't out of sync.
-    ASSERT(m_pendingStylesheets > 0);
-
-    m_pendingStylesheets--;
-
-    TreeScope* treeScope = isHTMLStyleElement(styleSheetCandidateNode) ? styleSheetCandidateNode->treeScope() : m_document;
-    if (treeScope == m_document)
-        m_needsDocumentStyleSheetsUpdate = true;
-    else
-        m_dirtyTreeScopes.add(treeScope);
-
-    if (m_pendingStylesheets)
-        return;
-
-    if (notification == RemovePendingSheetNotifyLater) {
-        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();
-}
-
-void DocumentStyleSheetCollection::addStyleSheetCandidateNode(Node* node, bool createdByParser)
-{
-    if (!node->inDocument())
-        return;
-
-    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) {
-        m_needsDocumentStyleSheetsUpdate = true;
-        return;
-    }
-
-    insertTreeScopeInDocumentOrder(m_activeTreeScopes, treeScope);
-    m_dirtyTreeScopes.add(treeScope);
-}
-
-void DocumentStyleSheetCollection::removeStyleSheetCandidateNode(Node* node, ContainerNode* scopingNode)
-{
-    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) {
-        m_needsDocumentStyleSheetsUpdate = true;
-        return;
-    }
-    m_dirtyTreeScopes.add(treeScope);
-    m_activeTreeScopes.remove(treeScope);
-}
-
-void DocumentStyleSheetCollection::modifiedStyleSheetCandidateNode(Node* node)
-{
-    if (!node->inDocument())
-        return;
-
-    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);
-}
-
-bool DocumentStyleSheetCollection::shouldUpdateShadowTreeStyleSheetCollection(StyleResolverUpdateMode updateMode)
-{
-    return !m_dirtyTreeScopes.isEmpty() || updateMode == FullStyleUpdate;
-}
-
-bool DocumentStyleSheetCollection::updateActiveStyleSheets(StyleResolverUpdateMode updateMode)
-{
-    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).
-        m_needsUpdateActiveStylesheetsOnStyleRecalc = true;
-        return false;
-
-    }
-    if (!m_document->renderer() || !m_document->attached())
-        return false;
-
-    bool requiresFullStyleRecalc = false;
-    if (m_needsDocumentStyleSheetsUpdate || updateMode == FullStyleUpdate)
-        requiresFullStyleRecalc = m_collectionForDocument.updateActiveStyleSheets(this, updateMode);
-
-    if (shouldUpdateShadowTreeStyleSheetCollection(updateMode)) {
-        TreeScopeSet treeScopes = updateMode == FullStyleUpdate ? m_activeTreeScopes : m_dirtyTreeScopes;
-        HashSet<TreeScope*> treeScopesRemoved;
-
-        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(collection);
-            collection->updateActiveStyleSheets(this, updateMode);
-            if (!collection->hasStyleSheetCandidateNodes())
-                treeScopesRemoved.add(treeScope);
+    if (styleResolverUpdateType == Reconstruct) {
+        document()->clearStyleResolver();
+    } else {
+        StyleResolver* styleResolver = document()->styleResolverIfExists();
+        ASSERT(styleResolver);
+        // FIXME: We might have already had styles in child treescope. In this case, we cannot use buildScopedStyleTreeInDocumentOrder.
+        // Need to change "false" to some valid condition.
+        styleResolver->setBuildScopedStyleTreeInDocumentOrder(false);
+        if (styleResolverUpdateType == Reset) {
+            resetAllRuleSetsInTreeScope(styleResolver);
+            styleResolver->appendAuthorStyleSheets(0, activeCSSStyleSheets);
+        } else {
+            ASSERT(styleResolverUpdateType == Additive);
+            styleResolver->appendAuthorStyleSheets(m_activeAuthorStyleSheets.size(), activeCSSStyleSheets);
         }
-        if (!treeScopesRemoved.isEmpty())
-            for (HashSet<TreeScope*>::iterator it = treeScopesRemoved.begin(); it != treeScopesRemoved.end(); ++it)
-                m_activeTreeScopes.remove(*it);
-        m_dirtyTreeScopes.clear();
     }
-
-    if (StyleResolver* styleResolver = m_document->styleResolverIfExists()) {
-        styleResolver->finishAppendAuthorStyleSheets();
-        resetCSSFeatureFlags(styleResolver->ruleFeatureSet());
-    }
-
-    m_needsUpdateActiveStylesheetsOnStyleRecalc = false;
-    activeStyleSheetsUpdatedForInspector();
-    m_usesRemUnits = m_collectionForDocument.usesRemUnits();
-
-    if (m_needsDocumentStyleSheetsUpdate || updateMode == FullStyleUpdate) {
-        m_document->notifySeamlessChildDocumentsOfStylesheetUpdate();
-        m_needsDocumentStyleSheetsUpdate = false;
-    }
+    m_scopingNodesForStyleScoped.didRemoveScopingNodes();
+    m_activeAuthorStyleSheets.swap(activeCSSStyleSheets);
+    m_styleSheetsForStyleSheetList.swap(styleSheets);
+    updateUsesRemUnits();
 
     return requiresFullStyleRecalc;
 }
 
-void DocumentStyleSheetCollection::activeStyleSheetsUpdatedForInspector()
-{
-    if (m_activeTreeScopes.isEmpty()) {
-        InspectorInstrumentation::activeStyleSheetsUpdated(m_document, m_collectionForDocument.styleSheetsForStyleSheetList());
-        return;
-    }
-    Vector<RefPtr<StyleSheet> > activeStyleSheets;
-
-    activeStyleSheets.append(m_collectionForDocument.styleSheetsForStyleSheetList());
-
-    TreeScopeSet::iterator begin = m_activeTreeScopes.begin();
-    TreeScopeSet::iterator end = m_activeTreeScopes.end();
-    for (TreeScopeSet::iterator it = begin; it != end; ++it) {
-        if (StyleSheetCollection* collection = m_styleSheetCollectionMap.get(*it))
-            activeStyleSheets.append(collection->styleSheetsForStyleSheetList());
-    }
-
-    // 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);
-}
-
-void DocumentStyleSheetCollection::didRemoveShadowRoot(ShadowRoot* shadowRoot)
-{
-    m_styleSheetCollectionMap.remove(shadowRoot);
-}
-
-void DocumentStyleSheetCollection::appendActiveAuthorStyleSheets(StyleResolver* styleResolver)
-{
-    ASSERT(styleResolver);
-
-    styleResolver->setBuildScopedStyleTreeInDocumentOrder(true);
-    styleResolver->appendAuthorStyleSheets(0, m_collectionForDocument.activeAuthorStyleSheets());
-
-    TreeScopeSet::iterator begin = m_activeTreeScopes.begin();
-    TreeScopeSet::iterator end = m_activeTreeScopes.end();
-    for (TreeScopeSet::iterator it = begin; it != end; ++it) {
-        if (StyleSheetCollection* collection = m_styleSheetCollectionMap.get(*it)) {
-            styleResolver->setBuildScopedStyleTreeInDocumentOrder(!collection->scopingNodesForStyleScoped());
-            styleResolver->appendAuthorStyleSheets(0, collection->activeAuthorStyleSheets());
-        }
-    }
-    styleResolver->finishAppendAuthorStyleSheets();
-    styleResolver->setBuildScopedStyleTreeInDocumentOrder(false);
-}
-
 }
diff --git a/Source/core/dom/DocumentStyleSheetCollection.h b/Source/core/dom/DocumentStyleSheetCollection.h
index 2dd47c5..4072cc8 100644
--- a/Source/core/dom/DocumentStyleSheetCollection.h
+++ b/Source/core/dom/DocumentStyleSheetCollection.h
@@ -6,7 +6,7 @@
  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All rights reserved.
  * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
  * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
- * Copyright (C) 2011 Google Inc. All rights reserved.
+ * Copyright (C) 2013 Google Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -28,136 +28,25 @@
 #ifndef DocumentStyleSheetCollection_h
 #define DocumentStyleSheetCollection_h
 
-#include "core/dom/Document.h"
-#include "core/dom/DocumentOrderedList.h"
 #include "core/dom/StyleSheetCollection.h"
-#include "wtf/FastAllocBase.h"
-#include "wtf/ListHashSet.h"
-#include "wtf/RefPtr.h"
-#include "wtf/Vector.h"
-#include "wtf/text/WTFString.h"
 
 namespace WebCore {
 
 class CSSStyleSheet;
-class Node;
-class RuleFeatureSet;
 class StyleSheet;
-class StyleSheetContents;
-class StyleSheetList;
+class StyleSheetCollection;
+class StyleSheetCollections;
+class TreeScope;
 
-class DocumentStyleSheetCollection {
-    WTF_MAKE_FAST_ALLOCATED;
+class DocumentStyleSheetCollection FINAL : public StyleSheetCollection {
+    WTF_MAKE_NONCOPYABLE(DocumentStyleSheetCollection); WTF_MAKE_FAST_ALLOCATED;
 public:
-    static PassOwnPtr<DocumentStyleSheetCollection> create(Document* document) { return adoptPtr(new DocumentStyleSheetCollection(document)); }
+    explicit DocumentStyleSheetCollection(TreeScope*);
 
-    ~DocumentStyleSheetCollection();
-
-    const Vector<RefPtr<StyleSheet> >& styleSheetsForStyleSheetList();
-    const Vector<RefPtr<CSSStyleSheet> >& activeAuthorStyleSheets() const;
-
-    CSSStyleSheet* pageUserSheet();
-    const Vector<RefPtr<CSSStyleSheet> >& documentUserStyleSheets() const { return m_userStyleSheets; }
-    const Vector<RefPtr<CSSStyleSheet> >& documentAuthorStyleSheets() const { return m_authorStyleSheets; }
-    const Vector<RefPtr<CSSStyleSheet> >& injectedUserStyleSheets() const;
-    const Vector<RefPtr<CSSStyleSheet> >& injectedAuthorStyleSheets() const;
-
-    void addStyleSheetCandidateNode(Node*, bool createdByParser);
-    void removeStyleSheetCandidateNode(Node*, ContainerNode* scopingNode = 0);
-    void modifiedStyleSheetCandidateNode(Node*);
-
-    void clearPageUserSheet();
-    void updatePageUserSheet();
-    void invalidateInjectedStyleSheetCache();
-    void updateInjectedStyleSheetCache() const;
-
-    void addAuthorSheet(PassRefPtr<StyleSheetContents> authorSheet);
-    void addUserSheet(PassRefPtr<StyleSheetContents> userSheet);
-
-    bool needsUpdateActiveStylesheetsOnStyleRecalc() const { return m_needsUpdateActiveStylesheetsOnStyleRecalc; }
-
-    bool updateActiveStyleSheets(StyleResolverUpdateMode);
-
-    String preferredStylesheetSetName() const { return m_preferredStylesheetSetName; }
-    String selectedStylesheetSetName() const { return m_selectedStylesheetSetName; }
-    void setPreferredStylesheetSetName(const String& name) { m_preferredStylesheetSetName = name; }
-    void setSelectedStylesheetSetName(const String& name) { m_selectedStylesheetSetName = name; }
-
-    void addPendingSheet() { m_pendingStylesheets++; }
-    enum RemovePendingSheetNotificationType {
-        RemovePendingSheetNotifyImmediately,
-        RemovePendingSheetNotifyLater
-    };
-    void removePendingSheet(Node* styleSheetCandidateNode, RemovePendingSheetNotificationType = RemovePendingSheetNotifyImmediately);
-
-    bool hasPendingSheets() const { return m_pendingStylesheets > 0; }
-
-    bool usesSiblingRules() const { return m_usesSiblingRules || m_usesSiblingRulesOverride; }
-    void setUsesSiblingRulesOverride(bool b) { m_usesSiblingRulesOverride = b; }
-    bool usesFirstLineRules() const { return m_usesFirstLineRules; }
-    bool usesFirstLetterRules() const { return m_usesFirstLetterRules; }
-    void setUsesFirstLetterRules(bool b) { m_usesFirstLetterRules = b; }
-    bool usesBeforeAfterRules() const { return m_usesBeforeAfterRules || m_usesBeforeAfterRulesOverride; }
-    void setUsesBeforeAfterRulesOverride(bool b) { m_usesBeforeAfterRulesOverride = b; }
-    bool usesRemUnits() const { return m_usesRemUnits; }
-    void setUsesRemUnit(bool b) { m_usesRemUnits = b; }
-    bool hasScopedStyleSheet() { return m_collectionForDocument.scopingNodesForStyleScoped(); }
-
-    void combineCSSFeatureFlags(const RuleFeatureSet&);
-    void resetCSSFeatureFlags(const RuleFeatureSet&);
-
-    void didModifySeamlessParentStyleSheet() { m_needsDocumentStyleSheetsUpdate = true; }
-    void didRemoveShadowRoot(ShadowRoot*);
-    void appendActiveAuthorStyleSheets(StyleResolver*);
-    void getActiveAuthorStyleSheets(Vector<const Vector<RefPtr<CSSStyleSheet> >*>& activeAuthorStyleSheets) const;
+    bool updateActiveStyleSheets(StyleSheetCollections*, StyleResolverUpdateMode);
 
 private:
-    DocumentStyleSheetCollection(Document*);
-
-    StyleSheetCollection* ensureStyleSheetCollectionFor(TreeScope*);
-    StyleSheetCollection* styleSheetCollectionFor(TreeScope*);
-    void activeStyleSheetsUpdatedForInspector();
-    bool shouldUpdateShadowTreeStyleSheetCollection(StyleResolverUpdateMode);
-
-    typedef ListHashSet<TreeScope*, 16> TreeScopeSet;
-    static void insertTreeScopeInDocumentOrder(TreeScopeSet&, TreeScope*);
-
-    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.
-    // We use this count of pending sheets to detect when we can begin attaching
-    // elements and when it is safe to execute scripts.
-    int m_pendingStylesheets;
-
-    RefPtr<CSSStyleSheet> m_pageUserSheet;
-
-    mutable Vector<RefPtr<CSSStyleSheet> > m_injectedUserStyleSheets;
-    mutable Vector<RefPtr<CSSStyleSheet> > m_injectedAuthorStyleSheets;
-    mutable bool m_injectedStyleSheetCacheValid;
-
-    Vector<RefPtr<CSSStyleSheet> > m_userStyleSheets;
-    Vector<RefPtr<CSSStyleSheet> > m_authorStyleSheets;
-
-    bool m_needsUpdateActiveStylesheetsOnStyleRecalc;
-
-    StyleSheetCollectionForDocument m_collectionForDocument;
-    HashMap<TreeScope*, OwnPtr<StyleSheetCollection> > m_styleSheetCollectionMap;
-
-    TreeScopeSet m_dirtyTreeScopes;
-    TreeScopeSet m_activeTreeScopes;
-    bool m_needsDocumentStyleSheetsUpdate;
-
-    String m_preferredStylesheetSetName;
-    String m_selectedStylesheetSetName;
-
-    bool m_usesSiblingRules;
-    bool m_usesSiblingRulesOverride;
-    bool m_usesFirstLineRules;
-    bool m_usesFirstLetterRules;
-    bool m_usesBeforeAfterRules;
-    bool m_usesBeforeAfterRulesOverride;
-    bool m_usesRemUnits;
+    void collectStyleSheets(StyleSheetCollections*, Vector<RefPtr<StyleSheet> >& styleSheets, Vector<RefPtr<CSSStyleSheet> >& activeSheets);
 };
 
 }
diff --git a/Source/core/dom/DocumentType.cpp b/Source/core/dom/DocumentType.cpp
index e85936b..12fbd2f 100644
--- a/Source/core/dom/DocumentType.cpp
+++ b/Source/core/dom/DocumentType.cpp
@@ -60,24 +60,18 @@
 Node::InsertionNotificationRequest DocumentType::insertedInto(ContainerNode* insertionPoint)
 {
     Node::insertedInto(insertionPoint);
-    if (!insertionPoint->inDocument())
-        return InsertionDone;
 
-    // Our document node can be null if we were created by a DOMImplementation.  We use the parent() instead.
-    ASSERT(parentNode() && parentNode()->isDocumentNode());
-    if (parentNode() && parentNode()->isDocumentNode()) {
-        Document* doc = toDocument(parentNode());
-        if (!doc->doctype())
-            doc->setDocType(this);
-    }
+    // DocumentType can only be inserted into a Document.
+    ASSERT(parentNode()->isDocumentNode());
+
+    document()->setDoctype(this);
 
     return InsertionDone;
 }
 
 void DocumentType::removedFrom(ContainerNode* insertionPoint)
 {
-    if (insertionPoint->inDocument() && document() && document()->doctype() == this)
-        document()->setDocType(0);
+    document()->setDoctype(0);
     Node::removedFrom(insertionPoint);
 }
 
diff --git a/Source/core/dom/DocumentType.h b/Source/core/dom/DocumentType.h
index aefc21d..0ad56fa 100644
--- a/Source/core/dom/DocumentType.h
+++ b/Source/core/dom/DocumentType.h
@@ -37,9 +37,10 @@
         return adoptRef(new DocumentType(document, name, publicId, systemId));
     }
 
-    // FIXME: We never fill m_entities and m_notations. Current implementation of NamedNodeMap doesn't work without an associated Element yet.
-    NamedNodeMap* entities() const { return m_entities.get(); }
-    NamedNodeMap* notations() const { return m_notations.get(); }
+    // FIXME: These wre removed from DOM4, we should add a UseCounter and see if
+    // we can remove them since they never worked anyway.
+    NamedNodeMap* entities() const { return 0; }
+    NamedNodeMap* notations() const { return 0; }
 
     const String& name() const { return m_name; }
     const String& publicId() const { return m_publicId; }
@@ -49,17 +50,14 @@
 private:
     DocumentType(Document*, const String& name, const String& publicId, const String& systemId);
 
-    virtual KURL baseURI() const;
-    virtual String nodeName() const;
-    virtual NodeType nodeType() const;
-    virtual PassRefPtr<Node> cloneNode(bool deep);
+    virtual KURL baseURI() const OVERRIDE;
+    virtual String nodeName() const OVERRIDE;
+    virtual NodeType nodeType() const OVERRIDE;
+    virtual PassRefPtr<Node> cloneNode(bool deep) OVERRIDE;
 
     virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
     virtual void removedFrom(ContainerNode*) OVERRIDE;
 
-    OwnPtr<NamedNodeMap> m_entities;
-    OwnPtr<NamedNodeMap> m_notations;
-
     String m_name;
     String m_publicId;
     String m_systemId;
diff --git a/Source/core/dom/Element.cpp b/Source/core/dom/Element.cpp
index 9577774..ce5e91a 100644
--- a/Source/core/dom/Element.cpp
+++ b/Source/core/dom/Element.cpp
@@ -35,6 +35,7 @@
 #include "bindings/v8/ExceptionState.h"
 #include "core/accessibility/AXObjectCache.h"
 #include "core/animation/DocumentTimeline.h"
+#include "core/animation/css/CSSAnimations.h"
 #include "core/css/CSSParser.h"
 #include "core/css/CSSStyleSheet.h"
 #include "core/css/CSSValuePool.h"
@@ -1449,64 +1450,75 @@
     if (hasCustomStyleCallbacks())
         willRecalcStyle(change);
 
-    // Ref currentStyle in case it would otherwise be deleted when setting the new style in the renderer.
-    RefPtr<RenderStyle> currentStyle = renderStyle();
-    bool hasParentStyle = static_cast<bool>(parentRenderStyle());
-    bool hasDirectAdjacentRules = childrenAffectedByDirectAdjacentRules();
-    bool hasIndirectAdjacentRules = childrenAffectedByForwardPositionalRules();
-
     if (hasRareData() && (change > NoChange || needsStyleRecalc())) {
         ElementRareData* data = elementRareData();
         data->resetStyleState();
         data->clearComputedStyle();
     }
 
-    if (hasParentStyle && (change >= Inherit || needsStyleRecalc())) {
-        StyleChange localChange = Detach;
-        RefPtr<RenderStyle> newStyle;
-        if (currentStyle) {
-            newStyle = styleForRenderer();
-            localChange = Node::diff(currentStyle.get(), newStyle.get(), document());
-        } else if (attached() && isActiveInsertionPoint(this)) {
-            // Active InsertionPoints will never have renderers so there's no reason to
-            // reattach them repeatedly once they're already attached.
-            localChange = change;
-        }
-        if (localChange == Detach) {
-            AttachContext reattachContext;
-            reattachContext.resolvedStyle = newStyle.get();
-            reattach(reattachContext);
+    // Active InsertionPoints have no renderers so they never need to go through a recalc.
+    if ((change >= Inherit || needsStyleRecalc()) && parentRenderStyle() && !isActiveInsertionPoint(this))
+        change = recalcOwnStyle(change);
 
-            if (hasCustomStyleCallbacks())
-                didRecalcStyle(change);
-            return true;
-        }
+    // If we reattached we don't need to recalc the style of our descendants anymore.
+    if (change < Reattach)
+        recalcChildStyle(change);
 
-        InspectorInstrumentation::didRecalculateStyleForElement(this);
+    clearNeedsStyleRecalc();
+    clearChildNeedsStyleRecalc();
 
-        if (RenderObject* renderer = this->renderer()) {
-            if (localChange != NoChange || pseudoStyleCacheIsInvalid(currentStyle.get(), newStyle.get()) || (change == Force && renderer->requiresForcedStyleRecalcPropagation()) || shouldNotifyRendererWithIdenticalStyles()) {
-                renderer->setAnimatableStyle(newStyle.get());
-            } else if (needsStyleRecalc()) {
-                // Although no change occurred, we use the new style so that the cousin style sharing code won't get
-                // fooled into believing this style is the same.
-                renderer->setStyleInternal(newStyle.get());
-            }
-        }
+    if (hasCustomStyleCallbacks())
+        didRecalcStyle(change);
 
-        // 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()->styleSheetCollection()->usesRemUnits() && document()->documentElement() == this && localChange != NoChange && currentStyle && newStyle && currentStyle->fontSize() != newStyle->fontSize()) {
-            // Cached RenderStyles may depend on the re units.
-            document()->styleResolver()->invalidateMatchedPropertiesCache();
-            change = Force;
-        }
+    return change == Reattach;
+}
 
-        if (styleChangeType() >= SubtreeStyleChange)
-            change = Force;
-        else if (change != Force)
-            change = localChange;
+Node::StyleChange Element::recalcOwnStyle(StyleChange change)
+{
+    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;
+
+    if (localChange == Reattach) {
+        AttachContext reattachContext;
+        reattachContext.resolvedStyle = newStyle.get();
+        reattach(reattachContext);
+        return Reattach;
     }
+
+    InspectorInstrumentation::didRecalculateStyleForElement(this);
+
+    if (RenderObject* renderer = this->renderer()) {
+        if (localChange != NoChange || pseudoStyleCacheIsInvalid(oldStyle.get(), newStyle.get()) || (change == Force && renderer->requiresForcedStyleRecalcPropagation()) || shouldNotifyRendererWithIdenticalStyles()) {
+            renderer->setAnimatableStyle(newStyle.get());
+        } else if (needsStyleRecalc()) {
+            // Although no change occurred, we use the new style so that the cousin style sharing code won't get
+            // fooled into believing this style is the same.
+            renderer->setStyleInternal(newStyle.get());
+        }
+    }
+
+    // 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()) {
+        // Cached RenderStyles may depend on the re units.
+        document()->styleResolver()->invalidateMatchedPropertiesCache();
+        return Force;
+    }
+
+    if (styleChangeType() >= SubtreeStyleChange)
+        return Force;
+
+    return max(localChange, change);
+}
+
+void Element::recalcChildStyle(StyleChange change)
+{
+    ASSERT(document()->inStyleRecalc());
+
     StyleResolverParentPusher parentPusher(this);
 
     for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot()) {
@@ -1522,6 +1534,8 @@
     // FIXME: This check is good enough for :hover + foo, but it is not good enough for :hover + foo + bar.
     // For now we will just worry about the common case, since it's a lot trickier to get the second case right
     // without doing way too much re-resolution.
+    bool hasDirectAdjacentRules = childrenAffectedByDirectAdjacentRules();
+    bool hasIndirectAdjacentRules = childrenAffectedByForwardPositionalRules();
     bool forceCheckOfNextElementSibling = false;
     bool forceCheckOfAnyElementSibling = false;
     bool forceReattachOfAnyWhitespaceSibling = false;
@@ -1560,13 +1574,6 @@
         updatePseudoElement(AFTER, change);
         updatePseudoElement(BACKDROP, change);
     }
-
-    clearNeedsStyleRecalc();
-    clearChildNeedsStyleRecalc();
-
-    if (hasCustomStyleCallbacks())
-        didRecalcStyle(change);
-    return false;
 }
 
 ElementShadow* Element::shadow() const
@@ -1636,11 +1643,6 @@
     return shadowRoot;
 }
 
-bool Element::supportsShadowElementForUserAgentShadow() const
-{
-    return true;
-}
-
 bool Element::childTypeAllowed(NodeType type) const
 {
     switch (type) {
@@ -2463,9 +2465,6 @@
 
 void Element::createPseudoElementIfNeeded(PseudoId pseudoId)
 {
-    if ((pseudoId == BEFORE || pseudoId == AFTER) && !document()->styleSheetCollection()->usesBeforeAfterRules())
-        return;
-
     if (pseudoId == BACKDROP && !isInTopLayer())
         return;
 
diff --git a/Source/core/dom/Element.h b/Source/core/dom/Element.h
index 556fe4f..1b35d58 100644
--- a/Source/core/dom/Element.h
+++ b/Source/core/dom/Element.h
@@ -447,7 +447,6 @@
 
     ShadowRoot* userAgentShadowRoot() const;
     ShadowRoot* ensureUserAgentShadowRoot();
-    virtual bool supportsShadowElementForUserAgentShadow() const;
     virtual const AtomicString& shadowPseudoId() const { return !part().isEmpty() ? part() : pseudo(); }
 
     RenderStyle* computedStyle(PseudoId = NOPSEUDO);
@@ -664,7 +663,7 @@
     virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
     virtual void removedFrom(ContainerNode*) OVERRIDE;
     virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
-    virtual void removeAllEventListeners() OVERRIDE FINAL;
+    virtual void removeAllEventListeners() OVERRIDE;
 
     virtual void willRecalcStyle(StyleChange);
     virtual void didRecalcStyle(StyleChange);
@@ -698,6 +697,9 @@
     void setInlineStyleFromString(const AtomicString&);
     MutableStylePropertySet* ensureMutableInlineStyle();
 
+    StyleChange recalcOwnStyle(StyleChange);
+    void recalcChildStyle(StyleChange);
+
     void makePresentationAttributeCacheKey(PresentationAttributeCacheKey&) const;
     void rebuildPresentationAttributeStyle();
 
diff --git a/Source/core/dom/Event.cpp b/Source/core/dom/Event.cpp
index 1b714f7..5b653df 100644
--- a/Source/core/dom/Event.cpp
+++ b/Source/core/dom/Event.cpp
@@ -148,18 +148,14 @@
     return false;
 }
 
-bool Event::storesResultAsString() const
-{
-    return false;
-}
-
 bool Event::isBeforeTextInsertedEvent() const
 {
     return false;
 }
 
-void Event::storeResult(const String&)
+bool Event::isBeforeUnloadEvent() const
 {
+    return false;
 }
 
 void Event::setTarget(PassRefPtr<EventTarget> target)
diff --git a/Source/core/dom/Event.h b/Source/core/dom/Event.h
index 7875b1e..f867528 100644
--- a/Source/core/dom/Event.h
+++ b/Source/core/dom/Event.h
@@ -76,6 +76,22 @@
     {
         return adoptRef(new Event);
     }
+
+    // A factory for a simple event. The event doesn't bubble, and isn't
+    // cancelable.
+    // http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#fire-a-simple-event
+    static PassRefPtr<Event> create(const AtomicString& type)
+    {
+        return adoptRef(new Event(type, false, false));
+    }
+    static PassRefPtr<Event> createCancelable(const AtomicString& type)
+    {
+        return adoptRef(new Event(type, false, true));
+    }
+    static PassRefPtr<Event> createBubble(const AtomicString& type)
+    {
+        return adoptRef(new Event(type, true, false));
+    }
     static PassRefPtr<Event> create(const AtomicString& type, bool canBubble, bool cancelable)
     {
         return adoptRef(new Event(type, canBubble, cancelable));
@@ -112,8 +128,8 @@
     // IE Extensions
     EventTarget* srcElement() const { return target(); } // MSIE extension - "the object that fired the event"
 
-    bool returnValue() const { return !defaultPrevented(); }
-    void setReturnValue(bool returnValue) { setDefaultPrevented(!returnValue); }
+    bool legacyReturnValue() const { return !defaultPrevented(); }
+    void setLegacyReturnValue(bool returnValue) { setDefaultPrevented(!returnValue); }
 
     Clipboard* clipboardData() const { return isClipboardEvent() ? clipboard() : 0; }
 
@@ -134,6 +150,8 @@
     virtual bool isClipboardEvent() const;
     virtual bool isBeforeTextInsertedEvent() const;
 
+    virtual bool isBeforeUnloadEvent() const;
+
     bool propagationStopped() const { return m_propagationStopped || m_immediatePropagationStopped; }
     bool immediatePropagationStopped() const { return m_immediatePropagationStopped; }
 
@@ -157,9 +175,6 @@
     EventPath& eventPath() { return m_eventPath; }
     PassRefPtr<NodeList> path() const;
 
-    virtual bool storesResultAsString() const;
-    virtual void storeResult(const String&);
-
     virtual Clipboard* clipboard() const { return 0; }
 
     bool isBeingDispatched() const { return eventPhase(); }
diff --git a/Source/core/dom/Event.idl b/Source/core/dom/Event.idl
index 74af6e1..88d704f 100644
--- a/Source/core/dom/Event.idl
+++ b/Source/core/dom/Event.idl
@@ -69,7 +69,7 @@
 
     // IE Extensions
     readonly attribute EventTarget      srcElement;
-             attribute boolean          returnValue;
+    [ImplementedAs=legacyReturnValue, DeprecateAs=EventReturnValue] attribute boolean returnValue;
              attribute boolean          cancelBubble;
 
     [EnabledAtRuntime=ShadowDOM] readonly attribute NodeList path;
diff --git a/Source/core/dom/EventAliases.in b/Source/core/dom/EventAliases.in
index 07c2e49..a4b61c2 100644
--- a/Source/core/dom/EventAliases.in
+++ b/Source/core/dom/EventAliases.in
@@ -1,4 +1,5 @@
 # Aliases
+AnimationEvent ImplementedAs=WebKitAnimationEvent, EnabledAtRuntime=cssAnimationUnprefixedEnabled
 Events ImplementedAs=Event
 HTMLEvents ImplementedAs=Event
 KeyboardEvents ImplementedAs=KeyboardEvent
diff --git a/Source/core/dom/EventListenerMap.cpp b/Source/core/dom/EventListenerMap.cpp
index ad0b72b..35af02f 100644
--- a/Source/core/dom/EventListenerMap.cpp
+++ b/Source/core/dom/EventListenerMap.cpp
@@ -38,7 +38,7 @@
 #include "wtf/Vector.h"
 
 #ifndef NDEBUG
-#include "wtf/Threading.h"
+#include "wtf/ThreadingPrimitives.h"
 #endif
 
 using namespace WTF;
diff --git a/Source/core/dom/EventNames.h b/Source/core/dom/EventNames.h
index 098071d..1633336 100644
--- a/Source/core/dom/EventNames.h
+++ b/Source/core/dom/EventNames.h
@@ -40,6 +40,7 @@
     macro(blocked) \
     macro(blur) \
     macro(cached) \
+    macro(cancel) \
     macro(change) \
     macro(chargingchange) \
     macro(chargingtimechange) \
@@ -190,8 +191,11 @@
     macro(stalled) \
     macro(suspend) \
     \
+    macro(animationend) \
     macro(webkitAnimationEnd) \
+    macro(animationstart) \
     macro(webkitAnimationStart) \
+    macro(animationiteration) \
     macro(webkitAnimationIteration) \
     \
     macro(webkitTransitionEnd) \
diff --git a/Source/core/dom/EventRetargeter.cpp b/Source/core/dom/EventRetargeter.cpp
index c113fd1..cf2d449 100644
--- a/Source/core/dom/EventRetargeter.cpp
+++ b/Source/core/dom/EventRetargeter.cpp
@@ -100,8 +100,6 @@
             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)
diff --git a/Source/core/dom/EventTarget.cpp b/Source/core/dom/EventTarget.cpp
index 30c6854..991f785 100644
--- a/Source/core/dom/EventTarget.cpp
+++ b/Source/core/dom/EventTarget.cpp
@@ -32,6 +32,7 @@
 #include "config.h"
 #include "core/dom/EventTarget.h"
 
+#include "RuntimeEnabledFeatures.h"
 #include "bindings/v8/DOMWrapperWorld.h"
 #include "bindings/v8/ExceptionState.h"
 #include "bindings/v8/ScriptController.h"
@@ -186,12 +187,64 @@
     if (event->type() == eventNames().transitionendEvent)
         return eventNames().webkitTransitionEndEvent;
 
+    if (event->type() == eventNames().animationstartEvent)
+        return eventNames().webkitAnimationStartEvent;
+
+    if (event->type() == eventNames().animationendEvent)
+        return eventNames().webkitAnimationEndEvent;
+
+    if (event->type() == eventNames().animationiterationEvent)
+        return eventNames().webkitAnimationIterationEvent;
+
     if (event->type() == eventNames().wheelEvent)
         return eventNames().mousewheelEvent;
 
     return emptyString();
 }
 
+void EventTarget::countLegacyEvents(const AtomicString& legacyTypeName, EventListenerVector* listenersVector, EventListenerVector* legacyListenersVector)
+{
+    UseCounter::Feature unprefixedFeature;
+    UseCounter::Feature prefixedFeature;
+    UseCounter::Feature prefixedAndUnprefixedFeature;
+    bool shouldCount = false;
+
+    if (legacyTypeName == eventNames().webkitTransitionEndEvent) {
+        prefixedFeature = UseCounter::PrefixedTransitionEndEvent;
+        unprefixedFeature = UseCounter::UnprefixedTransitionEndEvent;
+        prefixedAndUnprefixedFeature = UseCounter::PrefixedAndUnprefixedTransitionEndEvent;
+        shouldCount = true;
+    } else if (legacyTypeName == eventNames().webkitAnimationEndEvent) {
+        prefixedFeature = UseCounter::PrefixedAnimationEndEvent;
+        unprefixedFeature = UseCounter::UnprefixedAnimationEndEvent;
+        prefixedAndUnprefixedFeature = UseCounter::PrefixedAndUnprefixedAnimationEndEvent;
+        shouldCount = true;
+    } else if (legacyTypeName == eventNames().webkitAnimationStartEvent) {
+        prefixedFeature = UseCounter::PrefixedAnimationStartEvent;
+        unprefixedFeature = UseCounter::UnprefixedAnimationStartEvent;
+        prefixedAndUnprefixedFeature = UseCounter::PrefixedAndUnprefixedAnimationStartEvent;
+        shouldCount = true;
+    } else if (legacyTypeName == eventNames().webkitAnimationIterationEvent) {
+        prefixedFeature = UseCounter::PrefixedAnimationIterationEvent;
+        unprefixedFeature = UseCounter::UnprefixedAnimationIterationEvent;
+        prefixedAndUnprefixedFeature = UseCounter::PrefixedAndUnprefixedAnimationIterationEvent;
+        shouldCount = true;
+    }
+
+    if (shouldCount) {
+        if (DOMWindow* executingWindow = this->executingWindow()) {
+            if (legacyListenersVector) {
+                if (listenersVector)
+                    UseCounter::count(executingWindow, prefixedAndUnprefixedFeature);
+                else
+                    UseCounter::count(executingWindow, prefixedFeature);
+            } else if (listenersVector) {
+                UseCounter::count(executingWindow, unprefixedFeature);
+            }
+        }
+    }
+}
+
 bool EventTarget::fireEventListeners(Event* event)
 {
     ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
@@ -207,6 +260,9 @@
         legacyListenersVector = d->eventListenerMap.find(legacyTypeName);
 
     EventListenerVector* listenersVector = d->eventListenerMap.find(event->type());
+    if (!RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled() && (event->type() == eventNames().animationiterationEvent || event->type() == eventNames().animationendEvent
+        || event->type() == eventNames().animationstartEvent))
+        listenersVector = 0;
 
     if (listenersVector) {
         fireEventListeners(event, d, *listenersVector);
@@ -217,19 +273,7 @@
         event->setType(unprefixedTypeName);
     }
 
-    if (legacyTypeName == eventNames().webkitTransitionEndEvent) {
-        if (DOMWindow* executingWindow = this->executingWindow()) {
-            if (legacyListenersVector) {
-                if (listenersVector)
-                    UseCounter::count(executingWindow, UseCounter::PrefixedAndUnprefixedTransitionEndEvent);
-                else
-                    UseCounter::count(executingWindow, UseCounter::PrefixedTransitionEndEvent);
-            } else if (listenersVector) {
-                UseCounter::count(executingWindow, UseCounter::UnprefixedTransitionEndEvent);
-            }
-        }
-    }
-
+    countLegacyEvents(legacyTypeName, listenersVector, legacyListenersVector);
     return !event->defaultPrevented();
 }
 
diff --git a/Source/core/dom/EventTarget.h b/Source/core/dom/EventTarget.h
index 267306a..b63c8fb 100644
--- a/Source/core/dom/EventTarget.h
+++ b/Source/core/dom/EventTarget.h
@@ -139,6 +139,7 @@
 
         DOMWindow* executingWindow();
         void fireEventListeners(Event*, EventTargetData*, EventListenerVector&);
+        void countLegacyEvents(const AtomicString& legacyTypeName, EventListenerVector*, EventListenerVector*);
 
         bool clearAttributeEventListener(const AtomicString& eventType, DOMWrapperWorld* isolatedWorld);
 
diff --git a/Source/core/dom/FullscreenElementStack.cpp b/Source/core/dom/FullscreenElementStack.cpp
index b72b25b..43ee0a7 100644
--- a/Source/core/dom/FullscreenElementStack.cpp
+++ b/Source/core/dom/FullscreenElementStack.cpp
@@ -490,7 +490,7 @@
         if (!document()->contains(node.get()) && !node->inDocument())
             changeQueue.append(document()->documentElement());
 
-        node->dispatchEvent(Event::create(eventNames().webkitfullscreenchangeEvent, true, false));
+        node->dispatchEvent(Event::createBubble(eventNames().webkitfullscreenchangeEvent));
     }
 
     while (!errorQueue.isEmpty()) {
@@ -506,7 +506,7 @@
         if (!document()->contains(node.get()) && !node->inDocument())
             errorQueue.append(document()->documentElement());
 
-        node->dispatchEvent(Event::create(eventNames().webkitfullscreenerrorEvent, true, false));
+        node->dispatchEvent(Event::createBubble(eventNames().webkitfullscreenerrorEvent));
     }
 }
 
diff --git a/Source/core/dom/Node.cpp b/Source/core/dom/Node.cpp
index c4eebe4..75e593c 100644
--- a/Source/core/dom/Node.cpp
+++ b/Source/core/dom/Node.cpp
@@ -72,6 +72,7 @@
 #include "core/dom/shadow/ShadowRoot.h"
 #include "core/editing/htmlediting.h"
 #include "core/html/HTMLAnchorElement.h"
+#include "core/html/HTMLDialogElement.h"
 #include "core/html/HTMLFrameOwnerElement.h"
 #include "core/html/HTMLStyleElement.h"
 #include "core/html/RadioNodeList.h"
@@ -282,7 +283,7 @@
     if (display1 != display2 || fl1 != fl2 || colSpan1 != colSpan2
         || (specifiesColumns1 != specifiesColumns2 && doc->settings()->regionBasedColumnsEnabled())
         || (s1 && s2 && !s1->contentDataEquivalent(s2)))
-        ch = Detach;
+        ch = Reattach;
     else if (!s1 || !s2)
         ch = Inherit;
     else if (*s1 == *s2)
@@ -312,15 +313,15 @@
     // 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 = Detach;
+        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 = Detach;
+        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 = Detach;
+        ch = Reattach;
 
     return ch;
 }
@@ -383,7 +384,7 @@
 
 NodeRareData* Node::rareData() const
 {
-    ASSERT(hasRareData());
+    ASSERT_WITH_SECURITY_IMPLICATION(hasRareData());
     return static_cast<NodeRareData*>(m_data.m_rareData);
 }
 
@@ -515,18 +516,18 @@
     return lastChild();
 }
 
-void Node::insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionState& es, AttachBehavior attachBehavior)
+void Node::insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionState& es)
 {
     if (isContainerNode())
-        toContainerNode(this)->insertBefore(newChild, refChild, es, attachBehavior);
+        toContainerNode(this)->insertBefore(newChild, refChild, es);
     else
         es.throwDOMException(HierarchyRequestError);
 }
 
-void Node::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionState& es, AttachBehavior attachBehavior)
+void Node::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionState& es)
 {
     if (isContainerNode())
-        toContainerNode(this)->replaceChild(newChild, oldChild, es, attachBehavior);
+        toContainerNode(this)->replaceChild(newChild, oldChild, es);
     else
         es.throwDOMException(HierarchyRequestError);
 }
@@ -539,10 +540,10 @@
         es.throwDOMException(NotFoundError);
 }
 
-void Node::appendChild(PassRefPtr<Node> newChild, ExceptionState& es, AttachBehavior attachBehavior)
+void Node::appendChild(PassRefPtr<Node> newChild, ExceptionState& es)
 {
     if (isContainerNode())
-        toContainerNode(this)->appendChild(newChild, es, attachBehavior);
+        toContainerNode(this)->appendChild(newChild, es);
     else
         es.throwDOMException(HierarchyRequestError);
 }
@@ -866,7 +867,7 @@
 
 bool Node::isInert() const
 {
-    const Element* dialog = document()->activeModalDialog();
+    const HTMLDialogElement* dialog = document()->activeModalDialog();
     if (dialog && !containsIncludingShadowDOM(dialog) && !dialog->containsIncludingShadowDOM(this))
         return true;
     return document()->ownerElement() && document()->ownerElement()->isInert();
@@ -2477,12 +2478,12 @@
 
 void Node::dispatchChangeEvent()
 {
-    dispatchScopedEvent(Event::create(eventNames().changeEvent, true, false));
+    dispatchScopedEvent(Event::createBubble(eventNames().changeEvent));
 }
 
 void Node::dispatchInputEvent()
 {
-    dispatchScopedEvent(Event::create(eventNames().inputEvent, true, false));
+    dispatchScopedEvent(Event::createBubble(eventNames().inputEvent));
 }
 
 void Node::defaultEventHandler(Event* event)
diff --git a/Source/core/dom/Node.h b/Source/core/dom/Node.h
index bdfdb4c..5831fdd 100644
--- a/Source/core/dom/Node.h
+++ b/Source/core/dom/Node.h
@@ -100,6 +100,11 @@
     StyleChangeFromRenderer
 };
 
+enum AttachBehavior {
+    DeprecatedAttachNow,
+    AttachLazily,
+};
+
 class NodeRareDataBase {
 public:
     RenderObject* renderer() const { return m_renderer; }
@@ -114,11 +119,6 @@
     RenderObject* m_renderer;
 };
 
-enum AttachBehavior {
-    DeprecatedAttachNow,
-    AttachLazily,
-};
-
 class Node : public EventTarget, public ScriptWrappable, public TreeShared<Node> {
     friend class Document;
     friend class TreeScope;
@@ -166,7 +166,7 @@
     static bool isSupported(const String& feature, const String& version);
     static void dumpStatistics();
 
-    enum StyleChange { NoChange, NoInherit, Inherit, Detach, Force };
+    enum StyleChange { NoChange, NoInherit, Inherit, Force, Reattach };
     static StyleChange diff(const RenderStyle*, const RenderStyle*, Document*);
 
     virtual ~Node();
@@ -205,10 +205,10 @@
     // These should all actually return a node, but this is only important for language bindings,
     // which will already know and hold a ref on the right node to return. Returning bool allows
     // these methods to be more efficient since they don't need to return a ref
-    void insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionState& = ASSERT_NO_EXCEPTION, AttachBehavior = AttachLazily);
-    void replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionState& = ASSERT_NO_EXCEPTION, AttachBehavior = AttachLazily);
+    void insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionState& = ASSERT_NO_EXCEPTION);
+    void replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionState& = ASSERT_NO_EXCEPTION);
     void removeChild(Node* child, ExceptionState&);
-    void appendChild(PassRefPtr<Node> newChild, ExceptionState& = ASSERT_NO_EXCEPTION, AttachBehavior = AttachLazily);
+    void appendChild(PassRefPtr<Node> newChild, ExceptionState& = ASSERT_NO_EXCEPTION);
 
     bool hasChildNodes() const { return firstChild(); }
     virtual PassRefPtr<Node> cloneNode(bool deep = true) = 0;
diff --git a/Source/core/dom/NodeRenderingContext.cpp b/Source/core/dom/NodeRenderingContext.cpp
index c66ae3c..a59c09e 100644
--- a/Source/core/dom/NodeRenderingContext.cpp
+++ b/Source/core/dom/NodeRenderingContext.cpp
@@ -27,6 +27,7 @@
 #include "core/dom/NodeRenderingContext.h"
 
 #include "RuntimeEnabledFeatures.h"
+#include "core/animation/css/CSSAnimations.h"
 #include "core/css/resolver/StyleResolver.h"
 #include "core/dom/ContainerNode.h"
 #include "core/dom/FullscreenElementStack.h"
@@ -215,6 +216,8 @@
     if (!shouldCreateRenderer() && !elementInsideRegionNeedsRenderer())
         return;
 
+    // If m_style is already available, this scope shouldn't attempt to trigger animation updates.
+    CSSAnimationUpdateScope cssAnimationUpdateScope(m_style ? 0 : element);
     if (!m_style)
         m_style = element->styleForRenderer();
     ASSERT(m_style);
diff --git a/Source/core/dom/NodeRenderingTraversal.cpp b/Source/core/dom/NodeRenderingTraversal.cpp
index d550bcb..2563ccb 100644
--- a/Source/core/dom/NodeRenderingTraversal.cpp
+++ b/Source/core/dom/NodeRenderingTraversal.cpp
@@ -28,7 +28,7 @@
 #include "core/dom/NodeRenderingTraversal.h"
 
 #include "core/dom/PseudoElement.h"
-#include "core/dom/shadow/ComposedShadowTreeWalker.h"
+#include "core/dom/shadow/ComposedTreeWalker.h"
 
 namespace WebCore {
 
@@ -50,14 +50,14 @@
 ContainerNode* parent(const Node* node, ParentDetails* details)
 {
     // FIXME: Once everything lazy attaches we should assert that we don't need a distribution recalc here.
-    ComposedShadowTreeWalker walker(node, ComposedShadowTreeWalker::CrossUpperBoundary, ComposedShadowTreeWalker::CanStartFromShadowBoundary);
+    ComposedTreeWalker walker(node, ComposedTreeWalker::CrossUpperBoundary, ComposedTreeWalker::CanStartFromShadowBoundary);
     ContainerNode* found = toContainerNode(walker.traverseParent(walker.get(), details));
     return details->outOfComposition() ? 0 : found;
 }
 
 Node* nextSibling(const Node* node)
 {
-    ComposedShadowTreeWalker walker(node);
+    ComposedTreeWalker walker(node);
     if (node->isBeforePseudoElement()) {
         walker.parent();
         walker.firstChild();
@@ -76,7 +76,7 @@
 
 Node* previousSibling(const Node* node)
 {
-    ComposedShadowTreeWalker walker(node);
+    ComposedTreeWalker walker(node);
     if (node->isAfterPseudoElement()) {
         walker.parent();
         walker.lastChild();
@@ -95,28 +95,28 @@
 
 Node* nextInScope(const Node* node)
 {
-    ComposedShadowTreeWalker walker = ComposedShadowTreeWalker(node, ComposedShadowTreeWalker::DoNotCrossUpperBoundary);
+    ComposedTreeWalker walker = ComposedTreeWalker(node, ComposedTreeWalker::DoNotCrossUpperBoundary);
     walker.next();
     return walker.get();
 }
 
 Node* previousInScope(const Node* node)
 {
-    ComposedShadowTreeWalker walker = ComposedShadowTreeWalker(node, ComposedShadowTreeWalker::DoNotCrossUpperBoundary);
+    ComposedTreeWalker walker = ComposedTreeWalker(node, ComposedTreeWalker::DoNotCrossUpperBoundary);
     walker.previous();
     return walker.get();
 }
 
 Node* parentInScope(const Node* node)
 {
-    ComposedShadowTreeWalker walker = ComposedShadowTreeWalker(node, ComposedShadowTreeWalker::DoNotCrossUpperBoundary);
+    ComposedTreeWalker walker = ComposedTreeWalker(node, ComposedTreeWalker::DoNotCrossUpperBoundary);
     walker.parent();
     return walker.get();
 }
 
 Node* lastChildInScope(const Node* node)
 {
-    ComposedShadowTreeWalker walker = ComposedShadowTreeWalker(node, ComposedShadowTreeWalker::DoNotCrossUpperBoundary);
+    ComposedTreeWalker walker = ComposedTreeWalker(node, ComposedTreeWalker::DoNotCrossUpperBoundary);
     walker.lastChild();
     return walker.get();
 }
diff --git a/Source/core/dom/ProcessingInstruction.cpp b/Source/core/dom/ProcessingInstruction.cpp
index 033c043..a4ede16 100644
--- a/Source/core/dom/ProcessingInstruction.cpp
+++ b/Source/core/dom/ProcessingInstruction.cpp
@@ -26,7 +26,7 @@
 #include "core/css/MediaList.h"
 #include "core/css/StyleSheetContents.h"
 #include "core/dom/Document.h"
-#include "core/dom/DocumentStyleSheetCollection.h"
+#include "core/dom/StyleSheetCollections.h"
 #include "core/fetch/CSSStyleSheetResource.h"
 #include "core/fetch/FetchRequest.h"
 #include "core/fetch/ResourceFetcher.h"
@@ -63,7 +63,7 @@
         m_resource->removeClient(this);
 
     if (inDocument())
-        document()->styleSheetCollection()->removeStyleSheetCandidateNode(this);
+        document()->styleSheetCollections()->removeStyleSheetCandidateNode(this);
 }
 
 String ProcessingInstruction::nodeName() const
@@ -133,10 +133,10 @@
                 return;
 
             m_loading = true;
-            document()->styleSheetCollection()->addPendingSheet();
+            document()->styleSheetCollections()->addPendingSheet();
             FetchRequest request(ResourceRequest(document()->completeURL(href)), FetchInitiatorTypeNames::processinginstruction);
             if (m_isXSL)
-                m_resource = document()->fetcher()->requestXSLStyleSheet(request);
+                m_resource = document()->fetcher()->fetchXSLStyleSheet(request);
             else
             {
                 String charset = attrs.get("charset");
@@ -144,14 +144,14 @@
                     charset = document()->charset();
                 request.setCharset(charset);
 
-                m_resource = document()->fetcher()->requestCSSStyleSheet(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()->styleSheetCollection()->removePendingSheet(this);
+                document()->styleSheetCollections()->removePendingSheet(this);
             }
         }
     }
@@ -169,7 +169,7 @@
 bool ProcessingInstruction::sheetLoaded()
 {
     if (!isLoading()) {
-        document()->styleSheetCollection()->removePendingSheet(this);
+        document()->styleSheetCollections()->removePendingSheet(this);
         return true;
     }
     return false;
@@ -248,7 +248,7 @@
     CharacterData::insertedInto(insertionPoint);
     if (!insertionPoint->inDocument())
         return InsertionDone;
-    document()->styleSheetCollection()->addStyleSheetCandidateNode(this, m_createdByParser);
+    document()->styleSheetCollections()->addStyleSheetCandidateNode(this, m_createdByParser);
     checkStyleSheet();
     return InsertionDone;
 }
@@ -259,7 +259,7 @@
     if (!insertionPoint->inDocument())
         return;
 
-    document()->styleSheetCollection()->removeStyleSheetCandidateNode(this);
+    document()->styleSheetCollections()->removeStyleSheetCandidateNode(this);
 
     RefPtr<StyleSheet> removedSheet = m_sheet;
 
diff --git a/Source/core/dom/Range.cpp b/Source/core/dom/Range.cpp
index 8d1ad9d..ba27e67 100644
--- a/Source/core/dom/Range.cpp
+++ b/Source/core/dom/Range.cpp
@@ -25,6 +25,7 @@
 #include "config.h"
 #include "core/dom/Range.h"
 
+#include "bindings/v8/ExceptionMessages.h"
 #include "bindings/v8/ExceptionState.h"
 #include "bindings/v8/ExceptionStatePlaceholder.h"
 #include "core/dom/ClientRect.h"
@@ -1159,12 +1160,27 @@
     return 0;
 }
 
-void Range::checkNodeBA(Node* n, ExceptionState& es) const
+void Range::checkNodeBA(Node* n, ExceptionState& es, const char* methodName) const
 {
+    if (!m_start.container()) {
+        es.throwDOMException(InvalidStateError);
+        return;
+    }
+
+    if (!n) {
+        es.throwDOMException(NotFoundError);
+        return;
+    }
+
     // InvalidNodeTypeError: Raised if the root container of refNode is not an
     // Attr, Document, DocumentFragment or ShadowRoot node, or part of a SVG shadow DOM tree,
     // or if refNode is a Document, DocumentFragment, ShadowRoot, Attr, Entity, or Notation node.
 
+    if (!n->parentNode()) {
+        es.throwDOMException(InvalidNodeTypeError, ExceptionMessages::failedToExecute(methodName, "Range", "the given Node has no parent."));
+        return;
+    }
+
     switch (n->nodeType()) {
         case Node::ATTRIBUTE_NODE:
         case Node::DOCUMENT_FRAGMENT_NODE:
@@ -1191,11 +1207,11 @@
         case Node::ATTRIBUTE_NODE:
         case Node::DOCUMENT_NODE:
         case Node::DOCUMENT_FRAGMENT_NODE:
+        case Node::ELEMENT_NODE:
             break;
         case Node::CDATA_SECTION_NODE:
         case Node::COMMENT_NODE:
         case Node::DOCUMENT_TYPE_NODE:
-        case Node::ELEMENT_NODE:
         case Node::ENTITY_NODE:
         case Node::NOTATION_NODE:
         case Node::PROCESSING_INSTRUCTION_NODE:
@@ -1218,17 +1234,7 @@
 
 void Range::setStartAfter(Node* refNode, ExceptionState& es)
 {
-    if (!m_start.container()) {
-        es.throwDOMException(InvalidStateError);
-        return;
-    }
-
-    if (!refNode) {
-        es.throwDOMException(NotFoundError);
-        return;
-    }
-
-    checkNodeBA(refNode, es);
+    checkNodeBA(refNode, es, "setStartAfter");
     if (es.hadException())
         return;
 
@@ -1237,17 +1243,7 @@
 
 void Range::setEndBefore(Node* refNode, ExceptionState& es)
 {
-    if (!m_start.container()) {
-        es.throwDOMException(InvalidStateError);
-        return;
-    }
-
-    if (!refNode) {
-        es.throwDOMException(NotFoundError);
-        return;
-    }
-
-    checkNodeBA(refNode, es);
+    checkNodeBA(refNode, es, "setEndBefore");
     if (es.hadException())
         return;
 
@@ -1256,17 +1252,7 @@
 
 void Range::setEndAfter(Node* refNode, ExceptionState& es)
 {
-    if (!m_start.container()) {
-        es.throwDOMException(InvalidStateError);
-        return;
-    }
-
-    if (!refNode) {
-        es.throwDOMException(NotFoundError);
-        return;
-    }
-
-    checkNodeBA(refNode, es);
+    checkNodeBA(refNode, es, "setEndAfter");
     if (es.hadException())
         return;
 
@@ -1285,6 +1271,11 @@
         return;
     }
 
+    if (!refNode->parentNode()) {
+        es.throwDOMException(InvalidNodeTypeError, ExceptionMessages::failedToExecute("selectNode", "Range", "the given Node has no parent."));
+        return;
+    }
+
     // InvalidNodeTypeError: Raised if an ancestor of refNode is an Entity, Notation or
     // DocumentType node or if refNode is a Document, DocumentFragment, ShadowRoot, Attr, Entity, or Notation
     // node.
@@ -1329,10 +1320,8 @@
     if (m_ownerDocument != refNode->document())
         setDocument(refNode->document());
 
-    setStartBefore(refNode, es);
-    if (es.hadException())
-        return;
-    setEndAfter(refNode, es);
+    setStartBefore(refNode);
+    setEndAfter(refNode);
 }
 
 void Range::selectNodeContents(Node* refNode, ExceptionState& es)
@@ -1462,17 +1451,7 @@
 
 void Range::setStartBefore(Node* refNode, ExceptionState& es)
 {
-    if (!m_start.container()) {
-        es.throwDOMException(InvalidStateError);
-        return;
-    }
-
-    if (!refNode) {
-        es.throwDOMException(NotFoundError);
-        return;
-    }
-
-    checkNodeBA(refNode, es);
+    checkNodeBA(refNode, es, "setStartBefore");
     if (es.hadException())
         return;
 
diff --git a/Source/core/dom/Range.h b/Source/core/dom/Range.h
index 0de0a15..5faaf9c 100644
--- a/Source/core/dom/Range.h
+++ b/Source/core/dom/Range.h
@@ -101,7 +101,7 @@
     void selectNode(Node*, ExceptionState& = ASSERT_NO_EXCEPTION);
     void selectNodeContents(Node*, ExceptionState&);
     void surroundContents(PassRefPtr<Node>, ExceptionState&);
-    void setStartBefore(Node*, ExceptionState&);
+    void setStartBefore(Node*, ExceptionState& = ASSERT_NO_EXCEPTION);
 
     const Position startPosition() const { return m_start.toPosition(); }
     const Position endPosition() const { return m_end.toPosition(); }
@@ -156,7 +156,7 @@
     void setDocument(Document*);
 
     Node* checkNodeWOffset(Node*, int offset, ExceptionState&) const;
-    void checkNodeBA(Node*, ExceptionState&) const;
+    void checkNodeBA(Node*, ExceptionState&, const char* methodName) const;
     void checkDeleteExtract(ExceptionState&);
     int maxStartOffset() const;
     int maxEndOffset() const;
diff --git a/Source/core/dom/ScriptLoader.cpp b/Source/core/dom/ScriptLoader.cpp
index 55d6844..30f9de9 100644
--- a/Source/core/dom/ScriptLoader.cpp
+++ b/Source/core/dom/ScriptLoader.cpp
@@ -135,7 +135,7 @@
 
 void ScriptLoader::dispatchErrorEvent()
 {
-    m_element->dispatchEvent(Event::create(eventNames().errorEvent, false, false));
+    m_element->dispatchEvent(Event::create(eventNames().errorEvent));
 }
 
 void ScriptLoader::dispatchLoadEvent()
@@ -232,7 +232,7 @@
         m_characterEncoding = elementDocument->charset();
 
     if (client->hasSourceAttribute()) {
-        if (!requestScript(client->sourceAttributeValue()))
+        if (!fetchScript(client->sourceAttributeValue()))
             return false;
     }
 
@@ -261,7 +261,7 @@
     return true;
 }
 
-bool ScriptLoader::requestScript(const String& sourceUrl)
+bool ScriptLoader::fetchScript(const String& sourceUrl)
 {
     ASSERT(m_element);
 
@@ -286,7 +286,7 @@
         if (isValidScriptNonce)
             request.setContentSecurityCheck(DoNotCheckContentSecurityPolicy);
 
-        m_resource = elementDocument->fetcher()->requestScript(request);
+        m_resource = elementDocument->fetcher()->fetchScript(request);
         m_isExternalScript = true;
     }
 
diff --git a/Source/core/dom/ScriptLoader.h b/Source/core/dom/ScriptLoader.h
index dfa8818..cd180f0 100644
--- a/Source/core/dom/ScriptLoader.h
+++ b/Source/core/dom/ScriptLoader.h
@@ -78,7 +78,7 @@
     bool ignoresLoadRequest() const;
     bool isScriptForEventSupported() const;
 
-    bool requestScript(const String& sourceUrl);
+    bool fetchScript(const String& sourceUrl);
     void stopLoadRequest();
 
     ScriptLoaderClient* client() const;
diff --git a/Source/core/dom/ShadowTreeStyleSheetCollection.cpp b/Source/core/dom/ShadowTreeStyleSheetCollection.cpp
index 2c53a05..ff29a77 100644
--- a/Source/core/dom/ShadowTreeStyleSheetCollection.cpp
+++ b/Source/core/dom/ShadowTreeStyleSheetCollection.cpp
@@ -31,8 +31,8 @@
 #include "core/css/CSSStyleSheet.h"
 #include "core/css/resolver/StyleResolver.h"
 #include "core/dom/Document.h"
-#include "core/dom/DocumentStyleSheetCollection.h"
 #include "core/dom/Element.h"
+#include "core/dom/StyleSheetCollections.h"
 #include "core/dom/shadow/ShadowRoot.h"
 #include "core/html/HTMLStyleElement.h"
 #include "core/page/Settings.h"
@@ -46,7 +46,7 @@
 {
 }
 
-void ShadowTreeStyleSheetCollection::collectStyleSheets(DocumentStyleSheetCollection* collections, Vector<RefPtr<StyleSheet> >& styleSheets, Vector<RefPtr<CSSStyleSheet> >& activeSheets)
+void ShadowTreeStyleSheetCollection::collectStyleSheets(StyleSheetCollections* collections, Vector<RefPtr<StyleSheet> >& styleSheets, Vector<RefPtr<CSSStyleSheet> >& activeSheets)
 {
     if (document()->settings() && !document()->settings()->authorAndUserStylesEnabled())
         return;
@@ -94,7 +94,7 @@
     }
 }
 
-bool ShadowTreeStyleSheetCollection::updateActiveStyleSheets(DocumentStyleSheetCollection* collections, StyleResolverUpdateMode updateMode)
+bool ShadowTreeStyleSheetCollection::updateActiveStyleSheets(StyleSheetCollections* collections, StyleResolverUpdateMode updateMode)
 {
     Vector<RefPtr<StyleSheet> > styleSheets;
     Vector<RefPtr<CSSStyleSheet> > activeCSSStyleSheets;
diff --git a/Source/core/dom/ShadowTreeStyleSheetCollection.h b/Source/core/dom/ShadowTreeStyleSheetCollection.h
index e398440..2e0a979 100644
--- a/Source/core/dom/ShadowTreeStyleSheetCollection.h
+++ b/Source/core/dom/ShadowTreeStyleSheetCollection.h
@@ -33,20 +33,20 @@
 namespace WebCore {
 
 class CSSStyleSheet;
-class DocumentStyleSheetCollection;
 class ShadowRoot;
 class StyleSheet;
 class StyleSheetCollection;
+class StyleSheetCollections;
 
 class ShadowTreeStyleSheetCollection FINAL : public StyleSheetCollection {
     WTF_MAKE_NONCOPYABLE(ShadowTreeStyleSheetCollection); WTF_MAKE_FAST_ALLOCATED;
 public:
     explicit ShadowTreeStyleSheetCollection(ShadowRoot*);
 
-    bool updateActiveStyleSheets(DocumentStyleSheetCollection*, StyleResolverUpdateMode);
+    bool updateActiveStyleSheets(StyleSheetCollections*, StyleResolverUpdateMode);
 
 private:
-    void collectStyleSheets(DocumentStyleSheetCollection*, Vector<RefPtr<StyleSheet> >& styleSheets, Vector<RefPtr<CSSStyleSheet> >& activeSheets);
+    void collectStyleSheets(StyleSheetCollections*, Vector<RefPtr<StyleSheet> >& styleSheets, Vector<RefPtr<CSSStyleSheet> >& activeSheets);
 };
 
 }
diff --git a/Source/core/dom/StyleElement.cpp b/Source/core/dom/StyleElement.cpp
index 8f31ee4..683a8f2 100644
--- a/Source/core/dom/StyleElement.cpp
+++ b/Source/core/dom/StyleElement.cpp
@@ -25,9 +25,9 @@
 #include "core/css/MediaQueryEvaluator.h"
 #include "core/css/StyleSheetContents.h"
 #include "core/dom/Document.h"
-#include "core/dom/DocumentStyleSheetCollection.h"
 #include "core/dom/Element.h"
 #include "core/dom/ScriptableDocumentParser.h"
+#include "core/dom/StyleSheetCollections.h"
 #include "core/html/HTMLStyleElement.h"
 #include "core/page/ContentSecurityPolicy.h"
 #include "wtf/text/StringBuilder.h"
@@ -59,7 +59,7 @@
 {
     ASSERT(document);
     ASSERT(element);
-    document->styleSheetCollection()->addStyleSheetCandidateNode(element, m_createdByParser);
+    document->styleSheetCollections()->addStyleSheetCandidateNode(element, m_createdByParser);
     if (m_createdByParser)
         return;
 
@@ -70,7 +70,7 @@
 {
     ASSERT(document);
     ASSERT(element);
-    document->styleSheetCollection()->removeStyleSheetCandidateNode(element, scopingNode);
+    document->styleSheetCollections()->removeStyleSheetCandidateNode(element, scopingNode);
 
     RefPtr<StyleSheet> removedSheet = m_sheet;
 
@@ -88,7 +88,7 @@
         m_sheet->clearOwnerNode();
 
     if (element->inDocument())
-        document->styleSheetCollection()->removeStyleSheetCandidateNode(element, isHTMLStyleElement(element) ? toHTMLStyleElement(element)->scopingNode() :  0);
+        document->styleSheetCollections()->removeStyleSheetCandidateNode(element, isHTMLStyleElement(element) ? toHTMLStyleElement(element)->scopingNode() :  0);
 }
 
 void StyleElement::childrenChanged(Element* element)
@@ -127,7 +127,7 @@
     Document* document = e->document();
     if (m_sheet) {
         if (m_sheet->isLoading())
-            document->styleSheetCollection()->removePendingSheet(e);
+            document->styleSheetCollections()->removePendingSheet(e);
         clearSheet();
     }
 
@@ -139,7 +139,7 @@
         MediaQueryEvaluator screenEval("screen", true);
         MediaQueryEvaluator printEval("print", true);
         if (screenEval.eval(mediaQueries.get()) || printEval.eval(mediaQueries.get())) {
-            document->styleSheetCollection()->addPendingSheet();
+            document->styleSheetCollections()->addPendingSheet();
             m_loading = true;
 
             TextPosition startPosition = m_startPosition == TextPosition::belowRangePosition() ? TextPosition::minimumPosition() : m_startPosition;
@@ -169,14 +169,14 @@
     if (isLoading())
         return false;
 
-    document->styleSheetCollection()->removePendingSheet(m_sheet->ownerNode());
+    document->styleSheetCollections()->removePendingSheet(m_sheet->ownerNode());
     return true;
 }
 
 void StyleElement::startLoadingDynamicSheet(Document* document)
 {
     ASSERT(document);
-    document->styleSheetCollection()->addPendingSheet();
+    document->styleSheetCollections()->addPendingSheet();
 }
 
 }
diff --git a/Source/core/dom/StyleSheetCollection.cpp b/Source/core/dom/StyleSheetCollection.cpp
index a665b80..8a2b102 100644
--- a/Source/core/dom/StyleSheetCollection.cpp
+++ b/Source/core/dom/StyleSheetCollection.cpp
@@ -27,27 +27,18 @@
 #include "config.h"
 #include "core/dom/StyleSheetCollection.h"
 
-#include "HTMLNames.h"
-#include "SVGNames.h"
 #include "core/css/CSSStyleSheet.h"
 #include "core/css/StyleInvalidationAnalysis.h"
 #include "core/css/StyleSheetContents.h"
 #include "core/css/resolver/StyleResolver.h"
 #include "core/dom/Document.h"
-#include "core/dom/DocumentStyleSheetCollection.h"
 #include "core/dom/Element.h"
-#include "core/dom/ProcessingInstruction.h"
-#include "core/dom/shadow/ShadowRoot.h"
-#include "core/html/HTMLIFrameElement.h"
-#include "core/html/HTMLLinkElement.h"
+#include "core/dom/StyleSheetCollections.h"
 #include "core/html/HTMLStyleElement.h"
 #include "core/page/Settings.h"
-#include "core/svg/SVGStyleElement.h"
 
 namespace WebCore {
 
-using namespace HTMLNames;
-
 StyleSheetCollection::StyleSheetCollection(TreeScope* treeScope)
     : m_treeScope(treeScope)
     , m_hadActiveLoadingStylesheet(false)
@@ -186,142 +177,4 @@
     m_usesRemUnits = styleSheetsUseRemUnits(m_activeAuthorStyleSheets);
 }
 
-StyleSheetCollectionForDocument::StyleSheetCollectionForDocument(TreeScope* treeScope)
-    : StyleSheetCollection(treeScope)
-{
-    ASSERT(treeScope->rootNode() == treeScope->rootNode()->document());
-}
-
-void StyleSheetCollectionForDocument::collectStyleSheets(DocumentStyleSheetCollection* collections, Vector<RefPtr<StyleSheet> >& styleSheets, Vector<RefPtr<CSSStyleSheet> >& activeSheets)
-{
-    if (document()->settings() && !document()->settings()->authorAndUserStylesEnabled())
-        return;
-
-    DocumentOrderedList::iterator begin = m_styleSheetCandidateNodes.begin();
-    DocumentOrderedList::iterator end = m_styleSheetCandidateNodes.end();
-    for (DocumentOrderedList::iterator it = begin; it != end; ++it) {
-        Node* n = *it;
-        StyleSheet* sheet = 0;
-        CSSStyleSheet* activeSheet = 0;
-        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);
-            // 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.
-                if (!document()->parsing() && !pi->isLoading())
-                    document()->applyXSLTransform(pi);
-                return;
-            }
-            sheet = pi->sheet();
-            if (sheet && !sheet->disabled() && sheet->isCSSStyleSheet())
-                activeSheet = static_cast<CSSStyleSheet*>(sheet);
-        } else if ((n->isHTMLElement() && (n->hasTagName(linkTag) || n->hasTagName(styleTag))) || (n->isSVGElement() && n->hasTagName(SVGNames::styleTag))) {
-            Element* e = toElement(n);
-            AtomicString title = e->getAttribute(titleAttr);
-            bool enabledViaScript = false;
-            if (e->hasLocalName(linkTag)) {
-                // <LINK> element
-                HTMLLinkElement* linkElement = toHTMLLinkElement(n);
-                enabledViaScript = linkElement->isEnabledViaScript();
-                if (!linkElement->isDisabled() && linkElement->styleSheetIsLoading()) {
-                    // it is loading but we should still decide which style sheet set to use
-                    if (!enabledViaScript && !title.isEmpty() && collections->preferredStylesheetSetName().isEmpty()) {
-                        const AtomicString& rel = e->getAttribute(relAttr);
-                        if (!rel.contains("alternate")) {
-                            collections->setPreferredStylesheetSetName(title);
-                            collections->setSelectedStylesheetSetName(title);
-                        }
-                    }
-
-                    continue;
-                }
-                sheet = linkElement->sheet();
-                if (!sheet)
-                    title = nullAtom;
-            } else if (n->isSVGElement() && n->hasTagName(SVGNames::styleTag)) {
-                sheet = static_cast<SVGStyleElement*>(n)->sheet();
-            } else {
-                sheet = static_cast<HTMLStyleElement*>(n)->sheet();
-            }
-
-            if (sheet && !sheet->disabled() && sheet->isCSSStyleSheet())
-                activeSheet = static_cast<CSSStyleSheet*>(sheet);
-
-            // Check to see if this sheet belongs to a styleset
-            // (thus making it PREFERRED or ALTERNATE rather than
-            // PERSISTENT).
-            AtomicString rel = e->getAttribute(relAttr);
-            if (!enabledViaScript && sheet && !title.isEmpty()) {
-                // Yes, we have a title.
-                if (collections->preferredStylesheetSetName().isEmpty()) {
-                    // No preferred set has been established. If
-                    // we are NOT an alternate sheet, then establish
-                    // us as the preferred set. Otherwise, just ignore
-                    // this sheet.
-                    if (e->hasLocalName(styleTag) || !rel.contains("alternate")) {
-                        collections->setPreferredStylesheetSetName(title);
-                        collections->setSelectedStylesheetSetName(title);
-                    }
-                }
-                if (title != collections->preferredStylesheetSetName())
-                    activeSheet = 0;
-            }
-
-            if (rel.contains("alternate") && title.isEmpty())
-                activeSheet = 0;
-        }
-        if (sheet)
-            styleSheets.append(sheet);
-        if (activeSheet)
-            activeSheets.append(activeSheet);
-    }
-}
-
-static void collectActiveCSSStyleSheetsFromSeamlessParents(Vector<RefPtr<CSSStyleSheet> >& sheets, Document* document)
-{
-    HTMLIFrameElement* seamlessParentIFrame = document->seamlessParentIFrame();
-    if (!seamlessParentIFrame)
-        return;
-    sheets.append(seamlessParentIFrame->document()->styleSheetCollection()->activeAuthorStyleSheets());
-}
-
-bool StyleSheetCollectionForDocument::updateActiveStyleSheets(DocumentStyleSheetCollection* collections, StyleResolverUpdateMode updateMode)
-{
-    Vector<RefPtr<StyleSheet> > styleSheets;
-    Vector<RefPtr<CSSStyleSheet> > activeCSSStyleSheets;
-    activeCSSStyleSheets.append(collections->injectedAuthorStyleSheets());
-    activeCSSStyleSheets.append(collections->documentAuthorStyleSheets());
-    collectActiveCSSStyleSheetsFromSeamlessParents(activeCSSStyleSheets, document());
-    collectStyleSheets(collections, styleSheets, activeCSSStyleSheets);
-
-    StyleResolverUpdateType styleResolverUpdateType;
-    bool requiresFullStyleRecalc;
-    analyzeStyleSheetChange(updateMode, activeAuthorStyleSheets(), activeCSSStyleSheets, styleResolverUpdateType, requiresFullStyleRecalc);
-
-    if (styleResolverUpdateType == Reconstruct) {
-        document()->clearStyleResolver();
-    } else {
-        StyleResolver* styleResolver = document()->styleResolverIfExists();
-        ASSERT(styleResolver);
-        // FIXME: We might have already had styles in child treescope. In this case, we cannot use buildScopedStyleTreeInDocumentOrder.
-        // Need to change "false" to some valid condition.
-        styleResolver->setBuildScopedStyleTreeInDocumentOrder(false);
-        if (styleResolverUpdateType == Reset) {
-            resetAllRuleSetsInTreeScope(styleResolver);
-            styleResolver->appendAuthorStyleSheets(0, activeCSSStyleSheets);
-        } else {
-            ASSERT(styleResolverUpdateType == Additive);
-            styleResolver->appendAuthorStyleSheets(m_activeAuthorStyleSheets.size(), activeCSSStyleSheets);
-        }
-    }
-    m_scopingNodesForStyleScoped.didRemoveScopingNodes();
-    m_activeAuthorStyleSheets.swap(activeCSSStyleSheets);
-    m_styleSheetsForStyleSheetList.swap(styleSheets);
-    updateUsesRemUnits();
-
-    return requiresFullStyleRecalc;
-}
-
 }
diff --git a/Source/core/dom/StyleSheetCollection.h b/Source/core/dom/StyleSheetCollection.h
index ce41034..5fc6111 100644
--- a/Source/core/dom/StyleSheetCollection.h
+++ b/Source/core/dom/StyleSheetCollection.h
@@ -43,7 +43,7 @@
 
 class ContainerNode;
 class CSSStyleSheet;
-class DocumentStyleSheetCollection;
+class StyleSheetCollections;
 class Node;
 class StyleSheet;
 class StyleSheetContents;
@@ -97,18 +97,6 @@
     StyleSheetScopingNodeList m_scopingNodesForStyleScoped;
 };
 
-// FIXME: rename this class to DocumentStyleSheetCollection.
-class StyleSheetCollectionForDocument FINAL : public StyleSheetCollection {
-    WTF_MAKE_NONCOPYABLE(StyleSheetCollectionForDocument); WTF_MAKE_FAST_ALLOCATED;
-public:
-    explicit StyleSheetCollectionForDocument(TreeScope*);
-
-    bool updateActiveStyleSheets(DocumentStyleSheetCollection*, StyleResolverUpdateMode);
-
-private:
-    void collectStyleSheets(DocumentStyleSheetCollection*, Vector<RefPtr<StyleSheet> >& styleSheets, Vector<RefPtr<CSSStyleSheet> >& activeSheets);
-};
-
 }
 
 #endif
diff --git a/Source/core/dom/StyleSheetCollections.cpp b/Source/core/dom/StyleSheetCollections.cpp
new file mode 100644
index 0000000..7a4ae2e
--- /dev/null
+++ b/Source/core/dom/StyleSheetCollections.cpp
@@ -0,0 +1,458 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ *           (C) 1999 Antti Koivisto (koivisto@kde.org)
+ *           (C) 2001 Dirk Mueller (mueller@kde.org)
+ *           (C) 2006 Alexey Proskuryakov (ap@webkit.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2008, 2009, 2011, 2012 Google Inc. All rights reserved.
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) Research In Motion Limited 2010-2011. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "core/dom/StyleSheetCollections.h"
+
+#include "HTMLNames.h"
+#include "SVGNames.h"
+#include "core/css/CSSStyleSheet.h"
+#include "core/css/StyleInvalidationAnalysis.h"
+#include "core/css/StyleSheetContents.h"
+#include "core/css/resolver/StyleResolver.h"
+#include "core/dom/Document.h"
+#include "core/dom/Element.h"
+#include "core/dom/ProcessingInstruction.h"
+#include "core/dom/ShadowTreeStyleSheetCollection.h"
+#include "core/dom/shadow/ShadowRoot.h"
+#include "core/html/HTMLIFrameElement.h"
+#include "core/html/HTMLLinkElement.h"
+#include "core/html/HTMLStyleElement.h"
+#include "core/page/Page.h"
+#include "core/page/PageGroup.h"
+#include "core/page/Settings.h"
+#include "core/page/UserContentURLPattern.h"
+#include "core/svg/SVGStyleElement.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+StyleSheetCollections::StyleSheetCollections(Document* document)
+    : m_document(document)
+    , m_pendingStylesheets(0)
+    , m_injectedStyleSheetCacheValid(false)
+    , m_needsUpdateActiveStylesheetsOnStyleRecalc(false)
+    , m_usesSiblingRules(false)
+    , m_usesSiblingRulesOverride(false)
+    , m_usesFirstLineRules(false)
+    , m_usesFirstLetterRules(false)
+    , m_usesRemUnits(false)
+    , m_documentStyleSheetCollection(document)
+    , m_needsDocumentStyleSheetsUpdate(true)
+{
+}
+
+StyleSheetCollections::~StyleSheetCollections()
+{
+    if (m_pageUserSheet)
+        m_pageUserSheet->clearOwnerNode();
+    for (unsigned i = 0; i < m_injectedUserStyleSheets.size(); ++i)
+        m_injectedUserStyleSheets[i]->clearOwnerNode();
+    for (unsigned i = 0; i < m_injectedAuthorStyleSheets.size(); ++i)
+        m_injectedAuthorStyleSheets[i]->clearOwnerNode();
+    for (unsigned i = 0; i < m_userStyleSheets.size(); ++i)
+        m_userStyleSheets[i]->clearOwnerNode();
+    for (unsigned i = 0; i < m_authorStyleSheets.size(); ++i)
+        m_authorStyleSheets[i]->clearOwnerNode();
+}
+
+void StyleSheetCollections::insertTreeScopeInDocumentOrder(TreeScopeSet& treeScopes, TreeScope* treeScope)
+{
+    if (treeScopes.isEmpty()) {
+        treeScopes.add(treeScope);
+        return;
+    }
+    if (treeScopes.contains(treeScope))
+        return;
+
+    TreeScopeSet::iterator begin = treeScopes.begin();
+    TreeScopeSet::iterator end = treeScopes.end();
+    TreeScopeSet::iterator it = end;
+    TreeScope* followingTreeScope = 0;
+    do {
+        --it;
+        TreeScope* n = *it;
+        unsigned short position = n->comparePosition(treeScope);
+        if (position & Node::DOCUMENT_POSITION_FOLLOWING) {
+            treeScopes.insertBefore(followingTreeScope, treeScope);
+            return;
+        }
+        followingTreeScope = n;
+    } while (it != begin);
+
+    treeScopes.insertBefore(followingTreeScope, treeScope);
+}
+
+StyleSheetCollection* StyleSheetCollections::ensureStyleSheetCollectionFor(TreeScope* treeScope)
+{
+    if (treeScope == m_document)
+        return &m_documentStyleSheetCollection;
+
+    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)
+{
+    if (treeScope == m_document)
+        return &m_documentStyleSheetCollection;
+
+    HashMap<TreeScope*, OwnPtr<StyleSheetCollection> >::iterator it = m_styleSheetCollectionMap.find(treeScope);
+    if (it == m_styleSheetCollectionMap.end())
+        return 0;
+    return it->value.get();
+}
+
+const Vector<RefPtr<StyleSheet> >& StyleSheetCollections::styleSheetsForStyleSheetList()
+{
+    return m_documentStyleSheetCollection.styleSheetsForStyleSheetList();
+}
+
+const Vector<RefPtr<CSSStyleSheet> >& StyleSheetCollections::activeAuthorStyleSheets() const
+{
+    return m_documentStyleSheetCollection.activeAuthorStyleSheets();
+}
+
+void StyleSheetCollections::getActiveAuthorStyleSheets(Vector<const Vector<RefPtr<CSSStyleSheet> >*>& activeAuthorStyleSheets) const
+{
+    activeAuthorStyleSheets.append(&m_documentStyleSheetCollection.activeAuthorStyleSheets());
+
+    HashMap<TreeScope*, OwnPtr<StyleSheetCollection> >::const_iterator::Values begin = m_styleSheetCollectionMap.values().begin();
+    HashMap<TreeScope*, OwnPtr<StyleSheetCollection> >::const_iterator::Values end = m_styleSheetCollectionMap.values().end();
+    HashMap<TreeScope*, OwnPtr<StyleSheetCollection> >::const_iterator::Values it = begin;
+    for (; it != end; ++it) {
+        const StyleSheetCollection* collection = it->get();
+        activeAuthorStyleSheets.append(&collection->activeAuthorStyleSheets());
+    }
+}
+
+void StyleSheetCollections::combineCSSFeatureFlags(const RuleFeatureSet& features)
+{
+    // Delay resetting the flags until after next style recalc since unapplying the style may not work without these set (this is true at least with before/after).
+    m_usesSiblingRules = m_usesSiblingRules || features.usesSiblingRules();
+    m_usesFirstLineRules = m_usesFirstLineRules || features.usesFirstLineRules();
+}
+
+void StyleSheetCollections::resetCSSFeatureFlags(const RuleFeatureSet& features)
+{
+    m_usesSiblingRules = features.usesSiblingRules();
+    m_usesFirstLineRules = features.usesFirstLineRules();
+}
+
+CSSStyleSheet* StyleSheetCollections::pageUserSheet()
+{
+    if (m_pageUserSheet)
+        return m_pageUserSheet.get();
+
+    Page* owningPage = m_document->page();
+    if (!owningPage)
+        return 0;
+
+    String userSheetText = owningPage->userStyleSheet();
+    if (userSheetText.isEmpty())
+        return 0;
+
+    // Parse the sheet and cache it.
+    m_pageUserSheet = CSSStyleSheet::createInline(m_document, m_document->settings()->userStyleSheetLocation());
+    m_pageUserSheet->contents()->setIsUserStyleSheet(true);
+    m_pageUserSheet->contents()->parseString(userSheetText);
+    return m_pageUserSheet.get();
+}
+
+void StyleSheetCollections::clearPageUserSheet()
+{
+    if (m_pageUserSheet) {
+        RefPtr<StyleSheet> removedSheet = m_pageUserSheet;
+        m_pageUserSheet = 0;
+        m_document->removedStyleSheet(removedSheet.get());
+    }
+}
+
+void StyleSheetCollections::updatePageUserSheet()
+{
+    clearPageUserSheet();
+    // FIXME: Why is this immediately and not defer?
+    if (StyleSheet* addedSheet = pageUserSheet())
+        m_document->addedStyleSheet(addedSheet, RecalcStyleImmediately);
+}
+
+const Vector<RefPtr<CSSStyleSheet> >& StyleSheetCollections::injectedUserStyleSheets() const
+{
+    updateInjectedStyleSheetCache();
+    return m_injectedUserStyleSheets;
+}
+
+const Vector<RefPtr<CSSStyleSheet> >& StyleSheetCollections::injectedAuthorStyleSheets() const
+{
+    updateInjectedStyleSheetCache();
+    return m_injectedAuthorStyleSheets;
+}
+
+void StyleSheetCollections::updateInjectedStyleSheetCache() const
+{
+    if (m_injectedStyleSheetCacheValid)
+        return;
+    m_injectedStyleSheetCacheValid = true;
+    m_injectedUserStyleSheets.clear();
+    m_injectedAuthorStyleSheets.clear();
+
+    Page* owningPage = m_document->page();
+    if (!owningPage)
+        return;
+
+    const PageGroup& pageGroup = owningPage->group();
+    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())
+            continue;
+        if (!UserContentURLPattern::matchesPatterns(m_document->url(), sheet->whitelist(), sheet->blacklist()))
+            continue;
+        RefPtr<CSSStyleSheet> groupSheet = CSSStyleSheet::createInline(const_cast<Document*>(m_document), sheet->url());
+        bool isUserStyleSheet = sheet->level() == UserStyleUserLevel;
+        if (isUserStyleSheet)
+            m_injectedUserStyleSheets.append(groupSheet);
+        else
+            m_injectedAuthorStyleSheets.append(groupSheet);
+        groupSheet->contents()->setIsUserStyleSheet(isUserStyleSheet);
+        groupSheet->contents()->parseString(sheet->source());
+    }
+}
+
+void StyleSheetCollections::invalidateInjectedStyleSheetCache()
+{
+    m_injectedStyleSheetCacheValid = false;
+    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);
+}
+
+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_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_needsDocumentStyleSheetsUpdate = true;
+}
+
+// This method is called whenever a top-level stylesheet has finished loading.
+void StyleSheetCollections::removePendingSheet(Node* styleSheetCandidateNode, RemovePendingSheetNotificationType notification)
+{
+    // Make sure we knew this sheet was pending, and that our count isn't out of sync.
+    ASSERT(m_pendingStylesheets > 0);
+
+    m_pendingStylesheets--;
+
+    TreeScope* treeScope = isHTMLStyleElement(styleSheetCandidateNode) ? styleSheetCandidateNode->treeScope() : m_document;
+    if (treeScope == m_document)
+        m_needsDocumentStyleSheetsUpdate = true;
+    else
+        m_dirtyTreeScopes.add(treeScope);
+
+    if (m_pendingStylesheets)
+        return;
+
+    if (notification == RemovePendingSheetNotifyLater) {
+        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();
+}
+
+void StyleSheetCollections::addStyleSheetCandidateNode(Node* node, bool createdByParser)
+{
+    if (!node->inDocument())
+        return;
+
+    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) {
+        m_needsDocumentStyleSheetsUpdate = true;
+        return;
+    }
+
+    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);
+
+    StyleSheetCollection* collection = styleSheetCollectionFor(treeScope);
+    ASSERT(collection);
+    collection->removeStyleSheetCandidateNode(node, scopingNode);
+
+    if (treeScope == m_document) {
+        m_needsDocumentStyleSheetsUpdate = true;
+        return;
+    }
+    m_dirtyTreeScopes.add(treeScope);
+    m_activeTreeScopes.remove(treeScope);
+}
+
+void StyleSheetCollections::modifiedStyleSheetCandidateNode(Node* node)
+{
+    if (!node->inDocument())
+        return;
+
+    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);
+}
+
+bool StyleSheetCollections::shouldUpdateShadowTreeStyleSheetCollection(StyleResolverUpdateMode updateMode)
+{
+    return !m_dirtyTreeScopes.isEmpty() || updateMode == FullStyleUpdate;
+}
+
+bool StyleSheetCollections::updateActiveStyleSheets(StyleResolverUpdateMode updateMode)
+{
+    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).
+        m_needsUpdateActiveStylesheetsOnStyleRecalc = true;
+        return false;
+
+    }
+    if (!m_document->renderer() || !m_document->attached())
+        return false;
+
+    bool requiresFullStyleRecalc = false;
+    if (m_needsDocumentStyleSheetsUpdate || updateMode == FullStyleUpdate)
+        requiresFullStyleRecalc = m_documentStyleSheetCollection.updateActiveStyleSheets(this, updateMode);
+
+    if (shouldUpdateShadowTreeStyleSheetCollection(updateMode)) {
+        TreeScopeSet treeScopes = updateMode == FullStyleUpdate ? m_activeTreeScopes : m_dirtyTreeScopes;
+        HashSet<TreeScope*> treeScopesRemoved;
+
+        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(collection);
+            collection->updateActiveStyleSheets(this, updateMode);
+            if (!collection->hasStyleSheetCandidateNodes())
+                treeScopesRemoved.add(treeScope);
+        }
+        if (!treeScopesRemoved.isEmpty())
+            for (HashSet<TreeScope*>::iterator it = treeScopesRemoved.begin(); it != treeScopesRemoved.end(); ++it)
+                m_activeTreeScopes.remove(*it);
+        m_dirtyTreeScopes.clear();
+    }
+
+    if (StyleResolver* styleResolver = m_document->styleResolverIfExists()) {
+        styleResolver->finishAppendAuthorStyleSheets();
+        resetCSSFeatureFlags(styleResolver->ruleFeatureSet());
+    }
+
+    m_needsUpdateActiveStylesheetsOnStyleRecalc = false;
+    activeStyleSheetsUpdatedForInspector();
+    m_usesRemUnits = m_documentStyleSheetCollection.usesRemUnits();
+
+    if (m_needsDocumentStyleSheetsUpdate || updateMode == FullStyleUpdate) {
+        m_document->notifySeamlessChildDocumentsOfStylesheetUpdate();
+        m_needsDocumentStyleSheetsUpdate = false;
+    }
+
+    return requiresFullStyleRecalc;
+}
+
+void StyleSheetCollections::activeStyleSheetsUpdatedForInspector()
+{
+    if (m_activeTreeScopes.isEmpty()) {
+        InspectorInstrumentation::activeStyleSheetsUpdated(m_document, m_documentStyleSheetCollection.styleSheetsForStyleSheetList());
+        return;
+    }
+    Vector<RefPtr<StyleSheet> > activeStyleSheets;
+
+    activeStyleSheets.append(m_documentStyleSheetCollection.styleSheetsForStyleSheetList());
+
+    TreeScopeSet::iterator begin = m_activeTreeScopes.begin();
+    TreeScopeSet::iterator end = m_activeTreeScopes.end();
+    for (TreeScopeSet::iterator it = begin; it != end; ++it) {
+        if (StyleSheetCollection* collection = m_styleSheetCollectionMap.get(*it))
+            activeStyleSheets.append(collection->styleSheetsForStyleSheetList());
+    }
+
+    // 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);
+}
+
+void StyleSheetCollections::didRemoveShadowRoot(ShadowRoot* shadowRoot)
+{
+    m_styleSheetCollectionMap.remove(shadowRoot);
+}
+
+void StyleSheetCollections::appendActiveAuthorStyleSheets(StyleResolver* styleResolver)
+{
+    ASSERT(styleResolver);
+
+    styleResolver->setBuildScopedStyleTreeInDocumentOrder(true);
+    styleResolver->appendAuthorStyleSheets(0, m_documentStyleSheetCollection.activeAuthorStyleSheets());
+
+    TreeScopeSet::iterator begin = m_activeTreeScopes.begin();
+    TreeScopeSet::iterator end = m_activeTreeScopes.end();
+    for (TreeScopeSet::iterator it = begin; it != end; ++it) {
+        if (StyleSheetCollection* collection = m_styleSheetCollectionMap.get(*it)) {
+            styleResolver->setBuildScopedStyleTreeInDocumentOrder(!collection->scopingNodesForStyleScoped());
+            styleResolver->appendAuthorStyleSheets(0, collection->activeAuthorStyleSheets());
+        }
+    }
+    styleResolver->finishAppendAuthorStyleSheets();
+    styleResolver->setBuildScopedStyleTreeInDocumentOrder(false);
+}
+
+}
diff --git a/Source/core/dom/StyleSheetCollections.h b/Source/core/dom/StyleSheetCollections.h
new file mode 100644
index 0000000..e934e51
--- /dev/null
+++ b/Source/core/dom/StyleSheetCollections.h
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ *           (C) 1999 Antti Koivisto (koivisto@kde.org)
+ *           (C) 2001 Dirk Mueller (mueller@kde.org)
+ *           (C) 2006 Alexey Proskuryakov (ap@webkit.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef StyleSheetCollections_h
+#define StyleSheetCollections_h
+
+#include "core/dom/Document.h"
+#include "core/dom/DocumentOrderedList.h"
+#include "core/dom/DocumentStyleSheetCollection.h"
+#include "wtf/FastAllocBase.h"
+#include "wtf/ListHashSet.h"
+#include "wtf/RefPtr.h"
+#include "wtf/Vector.h"
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+class CSSStyleSheet;
+class Node;
+class RuleFeatureSet;
+class ShadowTreeStyleSheetCollection;
+class StyleSheet;
+class StyleSheetCollection;
+class StyleSheetContents;
+class StyleSheetList;
+
+class StyleSheetCollections {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    static PassOwnPtr<StyleSheetCollections> create(Document* document) { return adoptPtr(new StyleSheetCollections(document)); }
+
+    ~StyleSheetCollections();
+
+    const Vector<RefPtr<StyleSheet> >& styleSheetsForStyleSheetList();
+    const Vector<RefPtr<CSSStyleSheet> >& activeAuthorStyleSheets() const;
+
+    CSSStyleSheet* pageUserSheet();
+    const Vector<RefPtr<CSSStyleSheet> >& documentUserStyleSheets() const { return m_userStyleSheets; }
+    const Vector<RefPtr<CSSStyleSheet> >& documentAuthorStyleSheets() const { return m_authorStyleSheets; }
+    const Vector<RefPtr<CSSStyleSheet> >& injectedUserStyleSheets() const;
+    const Vector<RefPtr<CSSStyleSheet> >& injectedAuthorStyleSheets() const;
+
+    void addStyleSheetCandidateNode(Node*, bool createdByParser);
+    void removeStyleSheetCandidateNode(Node*, ContainerNode* scopingNode = 0);
+    void modifiedStyleSheetCandidateNode(Node*);
+
+    void clearPageUserSheet();
+    void updatePageUserSheet();
+    void invalidateInjectedStyleSheetCache();
+    void updateInjectedStyleSheetCache() const;
+
+    void addAuthorSheet(PassRefPtr<StyleSheetContents> authorSheet);
+    void addUserSheet(PassRefPtr<StyleSheetContents> userSheet);
+
+    bool needsUpdateActiveStylesheetsOnStyleRecalc() const { return m_needsUpdateActiveStylesheetsOnStyleRecalc; }
+
+    bool updateActiveStyleSheets(StyleResolverUpdateMode);
+
+    String preferredStylesheetSetName() const { return m_preferredStylesheetSetName; }
+    String selectedStylesheetSetName() const { return m_selectedStylesheetSetName; }
+    void setPreferredStylesheetSetName(const String& name) { m_preferredStylesheetSetName = name; }
+    void setSelectedStylesheetSetName(const String& name) { m_selectedStylesheetSetName = name; }
+
+    void addPendingSheet() { m_pendingStylesheets++; }
+    enum RemovePendingSheetNotificationType {
+        RemovePendingSheetNotifyImmediately,
+        RemovePendingSheetNotifyLater
+    };
+    void removePendingSheet(Node* styleSheetCandidateNode, RemovePendingSheetNotificationType = RemovePendingSheetNotifyImmediately);
+
+    bool hasPendingSheets() const { return m_pendingStylesheets > 0; }
+
+    bool usesSiblingRules() const { return m_usesSiblingRules || m_usesSiblingRulesOverride; }
+    void setUsesSiblingRulesOverride(bool b) { m_usesSiblingRulesOverride = b; }
+    bool usesFirstLineRules() const { return m_usesFirstLineRules; }
+    bool usesFirstLetterRules() const { return m_usesFirstLetterRules; }
+    void setUsesFirstLetterRules(bool b) { m_usesFirstLetterRules = b; }
+    bool usesRemUnits() const { return m_usesRemUnits; }
+    void setUsesRemUnit(bool b) { m_usesRemUnits = b; }
+    bool hasScopedStyleSheet() { return m_documentStyleSheetCollection.scopingNodesForStyleScoped(); }
+
+    void combineCSSFeatureFlags(const RuleFeatureSet&);
+    void resetCSSFeatureFlags(const RuleFeatureSet&);
+
+    void didModifySeamlessParentStyleSheet() { m_needsDocumentStyleSheetsUpdate = true; }
+    void didRemoveShadowRoot(ShadowRoot*);
+    void appendActiveAuthorStyleSheets(StyleResolver*);
+    void getActiveAuthorStyleSheets(Vector<const Vector<RefPtr<CSSStyleSheet> >*>& activeAuthorStyleSheets) const;
+
+private:
+    StyleSheetCollections(Document*);
+
+    StyleSheetCollection* ensureStyleSheetCollectionFor(TreeScope*);
+    StyleSheetCollection* styleSheetCollectionFor(TreeScope*);
+    void activeStyleSheetsUpdatedForInspector();
+    bool shouldUpdateShadowTreeStyleSheetCollection(StyleResolverUpdateMode);
+
+    typedef ListHashSet<TreeScope*, 16> TreeScopeSet;
+    static void insertTreeScopeInDocumentOrder(TreeScopeSet&, TreeScope*);
+
+    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.
+    // We use this count of pending sheets to detect when we can begin attaching
+    // elements and when it is safe to execute scripts.
+    int m_pendingStylesheets;
+
+    RefPtr<CSSStyleSheet> m_pageUserSheet;
+
+    mutable Vector<RefPtr<CSSStyleSheet> > m_injectedUserStyleSheets;
+    mutable Vector<RefPtr<CSSStyleSheet> > m_injectedAuthorStyleSheets;
+    mutable bool m_injectedStyleSheetCacheValid;
+
+    Vector<RefPtr<CSSStyleSheet> > m_userStyleSheets;
+    Vector<RefPtr<CSSStyleSheet> > m_authorStyleSheets;
+
+    bool m_needsUpdateActiveStylesheetsOnStyleRecalc;
+
+    DocumentStyleSheetCollection m_documentStyleSheetCollection;
+    HashMap<TreeScope*, OwnPtr<StyleSheetCollection> > m_styleSheetCollectionMap;
+
+    TreeScopeSet m_dirtyTreeScopes;
+    TreeScopeSet m_activeTreeScopes;
+    bool m_needsDocumentStyleSheetsUpdate;
+
+    String m_preferredStylesheetSetName;
+    String m_selectedStylesheetSetName;
+
+    bool m_usesSiblingRules;
+    bool m_usesSiblingRulesOverride;
+    bool m_usesFirstLineRules;
+    bool m_usesFirstLetterRules;
+    bool m_usesRemUnits;
+};
+
+}
+
+#endif
+
diff --git a/Source/core/dom/TextLinkColors.cpp b/Source/core/dom/TextLinkColors.cpp
index 59589a5..a48f731 100644
--- a/Source/core/dom/TextLinkColors.cpp
+++ b/Source/core/dom/TextLinkColors.cpp
@@ -91,7 +91,7 @@
         if (col->cssValueId == cssValueId)
             return col->color;
     }
-    return RenderTheme::defaultTheme()->systemColor(cssValueId);
+    return RenderTheme::theme().systemColor(cssValueId);
 }
 
 StyleColor TextLinkColors::colorFromPrimitiveValue(const CSSPrimitiveValue* value, bool forVisitedLink) const
diff --git a/Source/core/dom/AnimationEvent.cpp b/Source/core/dom/WebKitAnimationEvent.cpp
similarity index 75%
rename from Source/core/dom/AnimationEvent.cpp
rename to Source/core/dom/WebKitAnimationEvent.cpp
index b583c06..777a5a4 100644
--- a/Source/core/dom/AnimationEvent.cpp
+++ b/Source/core/dom/WebKitAnimationEvent.cpp
@@ -24,25 +24,25 @@
  */
 
 #include "config.h"
-#include "core/dom/AnimationEvent.h"
+#include "core/dom/WebKitAnimationEvent.h"
 
 #include "core/dom/EventNames.h"
 
 namespace WebCore {
 
-AnimationEventInit::AnimationEventInit()
+WebKitAnimationEventInit::WebKitAnimationEventInit()
     : animationName()
     , elapsedTime(0.0)
 {
 }
 
-AnimationEvent::AnimationEvent()
+WebKitAnimationEvent::WebKitAnimationEvent()
     : m_elapsedTime(0.0)
 {
     ScriptWrappable::init(this);
 }
 
-AnimationEvent::AnimationEvent(const AtomicString& type, const AnimationEventInit& initializer)
+WebKitAnimationEvent::WebKitAnimationEvent(const AtomicString& type, const WebKitAnimationEventInit& initializer)
     : Event(type, initializer)
     , m_animationName(initializer.animationName)
     , m_elapsedTime(initializer.elapsedTime)
@@ -50,7 +50,7 @@
     ScriptWrappable::init(this);
 }
 
-AnimationEvent::AnimationEvent(const AtomicString& type, const String& animationName, double elapsedTime)
+WebKitAnimationEvent::WebKitAnimationEvent(const AtomicString& type, const String& animationName, double elapsedTime)
     : Event(type, true, true)
     , m_animationName(animationName)
     , m_elapsedTime(elapsedTime)
@@ -58,23 +58,23 @@
     ScriptWrappable::init(this);
 }
 
-AnimationEvent::~AnimationEvent()
+WebKitAnimationEvent::~WebKitAnimationEvent()
 {
 }
 
-const String& AnimationEvent::animationName() const
+const String& WebKitAnimationEvent::animationName() const
 {
     return m_animationName;
 }
 
-double AnimationEvent::elapsedTime() const
+double WebKitAnimationEvent::elapsedTime() const
 {
     return m_elapsedTime;
 }
 
-const AtomicString& AnimationEvent::interfaceName() const
+const AtomicString& WebKitAnimationEvent::interfaceName() const
 {
-    return eventNames().interfaceForAnimationEvent;
+    return eventNames().interfaceForWebKitAnimationEvent;
 }
 
 } // namespace WebCore
diff --git a/Source/core/dom/WebKitAnimationEvent.h b/Source/core/dom/WebKitAnimationEvent.h
new file mode 100644
index 0000000..8f642bf
--- /dev/null
+++ b/Source/core/dom/WebKitAnimationEvent.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebKitAnimationEvent_h
+#define WebKitAnimationEvent_h
+
+#include "core/dom/Event.h"
+
+namespace WebCore {
+
+// FIXME : This class has a WebKit prefix on purpose so we can use the EventAliases system. When the
+// runtime flag of unprefixed animation will be removed we can rename that class and do the same as
+// the CSS Transitions.
+struct WebKitAnimationEventInit : public EventInit {
+    WebKitAnimationEventInit();
+
+    String animationName;
+    double elapsedTime;
+};
+
+class WebKitAnimationEvent : public Event {
+public:
+    static PassRefPtr<WebKitAnimationEvent> create()
+    {
+        return adoptRef(new WebKitAnimationEvent);
+    }
+    static PassRefPtr<WebKitAnimationEvent> create(const AtomicString& type, const String& animationName, double elapsedTime)
+    {
+        return adoptRef(new WebKitAnimationEvent(type, animationName, elapsedTime));
+    }
+    static PassRefPtr<WebKitAnimationEvent> create(const AtomicString& type, const WebKitAnimationEventInit& initializer)
+    {
+        return adoptRef(new WebKitAnimationEvent(type, initializer));
+    }
+
+    virtual ~WebKitAnimationEvent();
+
+    const String& animationName() const;
+    double elapsedTime() const;
+
+    virtual const AtomicString& interfaceName() const;
+
+private:
+    WebKitAnimationEvent();
+    WebKitAnimationEvent(const AtomicString& type, const String& animationName, double elapsedTime);
+    WebKitAnimationEvent(const AtomicString&, const WebKitAnimationEventInit&);
+
+    String m_animationName;
+    double m_elapsedTime;
+};
+
+} // namespace WebCore
+
+#endif // WebKitAnimationEvent_h
diff --git a/Source/core/dom/WebKitAnimationEvent.idl b/Source/core/dom/WebKitAnimationEvent.idl
index e53b4e7..a168306 100644
--- a/Source/core/dom/WebKitAnimationEvent.idl
+++ b/Source/core/dom/WebKitAnimationEvent.idl
@@ -24,8 +24,7 @@
  */
 
 [
-    ConstructorTemplate=Event,
-    ImplementedAs=AnimationEvent
+    ConstructorTemplate=Event
 ] interface WebKitAnimationEvent : Event {
     [InitializedByEventConstructor] readonly attribute DOMString animationName;
     [InitializedByEventConstructor] readonly attribute double elapsedTime;
diff --git a/Source/core/dom/WheelEvent.cpp b/Source/core/dom/WheelEvent.cpp
index bcb3d69..f2b71f6 100644
--- a/Source/core/dom/WheelEvent.cpp
+++ b/Source/core/dom/WheelEvent.cpp
@@ -30,14 +30,6 @@
 
 namespace WebCore {
 
-static inline double wheelTicksToPixels(double ticks)
-{
-    // Make sure we use +0 for all zeros.
-    if (!ticks)
-        return 0;
-    return -ticks * WheelEvent::TickMultiplier;
-}
-
 WheelEventInit::WheelEventInit()
     : deltaX(0)
     , deltaY(0)
@@ -60,6 +52,7 @@
 
 WheelEvent::WheelEvent(const AtomicString& type, const WheelEventInit& initializer)
     : MouseEvent(type, initializer)
+    , m_wheelDelta(initializer.wheelDeltaX ? initializer.wheelDeltaX : -initializer.deltaX, initializer.wheelDeltaY ? initializer.wheelDeltaY : -initializer.deltaY)
     , m_deltaX(initializer.deltaX ? initializer.deltaX : -initializer.wheelDeltaX)
     , m_deltaY(initializer.deltaY ? initializer.deltaY : -initializer.wheelDeltaY)
     , m_deltaZ(initializer.deltaZ)
@@ -76,10 +69,10 @@
                  pageLocation.x(), pageLocation.y(),
                  0, 0,
                  ctrlKey, altKey, shiftKey, metaKey, 0, 0, 0, false)
-    , m_deltaX(wheelTicksToPixels(wheelTicks.x()))
-    , m_deltaY(wheelTicksToPixels(wheelTicks.y()))
-    , m_deltaZ(0) // FIXME: Not supported.
-    , m_rawDelta(roundedIntPoint(rawDelta))
+    , m_wheelDelta(wheelTicks.x() * TickMultiplier, wheelTicks.y() * TickMultiplier)
+    , m_deltaX(-rawDelta.x())
+    , m_deltaY(-rawDelta.y())
+    , m_deltaZ(0)
     , m_deltaMode(deltaMode)
     , m_directionInvertedFromDevice(directionInvertedFromDevice)
 {
@@ -101,9 +94,9 @@
     m_shiftKey = shiftKey;
     m_metaKey = metaKey;
 
-    m_deltaX = wheelTicksToPixels(rawDeltaX);
-    m_deltaY = wheelTicksToPixels(rawDeltaY);
-    m_rawDelta = IntPoint(rawDeltaX, rawDeltaY);
+    m_wheelDelta = IntPoint(rawDeltaX * TickMultiplier, rawDeltaY * TickMultiplier);
+    m_deltaX = -rawDeltaX;
+    m_deltaY = -rawDeltaY;
     m_deltaMode = DOM_DELTA_PIXEL;
     m_directionInvertedFromDevice = false;
 
diff --git a/Source/core/dom/WheelEvent.h b/Source/core/dom/WheelEvent.h
index 870c9b6..c393f37 100644
--- a/Source/core/dom/WheelEvent.h
+++ b/Source/core/dom/WheelEvent.h
@@ -85,11 +85,11 @@
     double deltaY() const { return m_deltaY; } // Positive when scrolling down.
     double deltaZ() const { return m_deltaZ; }
     int wheelDelta() const { return wheelDeltaY() ? wheelDeltaY() : wheelDeltaX(); } // Deprecated.
-    int wheelDeltaX() const { return -m_deltaX; } // Deprecated, negative when scrolling right.
-    int wheelDeltaY() const { return -m_deltaY; } // Deprecated, negative when scrolling down.
-    int rawDeltaX() const { return m_rawDelta.x(); }
-    int rawDeltaY() const { return m_rawDelta.y(); }
+    int wheelDeltaX() const { return m_wheelDelta.x(); } // Deprecated, negative when scrolling right.
+    int wheelDeltaY() const { return m_wheelDelta.y(); } // Deprecated, negative when scrolling down.
     unsigned deltaMode() const { return m_deltaMode; }
+    float ticksX() const { return static_cast<float>(m_wheelDelta.x()) / TickMultiplier; }
+    float ticksY() const { return static_cast<float>(m_wheelDelta.y()) / TickMultiplier; }
 
     bool webkitDirectionInvertedFromDevice() const { return m_directionInvertedFromDevice; }
 
@@ -103,10 +103,10 @@
         unsigned, PassRefPtr<AbstractView>, const IntPoint& screenLocation, const IntPoint& pageLocation,
         bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, bool directionInvertedFromDevice);
 
+    IntPoint m_wheelDelta;
     double m_deltaX;
     double m_deltaY;
     double m_deltaZ;
-    IntPoint m_rawDelta;
     unsigned m_deltaMode;
     bool m_directionInvertedFromDevice;
 };
diff --git a/Source/core/dom/default/chromium/PlatformMessagePortChannelChromium.h b/Source/core/dom/default/chromium/PlatformMessagePortChannelChromium.h
index f4b8373..7c54ada 100644
--- a/Source/core/dom/default/chromium/PlatformMessagePortChannelChromium.h
+++ b/Source/core/dom/default/chromium/PlatformMessagePortChannelChromium.h
@@ -31,11 +31,10 @@
 #ifndef PlatformMessagePortChannelChromium_h
 #define PlatformMessagePortChannelChromium_h
 
-
 #include "core/dom/MessagePortChannel.h"
 #include "public/platform/WebMessagePortChannelClient.h"
 #include "wtf/PassRefPtr.h"
-#include "wtf/Threading.h"
+#include "wtf/ThreadingPrimitives.h"
 
 namespace WebKit {
 class WebMessagePortChannel;
diff --git a/Source/core/dom/shadow/ComposedShadowTreeWalker.cpp b/Source/core/dom/shadow/ComposedTreeWalker.cpp
similarity index 81%
rename from Source/core/dom/shadow/ComposedShadowTreeWalker.cpp
rename to Source/core/dom/shadow/ComposedTreeWalker.cpp
index 80ff995..86f97ed 100644
--- a/Source/core/dom/shadow/ComposedShadowTreeWalker.cpp
+++ b/Source/core/dom/shadow/ComposedTreeWalker.cpp
@@ -26,7 +26,7 @@
  */
 
 #include "config.h"
-#include "core/dom/shadow/ComposedShadowTreeWalker.h"
+#include "core/dom/shadow/ComposedTreeWalker.h"
 
 #include "core/dom/Element.h"
 #include "core/dom/shadow/ElementShadow.h"
@@ -57,7 +57,7 @@
     return false;
 }
 
-Node* ComposedShadowTreeWalker::traverseChild(const Node* node, TraversalDirection direction) const
+Node* ComposedTreeWalker::traverseChild(const Node* node, TraversalDirection direction) const
 {
     ASSERT(node);
     if (canCrossUpperBoundary()) {
@@ -70,13 +70,13 @@
     return traverseLightChildren(node, direction);
 }
 
-Node* ComposedShadowTreeWalker::traverseLightChildren(const Node* node, TraversalDirection direction)
+Node* ComposedTreeWalker::traverseLightChildren(const Node* node, TraversalDirection direction)
 {
     ASSERT(node);
     return traverseSiblings(direction == TraversalDirectionForward ? node->firstChild() : node->lastChild(), direction);
 }
 
-Node* ComposedShadowTreeWalker::traverseSiblings(const Node* node, TraversalDirection direction)
+Node* ComposedTreeWalker::traverseSiblings(const Node* node, TraversalDirection direction)
 {
     for (const Node* sibling = node; sibling; sibling = (direction == TraversalDirectionForward ? sibling->nextSibling() : sibling->previousSibling())) {
         if (Node* found = traverseNode(sibling, direction))
@@ -85,7 +85,7 @@
     return 0;
 }
 
-Node* ComposedShadowTreeWalker::traverseNode(const Node* node, TraversalDirection direction)
+Node* ComposedTreeWalker::traverseNode(const Node* node, TraversalDirection direction)
 {
     ASSERT(node);
     if (!isActiveInsertionPoint(node))
@@ -96,7 +96,7 @@
     return traverseLightChildren(node, direction);
 }
 
-Node* ComposedShadowTreeWalker::traverseDistributedNodes(const Node* node, const InsertionPoint* insertionPoint, TraversalDirection direction)
+Node* ComposedTreeWalker::traverseDistributedNodes(const Node* node, const InsertionPoint* insertionPoint, TraversalDirection direction)
 {
     for (const Node* next = node; next; next = (direction == TraversalDirectionForward ? insertionPoint->nextTo(next) : insertionPoint->previousTo(next))) {
         if (Node* found = traverseNode(next, direction))
@@ -105,7 +105,7 @@
     return 0;
 }
 
-Node* ComposedShadowTreeWalker::traverseSiblingOrBackToInsertionPoint(const Node* node, TraversalDirection direction)
+Node* ComposedTreeWalker::traverseSiblingOrBackToInsertionPoint(const Node* node, TraversalDirection direction)
 {
     ASSERT(node);
 
@@ -121,7 +121,7 @@
     return traverseSiblingOrBackToInsertionPoint(insertionPoint, direction);
 }
 
-Node* ComposedShadowTreeWalker::traverseSiblingInCurrentTree(const Node* node, TraversalDirection direction)
+Node* ComposedTreeWalker::traverseSiblingInCurrentTree(const Node* node, TraversalDirection direction)
 {
     ASSERT(node);
     if (Node* found = traverseSiblings(direction == TraversalDirectionForward ? node->nextSibling() : node->previousSibling(), direction))
@@ -131,7 +131,7 @@
     return escapeFallbackContentElement(node, direction);
 }
 
-Node* ComposedShadowTreeWalker::traverseBackToYoungerShadowRoot(const Node* node, TraversalDirection direction)
+Node* ComposedTreeWalker::traverseBackToYoungerShadowRoot(const Node* node, TraversalDirection direction)
 {
     ASSERT(node);
     if (node->parentNode() && node->parentNode()->isShadowRoot()) {
@@ -145,7 +145,7 @@
     return 0;
 }
 
-inline Node* ComposedShadowTreeWalker::escapeFallbackContentElement(const Node* node, TraversalDirection direction)
+inline Node* ComposedTreeWalker::escapeFallbackContentElement(const Node* node, TraversalDirection direction)
 {
     ASSERT(node);
     if (node->parentNode() && isActiveInsertionPoint(node->parentNode()))
@@ -153,7 +153,7 @@
     return 0;
 }
 
-inline Node* ComposedShadowTreeWalker::traverseNodeEscapingFallbackContents(const Node* node, ParentTraversalDetails* details) const
+inline Node* ComposedTreeWalker::traverseNodeEscapingFallbackContents(const Node* node, ParentTraversalDetails* details) const
 {
     ASSERT(node);
     if (!node->isInsertionPoint())
@@ -165,7 +165,7 @@
 
 // FIXME: Use an iterative algorithm so that it can be inlined.
 // https://bugs.webkit.org/show_bug.cgi?id=90415
-Node* ComposedShadowTreeWalker::traverseParent(const Node* node, ParentTraversalDetails* details) const
+Node* ComposedTreeWalker::traverseParent(const Node* node, ParentTraversalDetails* details) const
 {
     if (node->isPseudoElement())
         return node->parentOrShadowHostNode();
@@ -189,14 +189,14 @@
     return traverseParentInCurrentTree(node, details);
 }
 
-inline Node* ComposedShadowTreeWalker::traverseParentInCurrentTree(const Node* node, ParentTraversalDetails* details) const
+inline Node* ComposedTreeWalker::traverseParentInCurrentTree(const Node* node, ParentTraversalDetails* details) const
 {
     if (Node* parent = node->parentNode())
         return parent->isShadowRoot() ? traverseParentBackToYoungerShadowRootOrHost(toShadowRoot(parent), details) : traverseNodeEscapingFallbackContents(parent, details);
     return 0;
 }
 
-Node* ComposedShadowTreeWalker::traverseParentBackToYoungerShadowRootOrHost(const ShadowRoot* shadowRoot, ParentTraversalDetails* details) const
+Node* ComposedTreeWalker::traverseParentBackToYoungerShadowRootOrHost(const ShadowRoot* shadowRoot, ParentTraversalDetails* details) const
 {
     ASSERT(shadowRoot);
     ASSERT(!shadowRoot->insertionPoint());
diff --git a/Source/core/dom/shadow/ComposedShadowTreeWalker.h b/Source/core/dom/shadow/ComposedTreeWalker.h
similarity index 84%
rename from Source/core/dom/shadow/ComposedShadowTreeWalker.h
rename to Source/core/dom/shadow/ComposedTreeWalker.h
index 34c5b01..a75ac9e 100644
--- a/Source/core/dom/shadow/ComposedShadowTreeWalker.h
+++ b/Source/core/dom/shadow/ComposedTreeWalker.h
@@ -24,8 +24,8 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef ComposedShadowTreeWalker_h
-#define ComposedShadowTreeWalker_h
+#ifndef ComposedTreeWalker_h
+#define ComposedTreeWalker_h
 
 #include "core/dom/NodeRenderingTraversal.h"
 #include "core/dom/shadow/InsertionPoint.h"
@@ -38,7 +38,7 @@
 
 // FIXME: Make some functions inline to optimise the performance.
 // https://bugs.webkit.org/show_bug.cgi?id=82702
-class ComposedShadowTreeWalker {
+class ComposedTreeWalker {
 public:
     typedef NodeRenderingTraversal::ParentDetails ParentTraversalDetails;
 
@@ -52,7 +52,7 @@
         CannotStartFromShadowBoundary
     };
 
-    ComposedShadowTreeWalker(const Node*, Policy = CrossUpperBoundary, StartPolicy = CannotStartFromShadowBoundary);
+    ComposedTreeWalker(const Node*, Policy = CrossUpperBoundary, StartPolicy = CannotStartFromShadowBoundary);
 
     Node* get() const { return const_cast<Node*>(m_node); }
 
@@ -70,7 +70,7 @@
     Node* traverseParent(const Node*, ParentTraversalDetails* = 0) const;
 
 private:
-    ComposedShadowTreeWalker(const Node*, ParentTraversalDetails*);
+    ComposedTreeWalker(const Node*, ParentTraversalDetails*);
 
     enum TraversalDirection {
         TraversalDirectionForward,
@@ -126,7 +126,7 @@
     Policy m_policy;
 };
 
-inline ComposedShadowTreeWalker::ComposedShadowTreeWalker(const Node* node, Policy policy, StartPolicy startPolicy)
+inline ComposedTreeWalker::ComposedTreeWalker(const Node* node, Policy policy, StartPolicy startPolicy)
     : m_node(node)
     , m_policy(policy)
 {
@@ -137,28 +137,28 @@
 #endif
 }
 
-inline void ComposedShadowTreeWalker::parent()
+inline void ComposedTreeWalker::parent()
 {
     assertPrecondition();
     m_node = traverseParent(m_node);
     assertPostcondition();
 }
 
-inline void ComposedShadowTreeWalker::nextSibling()
+inline void ComposedTreeWalker::nextSibling()
 {
     assertPrecondition();
     m_node = traverseSiblingOrBackToInsertionPoint(m_node, TraversalDirectionForward);
     assertPostcondition();
 }
 
-inline void ComposedShadowTreeWalker::previousSibling()
+inline void ComposedTreeWalker::previousSibling()
 {
     assertPrecondition();
     m_node = traverseSiblingOrBackToInsertionPoint(m_node, TraversalDirectionBackward);
     assertPostcondition();
 }
 
-inline void ComposedShadowTreeWalker::next()
+inline void ComposedTreeWalker::next()
 {
     assertPrecondition();
     if (Node* next = traverseFirstChild(m_node)) {
@@ -175,7 +175,7 @@
     assertPostcondition();
 }
 
-inline void ComposedShadowTreeWalker::previous()
+inline void ComposedTreeWalker::previous()
 {
     assertPrecondition();
     if (Node* previous = traversePreviousSibling(m_node)) {
@@ -188,39 +188,39 @@
     assertPostcondition();
 }
 
-inline void ComposedShadowTreeWalker::firstChild()
+inline void ComposedTreeWalker::firstChild()
 {
     assertPrecondition();
     m_node = traverseChild(m_node, TraversalDirectionForward);
     assertPostcondition();
 }
 
-inline void ComposedShadowTreeWalker::lastChild()
+inline void ComposedTreeWalker::lastChild()
 {
     assertPrecondition();
     m_node = traverseLastChild(m_node);
     assertPostcondition();
 }
 
-inline Node* ComposedShadowTreeWalker::traverseNextSibling(const Node* node)
+inline Node* ComposedTreeWalker::traverseNextSibling(const Node* node)
 {
     ASSERT(node);
     return traverseSiblingOrBackToInsertionPoint(node, TraversalDirectionForward);
 }
 
-inline Node* ComposedShadowTreeWalker::traversePreviousSibling(const Node* node)
+inline Node* ComposedTreeWalker::traversePreviousSibling(const Node* node)
 {
     ASSERT(node);
     return traverseSiblingOrBackToInsertionPoint(node, TraversalDirectionBackward);
 }
 
-inline Node* ComposedShadowTreeWalker::traverseFirstChild(const Node* node) const
+inline Node* ComposedTreeWalker::traverseFirstChild(const Node* node) const
 {
     ASSERT(node);
     return traverseChild(node, TraversalDirectionForward);
 }
 
-inline Node* ComposedShadowTreeWalker::traverseLastChild(const Node* node) const
+inline Node* ComposedTreeWalker::traverseLastChild(const Node* node) const
 {
     ASSERT(node);
     return traverseChild(node, TraversalDirectionBackward);
diff --git a/Source/core/dom/shadow/ContentDistribution.cpp b/Source/core/dom/shadow/ContentDistribution.cpp
index 405ce56..8333841 100644
--- a/Source/core/dom/shadow/ContentDistribution.cpp
+++ b/Source/core/dom/shadow/ContentDistribution.cpp
@@ -27,6 +27,8 @@
 #include "config.h"
 #include "core/dom/shadow/ContentDistribution.h"
 
+#include "core/dom/shadow/InsertionPoint.h"
+
 namespace WebCore {
 
 void ContentDistribution::swap(ContentDistribution& other)
@@ -37,6 +39,7 @@
 
 void ContentDistribution::append(PassRefPtr<Node> node)
 {
+    ASSERT(!isActiveInsertionPoint(node.get()));
     size_t size = m_nodes.size();
     m_indices.set(node.get(), size);
     m_nodes.append(node);
diff --git a/Source/core/dom/shadow/ElementShadow.cpp b/Source/core/dom/shadow/ElementShadow.cpp
index b6eef01..1224962 100644
--- a/Source/core/dom/shadow/ElementShadow.cpp
+++ b/Source/core/dom/shadow/ElementShadow.cpp
@@ -32,7 +32,6 @@
 #include "core/dom/NodeTraversal.h"
 #include "core/dom/shadow/ContentDistribution.h"
 #include "core/dom/shadow/InsertionPoint.h"
-#include "core/dom/shadow/ScopeContentDistribution.h"
 #include "core/dom/shadow/ShadowRoot.h"
 #include "core/html/shadow/HTMLContentElement.h"
 #include "core/html/shadow/HTMLShadowElement.h"
@@ -65,14 +64,12 @@
     m_shadowRoots.push(shadowRoot.get());
     ChildNodeInsertionNotifier(shadowHost).notify(shadowRoot.get());
     setNeedsDistributionRecalc();
+    shadowHost->lazyReattachIfAttached();
 
     // addShadowRoot() affects apply-author-styles. However, we know that the youngest shadow root has not had any children yet.
     // The youngest shadow root's apply-author-styles is default (false). So we can just set m_applyAuthorStyles false.
     m_applyAuthorStyles = false;
 
-    if (shadowHost->attached())
-        shadowHost->lazyReattach();
-
     InspectorInstrumentation::didPushShadowRoot(shadowHost, shadowRoot.get());
 
     return shadowRoot.get();
@@ -186,7 +183,7 @@
     InsertionPoint* insertionPoint = toInsertionPoint(node);
     if (insertionPoint->hasDistribution()) {
         for (size_t i = 0; i < insertionPoint->size(); ++i)
-            populate(insertionPoint->at(i), pool);
+            pool.append(insertionPoint->at(i));
     } else {
         for (Node* fallbackNode = insertionPoint->firstChild(); fallbackNode; fallbackNode = fallbackNode->nextSibling())
             pool.append(fallbackNode);
@@ -208,21 +205,19 @@
     for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot()) {
         HTMLShadowElement* firstActiveShadowInsertionPoint = 0;
 
-        if (ScopeContentDistribution* scope = root->scopeDistribution()) {
-            const Vector<RefPtr<InsertionPoint> >& insertionPoints = scope->ensureInsertionPointList(root);
-            for (size_t i = 0; i < insertionPoints.size(); ++i) {
-                InsertionPoint* point = insertionPoints[i].get();
-                if (!point->isActive())
-                    continue;
+        const Vector<RefPtr<InsertionPoint> >& insertionPoints = root->childInsertionPoints();
+        for (size_t i = 0; i < insertionPoints.size(); ++i) {
+            InsertionPoint* point = insertionPoints[i].get();
+            if (!point->isActive())
+                continue;
 
-                if (isHTMLShadowElement(point)) {
-                    if (!firstActiveShadowInsertionPoint)
-                        firstActiveShadowInsertionPoint = toHTMLShadowElement(point);
-                } else {
-                    distributeSelectionsTo(point, pool, distributed);
-                    if (ElementShadow* shadow = shadowOfParentForDistribution(point))
-                        shadow->setNeedsDistributionRecalc();
-                }
+            if (isHTMLShadowElement(point)) {
+                if (!firstActiveShadowInsertionPoint)
+                    firstActiveShadowInsertionPoint = toHTMLShadowElement(point);
+            } else {
+                distributeSelectionsTo(point, pool, distributed);
+                if (ElementShadow* shadow = shadowOfParentForDistribution(point))
+                    shadow->setNeedsDistributionRecalc();
             }
         }
 
@@ -234,13 +229,15 @@
         HTMLShadowElement* shadowElement = activeShadowInsertionPoints[i - 1];
         ShadowRoot* root = shadowElement->containingShadowRoot();
         ASSERT(root);
-        if (!shadowElement->shouldSelect()) {
-            if (root->olderShadowRoot())
-                root->olderShadowRoot()->ensureScopeDistribution()->setInsertionPointAssignedTo(shadowElement);
-        } else if (root->olderShadowRoot()) {
+        if (root->olderShadowRoot() && root->olderShadowRoot()->type() == root->type()) {
+            // Only allow reprojecting older shadow roots between the same type to
+            // disallow reprojecting UA elements into author shadows.
             distributeNodeChildrenTo(shadowElement, root->olderShadowRoot());
-            root->olderShadowRoot()->ensureScopeDistribution()->setInsertionPointAssignedTo(shadowElement);
-        } else {
+            root->olderShadowRoot()->setInsertionPoint(shadowElement);
+        } else if (!root->olderShadowRoot()) {
+            // There's assumed to always be a UA shadow that selects all nodes.
+            // We don't actually add it, instead we just distribute the pool to the
+            // <shadow> in the oldest shadow root.
             distributeSelectionsTo(shadowElement, pool, distributed);
         }
         if (ElementShadow* shadow = shadowOfParentForDistribution(shadowElement))
@@ -352,10 +349,8 @@
 {
     m_nodeToInsertionPoint.clear();
 
-    for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot()) {
-        if (ScopeContentDistribution* scope = root->scopeDistribution())
-            scope->setInsertionPointAssignedTo(0);
-    }
+    for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot())
+        root->setInsertionPoint(0);
 }
 
 } // namespace
diff --git a/Source/core/dom/shadow/InsertionPoint.cpp b/Source/core/dom/shadow/InsertionPoint.cpp
index f2447c4..5d01a73 100644
--- a/Source/core/dom/shadow/InsertionPoint.cpp
+++ b/Source/core/dom/shadow/InsertionPoint.cpp
@@ -35,7 +35,6 @@
 #include "core/dom/QualifiedName.h"
 #include "core/dom/StaticNodeList.h"
 #include "core/dom/shadow/ElementShadow.h"
-#include "core/dom/shadow/ScopeContentDistribution.h"
 #include "core/dom/shadow/ShadowRoot.h"
 
 namespace WebCore {
@@ -176,7 +175,7 @@
             rootOwner->setNeedsDistributionRecalc();
             if (isActive() && !m_registeredWithShadowRoot && insertionPoint->treeScope()->rootNode() == root) {
                 m_registeredWithShadowRoot = true;
-                root->ensureScopeDistribution()->registerInsertionPoint(this);
+                root->addInsertionPoint(this);
                 rootOwner->didAffectApplyAuthorStyles();
                 if (canAffectSelector())
                     rootOwner->willAffectSelector();
@@ -207,7 +206,7 @@
     if (m_registeredWithShadowRoot && insertionPoint->treeScope()->rootNode() == root) {
         ASSERT(root);
         m_registeredWithShadowRoot = false;
-        root->ensureScopeDistribution()->unregisterInsertionPoint(this);
+        root->removeInsertionPoint(this);
         if (rootOwner) {
             rootOwner->didAffectApplyAuthorStyles();
             if (canAffectSelector())
diff --git a/Source/core/dom/shadow/ScopeContentDistribution.cpp b/Source/core/dom/shadow/ScopeContentDistribution.cpp
deleted file mode 100644
index b20ee65..0000000
--- a/Source/core/dom/shadow/ScopeContentDistribution.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/dom/shadow/ScopeContentDistribution.h"
-
-#include "core/dom/ElementTraversal.h"
-#include "core/dom/shadow/InsertionPoint.h"
-#include "core/dom/shadow/ShadowRoot.h"
-#include "core/html/shadow/HTMLContentElement.h"
-#include "core/html/shadow/HTMLShadowElement.h"
-
-namespace WebCore {
-
-ScopeContentDistribution::ScopeContentDistribution()
-    : m_insertionPointAssignedTo(0)
-    , m_numberOfShadowElementChildren(0)
-    , m_numberOfContentElementChildren(0)
-    , m_numberOfElementShadowChildren(0)
-    , m_insertionPointListIsValid(false)
-{
-}
-
-void ScopeContentDistribution::setInsertionPointAssignedTo(PassRefPtr<InsertionPoint> insertionPoint)
-{
-    m_insertionPointAssignedTo = insertionPoint;
-}
-
-void ScopeContentDistribution::invalidateInsertionPointList()
-{
-    m_insertionPointListIsValid = false;
-    m_insertionPointList.clear();
-}
-
-const Vector<RefPtr<InsertionPoint> >& ScopeContentDistribution::ensureInsertionPointList(ShadowRoot* shadowRoot)
-{
-    if (m_insertionPointListIsValid)
-        return m_insertionPointList;
-
-    m_insertionPointListIsValid = true;
-    ASSERT(m_insertionPointList.isEmpty());
-
-    if (!shadowRoot->containsInsertionPoints())
-        return m_insertionPointList;
-
-    for (Element* element = ElementTraversal::firstWithin(shadowRoot); element; element = ElementTraversal::next(element, shadowRoot)) {
-        if (element->isInsertionPoint())
-            m_insertionPointList.append(toInsertionPoint(element));
-    }
-
-    return m_insertionPointList;
-}
-
-void ScopeContentDistribution::registerInsertionPoint(InsertionPoint* point)
-{
-    if (isHTMLShadowElement(point))
-        ++m_numberOfShadowElementChildren;
-    else if (isHTMLContentElement(point))
-        ++m_numberOfContentElementChildren;
-    else
-        ASSERT_NOT_REACHED();
-
-    invalidateInsertionPointList();
-}
-
-void ScopeContentDistribution::unregisterInsertionPoint(InsertionPoint* point)
-{
-    if (isHTMLShadowElement(point))
-        --m_numberOfShadowElementChildren;
-    else if (isHTMLContentElement(point))
-        --m_numberOfContentElementChildren;
-    else
-        ASSERT_NOT_REACHED();
-
-    ASSERT(m_numberOfContentElementChildren >= 0);
-    ASSERT(m_numberOfShadowElementChildren >= 0);
-
-    invalidateInsertionPointList();
-}
-
-} // namespace WebCore
diff --git a/Source/core/dom/shadow/ScopeContentDistribution.h b/Source/core/dom/shadow/ScopeContentDistribution.h
deleted file mode 100644
index 43ed09f..0000000
--- a/Source/core/dom/shadow/ScopeContentDistribution.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ScopeContentDistribution_h
-#define ScopeContentDistribution_h
-
-#include "wtf/Forward.h"
-#include "wtf/Vector.h"
-
-namespace WebCore {
-
-class InsertionPoint;
-class ShadowRoot;
-
-class ScopeContentDistribution {
-public:
-    ScopeContentDistribution();
-
-    InsertionPoint* insertionPointAssignedTo() const { return m_insertionPointAssignedTo.get(); }
-    void setInsertionPointAssignedTo(PassRefPtr<InsertionPoint>);
-
-    void registerInsertionPoint(InsertionPoint*);
-    void unregisterInsertionPoint(InsertionPoint*);
-    bool hasShadowElementChildren() const { return m_numberOfShadowElementChildren > 0; }
-    bool hasContentElementChildren() const { return m_numberOfContentElementChildren > 0; }
-
-    void registerElementShadow() { ++m_numberOfElementShadowChildren; }
-    void unregisterElementShadow() { ASSERT(m_numberOfElementShadowChildren > 0); --m_numberOfElementShadowChildren; }
-    unsigned numberOfElementShadowChildren() const { return m_numberOfElementShadowChildren; }
-    bool hasElementShadowChildren() const { return m_numberOfElementShadowChildren > 0; }
-
-    void invalidateInsertionPointList();
-    const Vector<RefPtr<InsertionPoint> >& ensureInsertionPointList(ShadowRoot*);
-
-private:
-    RefPtr<InsertionPoint> m_insertionPointAssignedTo;
-    unsigned m_numberOfShadowElementChildren;
-    unsigned m_numberOfContentElementChildren;
-    unsigned m_numberOfElementShadowChildren;
-    bool m_insertionPointListIsValid;
-    Vector<RefPtr<InsertionPoint> > m_insertionPointList;
-};
-
-} // namespace WebCore
-
-#endif
diff --git a/Source/core/dom/shadow/ShadowRoot.cpp b/Source/core/dom/shadow/ShadowRoot.cpp
index b9f9ce1..6269a5c 100644
--- a/Source/core/dom/shadow/ShadowRoot.cpp
+++ b/Source/core/dom/shadow/ShadowRoot.cpp
@@ -29,11 +29,12 @@
 
 #include "bindings/v8/ExceptionState.h"
 #include "core/css/resolver/StyleResolver.h"
-#include "core/dom/DocumentStyleSheetCollection.h"
+#include "core/dom/ElementTraversal.h"
+#include "core/dom/StyleSheetCollections.h"
 #include "core/dom/Text.h"
 #include "core/dom/shadow/ElementShadow.h"
 #include "core/dom/shadow/InsertionPoint.h"
-#include "core/dom/shadow/ScopeContentDistribution.h"
+#include "core/dom/shadow/ShadowRootRareData.h"
 #include "core/editing/markup.h"
 #include "core/platform/HistogramSupport.h"
 
@@ -62,6 +63,7 @@
     , m_resetStyleInheritance(false)
     , m_type(type)
     , m_registeredWithParentShadowRoot(false)
+    , m_childInsertionPointsIsValid(false)
 {
     ASSERT(document);
     ScriptWrappable::init(this);
@@ -77,7 +79,7 @@
     ASSERT(!m_prev);
     ASSERT(!m_next);
 
-    documentInternal()->styleSheetCollection()->didRemoveShadowRoot(this);
+    documentInternal()->styleSheetCollections()->didRemoveShadowRoot(this);
 
     // We cannot let ContainerNode destructor call willBeDeletedFrom()
     // for this ShadowRoot instance because TreeScope destructor
@@ -270,7 +272,7 @@
         return InsertionDone;
 
     if (ShadowRoot* root = host()->containingShadowRoot()) {
-        root->ensureScopeDistribution()->registerElementShadow();
+        root->addChildShadowRoot();
         m_registeredWithParentShadowRoot = true;
     }
 
@@ -283,9 +285,8 @@
         ShadowRoot* root = host()->containingShadowRoot();
         if (!root)
             root = insertionPoint->containingShadowRoot();
-
-        if (root && root->scopeDistribution())
-            root->scopeDistribution()->unregisterElementShadow();
+        if (root)
+            root->removeChildShadowRoot();
         m_registeredWithParentShadowRoot = false;
     }
 
@@ -314,33 +315,99 @@
     setHasScopedHTMLStyleChild(m_numberOfStyles > 0);
 }
 
-ScopeContentDistribution* ShadowRoot::ensureScopeDistribution()
+ShadowRootRareData* ShadowRoot::ensureShadowRootRareData()
 {
-    if (m_scopeDistribution)
-        return m_scopeDistribution.get();
+    if (m_shadowRootRareData)
+        return m_shadowRootRareData.get();
 
-    m_scopeDistribution = adoptPtr(new ScopeContentDistribution);
-    return m_scopeDistribution.get();
+    m_shadowRootRareData = adoptPtr(new ShadowRootRareData);
+    return m_shadowRootRareData.get();
 }
 
 bool ShadowRoot::containsShadowElements() const
 {
-    return m_scopeDistribution ? m_scopeDistribution->hasShadowElementChildren() : 0;
+    return m_shadowRootRareData ? m_shadowRootRareData->hasShadowElementChildren() : 0;
 }
 
 bool ShadowRoot::containsContentElements() const
 {
-    return m_scopeDistribution ? m_scopeDistribution->hasContentElementChildren() : 0;
+    return m_shadowRootRareData ? m_shadowRootRareData->hasContentElementChildren() : 0;
 }
 
 bool ShadowRoot::containsShadowRoots() const
 {
-    return m_scopeDistribution ? m_scopeDistribution->numberOfElementShadowChildren() : 0;
+    return m_shadowRootRareData ? m_shadowRootRareData->hasShadowRootChildren() : 0;
 }
 
 InsertionPoint* ShadowRoot::insertionPoint() const
 {
-    return m_scopeDistribution ? m_scopeDistribution->insertionPointAssignedTo() : 0;
+    return m_shadowRootRareData ? m_shadowRootRareData->insertionPoint() : 0;
+}
+
+void ShadowRoot::setInsertionPoint(PassRefPtr<InsertionPoint> insertionPoint)
+{
+    if (!m_shadowRootRareData && !insertionPoint)
+        return;
+    ensureShadowRootRareData()->setInsertionPoint(insertionPoint);
+}
+
+void ShadowRoot::addInsertionPoint(InsertionPoint* insertionPoint)
+{
+    ensureShadowRootRareData()->addInsertionPoint(insertionPoint);
+    invalidateChildInsertionPoints();
+}
+
+void ShadowRoot::removeInsertionPoint(InsertionPoint* insertionPoint)
+{
+    m_shadowRootRareData->removeInsertionPoint(insertionPoint);
+    invalidateChildInsertionPoints();
+}
+
+void ShadowRoot::addChildShadowRoot()
+{
+    ensureShadowRootRareData()->addChildShadowRoot();
+}
+
+void ShadowRoot::removeChildShadowRoot()
+{
+    // FIXME: Why isn't this an ASSERT?
+    if (!m_shadowRootRareData)
+        return;
+    m_shadowRootRareData->removeChildShadowRoot();
+}
+
+unsigned ShadowRoot::childShadowRootCount() const
+{
+    return m_shadowRootRareData ? m_shadowRootRareData->childShadowRootCount() : 0;
+}
+
+void ShadowRoot::invalidateChildInsertionPoints()
+{
+    m_childInsertionPointsIsValid = false;
+    m_shadowRootRareData->clearChildInsertionPoints();
+}
+
+const Vector<RefPtr<InsertionPoint> >& ShadowRoot::childInsertionPoints()
+{
+    DEFINE_STATIC_LOCAL(const Vector<RefPtr<InsertionPoint> >, emptyList, ());
+
+    if (m_shadowRootRareData && m_childInsertionPointsIsValid)
+        return m_shadowRootRareData->childInsertionPoints();
+
+    m_childInsertionPointsIsValid = true;
+
+    if (!containsInsertionPoints())
+        return emptyList;
+
+    Vector<RefPtr<InsertionPoint> > insertionPoints;
+    for (Element* element = ElementTraversal::firstWithin(this); element; element = ElementTraversal::next(element, this)) {
+        if (element->isInsertionPoint())
+            insertionPoints.append(toInsertionPoint(element));
+    }
+
+    ensureShadowRootRareData()->setChildInsertionPoints(insertionPoints);
+
+    return m_shadowRootRareData->childInsertionPoints();
 }
 
 }
diff --git a/Source/core/dom/shadow/ShadowRoot.h b/Source/core/dom/shadow/ShadowRoot.h
index 993fdb2..018f8e8 100644
--- a/Source/core/dom/shadow/ShadowRoot.h
+++ b/Source/core/dom/shadow/ShadowRoot.h
@@ -39,7 +39,7 @@
 class ElementShadow;
 class ExceptionState;
 class InsertionPoint;
-class ScopeContentDistribution;
+class ShadowRootRareData;
 
 class ShadowRoot FINAL : public DocumentFragment, public TreeScope, public DoublyLinkedListNode<ShadowRoot> {
     friend class WTF::DoublyLinkedListNode<ShadowRoot>;
@@ -91,15 +91,20 @@
     virtual void registerScopedHTMLStyleChild() OVERRIDE;
     virtual void unregisterScopedHTMLStyleChild() OVERRIDE;
 
-    ScopeContentDistribution* scopeDistribution() { return m_scopeDistribution.get(); }
-    const ScopeContentDistribution* scopeDistribution() const { return m_scopeDistribution.get(); }
-    ScopeContentDistribution* ensureScopeDistribution();
-
     bool containsShadowElements() const;
     bool containsContentElements() const;
     bool containsInsertionPoints() const { return containsShadowElements() || containsContentElements(); }
     bool containsShadowRoots() const;
+
+    // For Internals, don't use this.
+    unsigned childShadowRootCount() const;
+
     InsertionPoint* insertionPoint() const;
+    void setInsertionPoint(PassRefPtr<InsertionPoint>);
+
+    void addInsertionPoint(InsertionPoint*);
+    void removeInsertionPoint(InsertionPoint*);
+    const Vector<RefPtr<InsertionPoint> >& childInsertionPoints();
 
     ShadowRootType type() const { return static_cast<ShadowRootType>(m_type); }
 
@@ -114,6 +119,12 @@
     virtual bool childTypeAllowed(NodeType) const OVERRIDE;
     virtual void childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) OVERRIDE;
 
+    ShadowRootRareData* ensureShadowRootRareData();
+
+    void addChildShadowRoot();
+    void removeChildShadowRoot();
+    void invalidateChildInsertionPoints();
+
     // ShadowRoots should never be cloned.
     virtual PassRefPtr<Node> cloneNode(bool) OVERRIDE { return 0; }
 
@@ -123,12 +134,13 @@
 
     ShadowRoot* m_prev;
     ShadowRoot* m_next;
-    OwnPtr<ScopeContentDistribution> m_scopeDistribution;
-    unsigned m_numberOfStyles : 28;
+    OwnPtr<ShadowRootRareData> m_shadowRootRareData;
+    unsigned m_numberOfStyles : 27;
     unsigned m_applyAuthorStyles : 1;
     unsigned m_resetStyleInheritance : 1;
     unsigned m_type : 1;
     unsigned m_registeredWithParentShadowRoot : 1;
+    unsigned m_childInsertionPointsIsValid : 1;
 };
 
 inline Element* ShadowRoot::activeElement() const
diff --git a/Source/core/dom/shadow/ShadowRootRareData.h b/Source/core/dom/shadow/ShadowRootRareData.h
new file mode 100644
index 0000000..3a0966d
--- /dev/null
+++ b/Source/core/dom/shadow/ShadowRootRareData.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ShadowRootRareData_h
+#define ShadowRootRareData_h
+
+#include "core/dom/shadow/InsertionPoint.h"
+#include "core/html/shadow/HTMLContentElement.h"
+#include "core/html/shadow/HTMLShadowElement.h"
+#include "wtf/RefPtr.h"
+#include "wtf/Vector.h"
+
+namespace WebCore {
+
+class ShadowRootRareData {
+public:
+    ShadowRootRareData()
+        : m_childShadowElementCount(0)
+        , m_childContentElementCount(0)
+        , m_childShadowRootCount(0)
+    {
+    }
+
+    InsertionPoint* insertionPoint() const { return m_insertionPoint.get(); }
+    void setInsertionPoint(PassRefPtr<InsertionPoint> insertionPoint) { m_insertionPoint = insertionPoint; }
+
+    void addInsertionPoint(InsertionPoint*);
+    void removeInsertionPoint(InsertionPoint*);
+
+    bool hasShadowElementChildren() const { return m_childShadowElementCount; }
+    bool hasContentElementChildren() const { return m_childContentElementCount; }
+    bool hasShadowRootChildren() const { return m_childShadowRootCount; }
+
+    void addChildShadowRoot() { ++m_childShadowRootCount; }
+    void removeChildShadowRoot() { ASSERT(m_childShadowRootCount > 0); --m_childShadowRootCount; }
+
+    unsigned childShadowRootCount() const { return m_childShadowRootCount; }
+
+    const Vector<RefPtr<InsertionPoint> >& childInsertionPoints() { return m_childInsertionPoints; }
+    void setChildInsertionPoints(Vector<RefPtr<InsertionPoint> >& list) { m_childInsertionPoints.swap(list); }
+    void clearChildInsertionPoints() { m_childInsertionPoints.clear(); }
+
+private:
+    RefPtr<InsertionPoint> m_insertionPoint;
+    unsigned m_childShadowElementCount;
+    unsigned m_childContentElementCount;
+    unsigned m_childShadowRootCount;
+    Vector<RefPtr<InsertionPoint> > m_childInsertionPoints;
+};
+
+inline void ShadowRootRareData::addInsertionPoint(InsertionPoint* point)
+{
+    if (isHTMLShadowElement(point))
+        ++m_childShadowElementCount;
+    else if (isHTMLContentElement(point))
+        ++m_childContentElementCount;
+    else
+        ASSERT_NOT_REACHED();
+}
+
+inline void ShadowRootRareData::removeInsertionPoint(InsertionPoint* point)
+{
+    if (isHTMLShadowElement(point))
+        --m_childShadowElementCount;
+    else if (isHTMLContentElement(point))
+        --m_childContentElementCount;
+    else
+        ASSERT_NOT_REACHED();
+
+    ASSERT(m_childContentElementCount >= 0);
+    ASSERT(m_childShadowElementCount >= 0);
+}
+
+} // namespace WebCore
+
+#endif