Merge from Chromium at DEPS revision 232870

This commit was generated by merge_to_master.py.

Change-Id: Ib9d83ad19b18b768c3ab444a5de7965a594872e7
diff --git a/Source/core/dom/ContainerNode.cpp b/Source/core/dom/ContainerNode.cpp
index 676aac1..efe778d 100644
--- a/Source/core/dom/ContainerNode.cpp
+++ b/Source/core/dom/ContainerNode.cpp
@@ -63,16 +63,16 @@
 static const char insertBeforeMethodName[] = "insertBefore";
 static const char replaceChildMethodName[] = "replaceChild";
 
-static void collectChildrenAndRemoveFromOldParent(Node* node, NodeVector& nodes, ExceptionState& es)
+static void collectChildrenAndRemoveFromOldParent(Node& node, NodeVector& nodes, ExceptionState& es)
 {
-    if (node->nodeType() != Node::DOCUMENT_FRAGMENT_NODE) {
-        nodes.append(node);
-        if (ContainerNode* oldParent = node->parentNode())
-            oldParent->removeChild(node, es);
+    if (node.nodeType() != Node::DOCUMENT_FRAGMENT_NODE) {
+        nodes.append(&node);
+        if (ContainerNode* oldParent = node.parentNode())
+            oldParent->removeChild(&node, es);
         return;
     }
     getChildNodes(node, nodes);
-    toContainerNode(node)->removeChildren();
+    toContainerNode(node).removeChildren();
 }
 
 void ContainerNode::removeDetachedChildren()
@@ -81,14 +81,14 @@
         for (Node* child = firstChild(); child; child = child->nextSibling())
             child->updateAncestorConnectedSubframeCountForRemoval();
     }
-    // FIXME: We should be able to ASSERT(!confusingAndOftenMisusedAttached()) here: https://bugs.webkit.org/show_bug.cgi?id=107801
+    ASSERT(needsAttach());
     removeDetachedChildrenInContainer<Node, ContainerNode>(*this);
 }
 
-void ContainerNode::parserTakeAllChildrenFrom(ContainerNode* oldParent)
+void ContainerNode::parserTakeAllChildrenFrom(ContainerNode& oldParent)
 {
-    while (RefPtr<Node> child = oldParent->firstChild()) {
-        oldParent->parserRemoveChild(*child);
+    while (RefPtr<Node> child = oldParent.firstChild()) {
+        oldParent.parserRemoveChild(*child);
         treeScope().adoptIfNeeded(*child);
         parserAppendChild(child.get());
     }
@@ -100,32 +100,32 @@
     removeDetachedChildren();
 }
 
-static inline bool isChildTypeAllowed(ContainerNode* newParent, Node* child)
+static inline bool isChildTypeAllowed(ContainerNode& newParent, Node& child)
 {
-    if (!child->isDocumentFragment())
-        return newParent->childTypeAllowed(child->nodeType());
+    if (!child.isDocumentFragment())
+        return newParent.childTypeAllowed(child.nodeType());
 
-    for (Node* node = child->firstChild(); node; node = node->nextSibling()) {
-        if (!newParent->childTypeAllowed(node->nodeType()))
+    for (Node* node = child.firstChild(); node; node = node->nextSibling()) {
+        if (!newParent.childTypeAllowed(node->nodeType()))
             return false;
     }
     return true;
 }
 
-static inline bool isInTemplateContent(const Node* node)
+static inline bool isInTemplateContent(const Node& node)
 {
-    Document& document = node->document();
+    const Document& document = node.document();
     return document == document.templateDocument();
 }
 
-static inline bool containsConsideringHostElements(const Node* newChild, const Node* newParent)
+static inline bool containsConsideringHostElements(const Node& newChild, const Node& newParent)
 {
-    return (newParent->isInShadowTree() || isInTemplateContent(newParent))
-        ? newChild->containsIncludingHostElements(newParent)
-        : newChild->contains(newParent);
+    return (newParent.isInShadowTree() || isInTemplateContent(newParent))
+        ? newChild.containsIncludingHostElements(newParent)
+        : newChild.contains(&newParent);
 }
 
-static inline bool checkAcceptChild(ContainerNode* newParent, Node* newChild, Node* oldChild, const char* method, ExceptionState& es)
+static inline bool checkAcceptChild(ContainerNode& newParent, Node* newChild, Node* oldChild, const char* method, ExceptionState& es)
 {
     // Not mentioned in spec: throw NotFoundError if newChild is null
     if (!newChild) {
@@ -134,10 +134,10 @@
     }
 
     // Use common case fast path if possible.
-    if ((newChild->isElementNode() || newChild->isTextNode()) && newParent->isElementNode()) {
-        ASSERT(!newParent->isDocumentTypeNode());
-        ASSERT(isChildTypeAllowed(newParent, newChild));
-        if (containsConsideringHostElements(newChild, newParent)) {
+    if ((newChild->isElementNode() || newChild->isTextNode()) && newParent.isElementNode()) {
+        ASSERT(!newParent.isDocumentTypeNode());
+        ASSERT(isChildTypeAllowed(newParent, *newChild));
+        if (containsConsideringHostElements(*newChild, newParent)) {
             es.throwDOMException(HierarchyRequestError, ExceptionMessages::failedToExecute(method, "Node", "The new child element contains the parent."));
             return false;
         }
@@ -151,30 +151,30 @@
         return false;
     }
 
-    if (containsConsideringHostElements(newChild, newParent)) {
+    if (containsConsideringHostElements(*newChild, newParent)) {
         es.throwDOMException(HierarchyRequestError, ExceptionMessages::failedToExecute(method, "Node", "The new child element contains the parent."));
         return false;
     }
 
-    if (oldChild && newParent->isDocumentNode()) {
-        if (!toDocument(newParent)->canReplaceChild(newChild, oldChild)) {
+    if (oldChild && newParent.isDocumentNode()) {
+        if (!toDocument(newParent).canReplaceChild(*newChild, *oldChild)) {
             // FIXME: Adjust 'Document::canReplaceChild' to return some additional detail (or an error message).
             es.throwDOMException(HierarchyRequestError, ExceptionMessages::failedToExecute(method, "ContainerNode"));
             return false;
         }
-    } else if (!isChildTypeAllowed(newParent, newChild)) {
-        es.throwDOMException(HierarchyRequestError, ExceptionMessages::failedToExecute(method, "Node", "Nodes of type '" + newChild->nodeName() + "' may not be inserted inside nodes of type '" + newParent->nodeName() + "'."));
+    } else if (!isChildTypeAllowed(newParent, *newChild)) {
+        es.throwDOMException(HierarchyRequestError, ExceptionMessages::failedToExecute(method, "Node", "Nodes of type '" + newChild->nodeName() + "' may not be inserted inside nodes of type '" + newParent.nodeName() + "'."));
         return false;
     }
 
     return true;
 }
 
-static inline bool checkAcceptChildGuaranteedNodeTypes(ContainerNode* newParent, Node* newChild, const char* method, ExceptionState& es)
+static inline bool checkAcceptChildGuaranteedNodeTypes(ContainerNode& newParent, Node& newChild, const char* method, ExceptionState& es)
 {
-    ASSERT(!newParent->isDocumentTypeNode());
+    ASSERT(!newParent.isDocumentTypeNode());
     ASSERT(isChildTypeAllowed(newParent, newChild));
-    if (newChild->contains(newParent)) {
+    if (newChild.contains(&newParent)) {
         es.throwDOMException(HierarchyRequestError, ExceptionMessages::failedToExecute(method, "Node", "The new child element contains the parent."));
         return false;
     }
@@ -182,14 +182,14 @@
     return true;
 }
 
-static inline bool checkAddChild(ContainerNode* newParent, Node* newChild, const char* method, ExceptionState& es)
+static inline bool checkAddChild(ContainerNode& newParent, Node* newChild, const char* method, ExceptionState& es)
 {
     return checkAcceptChild(newParent, newChild, 0, method, es);
 }
 
-static inline bool checkReplaceChild(ContainerNode* newParent, Node* newChild, Node* oldChild, const char* method, ExceptionState& es)
+static inline bool checkReplaceChild(ContainerNode& newParent, Node* newChild, Node& oldChild, const char* method, ExceptionState& es)
 {
-    return checkAcceptChild(newParent, newChild, oldChild, method, es);
+    return checkAcceptChild(newParent, newChild, &oldChild, method, es);
 }
 
 void ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionState& es)
@@ -207,8 +207,9 @@
     }
 
     // Make sure adding the new child is OK.
-    if (!checkAddChild(this, newChild.get(), insertBeforeMethodName, es))
+    if (!checkAddChild(*this, newChild.get(), insertBeforeMethodName, es))
         return;
+    ASSERT(newChild);
 
     // NotFoundError: Raised if refChild is not a child of this node
     if (refChild->parentNode() != this) {
@@ -222,14 +223,14 @@
     RefPtr<Node> next = refChild;
 
     NodeVector targets;
-    collectChildrenAndRemoveFromOldParent(newChild.get(), targets, es);
+    collectChildrenAndRemoveFromOldParent(*newChild, targets, es);
     if (es.hadException())
         return;
     if (targets.isEmpty())
         return;
 
     // We need this extra check because collectChildrenAndRemoveFromOldParent() can fire mutation events.
-    if (!checkAcceptChildGuaranteedNodeTypes(this, newChild.get(), insertBeforeMethodName, es))
+    if (!checkAcceptChildGuaranteedNodeTypes(*this, *newChild, insertBeforeMethodName, es))
         return;
 
     InspectorInstrumentation::willInsertDOMNode(this);
@@ -283,27 +284,26 @@
     newChild.setNextSibling(&nextChild);
 }
 
-void ContainerNode::parserInsertBefore(PassRefPtr<Node> newChild, Node* nextChild)
+void ContainerNode::parserInsertBefore(PassRefPtr<Node> newChild, Node& nextChild)
 {
     ASSERT(newChild);
-    ASSERT(nextChild);
-    ASSERT(nextChild->parentNode() == this);
+    ASSERT(nextChild.parentNode() == this);
     ASSERT(!newChild->isDocumentFragment());
     ASSERT(!hasTagName(HTMLNames::templateTag));
 
-    if (nextChild->previousSibling() == newChild || nextChild == newChild) // nothing to do
+    if (nextChild.previousSibling() == newChild || nextChild == newChild) // nothing to do
         return;
 
     if (document() != newChild->document())
         document().adoptNode(newChild.get(), ASSERT_NO_EXCEPTION);
 
-    insertBeforeCommon(*nextChild, *newChild);
+    insertBeforeCommon(nextChild, *newChild);
 
     newChild->updateAncestorConnectedSubframeCountForInsertion();
 
     ChildListMutationScope(*this).childAdded(*newChild);
 
-    childrenChanged(true, newChild->previousSibling(), nextChild, 1);
+    childrenChanged(true, newChild->previousSibling(), &nextChild, 1);
 
     ChildNodeInsertionNotifier(*this).notify(*newChild);
 }
@@ -325,7 +325,7 @@
     }
 
     // Make sure replacing the old child with the new is ok
-    if (!checkReplaceChild(this, newChild.get(), oldChild, replaceChildMethodName, es))
+    if (!checkReplaceChild(*this, newChild.get(), *oldChild, replaceChildMethodName, es))
         return;
 
     // NotFoundError: Raised if oldChild is not a child of this node.
@@ -348,16 +348,16 @@
         return;
 
     // Does this one more time because removeChild() fires a MutationEvent.
-    if (!checkReplaceChild(this, newChild.get(), oldChild, replaceChildMethodName, es))
+    if (!checkReplaceChild(*this, newChild.get(), *oldChild, replaceChildMethodName, es))
         return;
 
     NodeVector targets;
-    collectChildrenAndRemoveFromOldParent(newChild.get(), targets, es);
+    collectChildrenAndRemoveFromOldParent(*newChild, targets, es);
     if (es.hadException())
         return;
 
     // Does this yet another check because collectChildrenAndRemoveFromOldParent() fires a MutationEvent.
-    if (!checkReplaceChild(this, newChild.get(), oldChild, replaceChildMethodName, es))
+    if (!checkReplaceChild(*this, newChild.get(), *oldChild, replaceChildMethodName, es))
         return;
 
     InspectorInstrumentation::willInsertDOMNode(this);
@@ -399,14 +399,14 @@
     ChildListMutationScope(*child.parentNode()).willRemoveChild(child);
     child.notifyMutationObserversNodeWillDetach();
     dispatchChildRemovalEvents(child);
-    child.document().nodeWillBeRemoved(&child); // e.g. mutation event listener can create a new range.
+    child.document().nodeWillBeRemoved(child); // e.g. mutation event listener can create a new range.
     ChildFrameDisconnector(child).disconnect();
 }
 
 static void willRemoveChildren(ContainerNode& container)
 {
     NodeVector children;
-    getChildNodes(&container, children);
+    getChildNodes(container, children);
 
     ChildListMutationScope mutation(container);
     for (NodeVector::const_iterator it = children.begin(); it != children.end(); it++) {
@@ -540,7 +540,7 @@
     {
         // Removing focus can cause frames to load, either via events (focusout, blur)
         // or widget updates (e.g., for <embed>).
-        SubframeLoadingDisabler disabler(this);
+        SubframeLoadingDisabler disabler(*this);
 
         // Exclude this node when looking for removed focusedElement since only
         // children will be removed.
@@ -583,14 +583,15 @@
     ASSERT(refCount() || parentOrShadowHostNode());
 
     // Make sure adding the new child is ok
-    if (!checkAddChild(this, newChild.get(), appendChildMethodName, es))
+    if (!checkAddChild(*this, newChild.get(), appendChildMethodName, es))
         return;
+    ASSERT(newChild);
 
     if (newChild == m_lastChild) // nothing to do
         return;
 
     NodeVector targets;
-    collectChildrenAndRemoveFromOldParent(newChild.get(), targets, es);
+    collectChildrenAndRemoveFromOldParent(*newChild, targets, es);
     if (es.hadException())
         return;
 
@@ -598,7 +599,7 @@
         return;
 
     // We need this extra check because collectChildrenAndRemoveFromOldParent() can fire mutation events.
-    if (!checkAcceptChildGuaranteedNodeTypes(this, newChild.get(), appendChildMethodName, es))
+    if (!checkAcceptChildGuaranteedNodeTypes(*this, *newChild, appendChildMethodName, es))
         return;
 
     InspectorInstrumentation::willInsertDOMNode(this);
@@ -955,13 +956,13 @@
 
     // dispatch pre-removal mutation events
     if (c->parentNode() && document->hasListenerType(Document::DOMNODEREMOVED_LISTENER)) {
-        NodeChildRemovalTracker scope(&child);
+        NodeChildRemovalTracker scope(child);
         c->dispatchScopedEvent(MutationEvent::create(EventTypeNames::DOMNodeRemoved, true, c->parentNode()));
     }
 
     // dispatch the DOMNodeRemovedFromDocument event to all descendants
     if (c->inDocument() && document->hasListenerType(Document::DOMNODEREMOVEDFROMDOCUMENT_LISTENER)) {
-        NodeChildRemovalTracker scope(&child);
+        NodeChildRemovalTracker scope(child);
         for (; c; c = NodeTraversal::next(c.get(), &child))
             c->dispatchScopedEvent(MutationEvent::create(EventTypeNames::DOMNodeRemovedFromDocument, false));
     }
diff --git a/Source/core/dom/ContainerNode.h b/Source/core/dom/ContainerNode.h
index 16d0942..e7d067c 100644
--- a/Source/core/dom/ContainerNode.h
+++ b/Source/core/dom/ContainerNode.h
@@ -106,8 +106,8 @@
     // However, arbitrary code may be run by beforeload handlers.
     void parserAppendChild(PassRefPtr<Node>);
     void parserRemoveChild(Node&);
-    void parserInsertBefore(PassRefPtr<Node> newChild, Node* refChild);
-    void parserTakeAllChildrenFrom(ContainerNode*);
+    void parserInsertBefore(PassRefPtr<Node> newChild, Node& refChild);
+    void parserTakeAllChildrenFrom(ContainerNode&);
 
     void removeChildren();
 
@@ -235,10 +235,10 @@
 const int initialNodeVectorSize = 11;
 typedef Vector<RefPtr<Node>, initialNodeVectorSize> NodeVector;
 
-inline void getChildNodes(Node* node, NodeVector& nodes)
+inline void getChildNodes(Node& node, NodeVector& nodes)
 {
     ASSERT(!nodes.size());
-    for (Node* child = node->firstChild(); child; child = child->nextSibling())
+    for (Node* child = node.firstChild(); child; child = child->nextSibling())
         nodes.append(child);
 }
 
diff --git a/Source/core/dom/ContainerNodeAlgorithms.h b/Source/core/dom/ContainerNodeAlgorithms.h
index a0b7dbe..c3cd3bf 100644
--- a/Source/core/dom/ContainerNodeAlgorithms.h
+++ b/Source/core/dom/ContainerNodeAlgorithms.h
@@ -313,7 +313,7 @@
 {
     // Must disable frame loading in the subtree so an unload handler cannot
     // insert more frames and create loaded frames in detached subtrees.
-    SubframeLoadingDisabler disabler(&m_root);
+    SubframeLoadingDisabler disabler(m_root);
 
     for (unsigned i = 0; i < m_frameOwners.size(); ++i) {
         HTMLFrameOwnerElement* owner = m_frameOwners[i].get();
diff --git a/Source/core/dom/ContextFeatures.h b/Source/core/dom/ContextFeatures.h
index 231ee04..b3f309f 100644
--- a/Source/core/dom/ContextFeatures.h
+++ b/Source/core/dom/ContextFeatures.h
@@ -27,7 +27,7 @@
 #ifndef ContextFeatures_h
 #define ContextFeatures_h
 
-#include "core/platform/RefCountedSupplement.h"
+#include "platform/RefCountedSupplement.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/Document.cpp b/Source/core/dom/Document.cpp
index 2f97a3f..ddbf569 100644
--- a/Source/core/dom/Document.cpp
+++ b/Source/core/dom/Document.cpp
@@ -174,6 +174,7 @@
 #include "platform/network/HTTPParsers.h"
 #include "platform/text/PlatformLocale.h"
 #include "platform/text/SegmentedString.h"
+#include "weborigin/OriginAccessEntry.h"
 #include "weborigin/SchemeRegistry.h"
 #include "weborigin/SecurityOrigin.h"
 #include "wtf/CurrentTime.h"
@@ -406,6 +407,7 @@
     , m_gotoAnchorNeededAfterStylesheetsLoad(false)
     , m_containsValidityStyleRules(false)
     , m_updateFocusAppearanceRestoresSelection(false)
+    , m_containsPlugins(false)
     , m_ignoreDestructiveWriteCount(0)
     , m_titleSetExplicitly(false)
     , m_markers(adoptPtr(new DocumentMarkerController))
@@ -487,20 +489,9 @@
     m_lifecyle.advanceTo(DocumentLifecycle::Inactive);
 }
 
-static bool isAttributeOnAllOwners(const WebCore::QualifiedName& attribute, const WebCore::QualifiedName& prefixedAttribute, const HTMLFrameOwnerElement* owner)
-{
-    if (!owner)
-        return true;
-    do {
-        if (!(owner->hasAttribute(attribute) || owner->hasAttribute(prefixedAttribute)))
-            return false;
-    } while ((owner = owner->document().ownerElement()));
-    return true;
-}
-
 Document::~Document()
 {
-    ASSERT(!renderer());
+    ASSERT(!renderView());
     ASSERT(m_ranges.isEmpty());
     ASSERT(!m_parentTreeScope);
     ASSERT(!hasGuardRefCount());
@@ -1022,7 +1013,7 @@
 
 PassRefPtr<DOMNamedFlowCollection> Document::webkitGetNamedFlows()
 {
-    if (!RuntimeEnabledFeatures::cssRegionsEnabled() || !renderer())
+    if (!RuntimeEnabledFeatures::cssRegionsEnabled() || !isActive())
         return 0;
 
     updateStyleIfNeeded();
@@ -1197,7 +1188,7 @@
 
 Element* Document::elementFromPoint(int x, int y) const
 {
-    if (!renderer())
+    if (!isActive())
         return 0;
 
     return TreeScope::elementFromPoint(x, y);
@@ -1205,7 +1196,7 @@
 
 PassRefPtr<Range> Document::caretRangeFromPoint(int x, int y)
 {
-    if (!renderer())
+    if (!isActive())
         return 0;
     LayoutPoint localPoint;
     RenderObject* renderer = rendererFromPoint(this, x, y, &localPoint);
@@ -1543,7 +1534,7 @@
 
 void Document::unscheduleStyleRecalc()
 {
-    ASSERT(!confusingAndOftenMisusedAttached() || (!needsStyleRecalc() && !childNeedsStyleRecalc()));
+    ASSERT(!isActive() || (!needsStyleRecalc() && !childNeedsStyleRecalc()));
     m_styleRecalcTimer.stop();
 }
 
@@ -1704,9 +1695,9 @@
         if (change == Force || (change >= Inherit && shouldDisplaySeamlesslyWithParent())) {
             m_hasNodesWithPlaceholderStyle = false;
             RefPtr<RenderStyle> documentStyle = StyleResolver::styleForDocument(*this, m_styleResolver ? m_styleResolver->fontSelector() : 0);
-            StyleRecalcChange localChange = RenderStyle::compare(documentStyle.get(), renderer()->style());
+            StyleRecalcChange localChange = RenderStyle::compare(documentStyle.get(), renderView()->style());
             if (localChange != NoChange)
-                renderer()->setStyle(documentStyle.release());
+                renderView()->setStyle(documentStyle.release());
         }
 
         inheritHtmlAndBodyElementStyles(change);
@@ -1788,7 +1779,7 @@
     updateStyleIfNeeded();
 
     // Only do a layout if changes have occurred that make it necessary.
-    if (frameView && renderer() && (frameView->layoutPending() || renderer()->needsLayout()))
+    if (frameView && isActive() && (frameView->layoutPending() || renderView()->needsLayout()))
         frameView->layout();
 
     if (frameView)
@@ -1957,7 +1948,7 @@
 
 void Document::attach(const AttachContext& context)
 {
-    ASSERT(!confusingAndOftenMisusedAttached());
+    ASSERT(m_lifecyle.state() == DocumentLifecycle::Inactive);
     ASSERT(!m_axObjectCache || this != topDocument());
 
     m_renderView = new RenderView(this);
@@ -1976,10 +1967,9 @@
 
 void Document::detach(const AttachContext& context)
 {
+    ASSERT(isActive());
     m_lifecyle.advanceTo(DocumentLifecycle::Stopping);
 
-    ASSERT(confusingAndOftenMisusedAttached());
-
     if (page())
         page()->documentDetached(this);
 
@@ -1996,20 +1986,14 @@
     if (svgExtensions())
         accessSVGExtensions()->pauseAnimations();
 
-    RenderView* renderView = m_renderView;
+    m_renderView->setIsInWindow(false);
 
-    documentWillBecomeInactive();
-
+    // FIXME: How can the frame be null here?
     if (m_frame) {
-        FrameView* view = m_frame->view();
-        if (view)
+        if (FrameView* view = m_frame->view())
             view->detachCustomScrollbars();
     }
 
-    // indicate destruction mode, i.e. confusingAndOftenMisusedAttached() but renderer == 0
-    setRenderer(0);
-    m_renderView = 0;
-
     m_hoverNode = 0;
     m_focusedElement = 0;
     m_activeElement = 0;
@@ -2022,9 +2006,6 @@
 
     clearStyleResolver();
 
-    if (renderView)
-        renderView->destroy();
-
     if (m_touchEventTargets && m_touchEventTargets->size() && parentDocument())
         parentDocument()->didRemoveEventTargetNode(this);
 
@@ -2046,9 +2027,8 @@
 {
     disconnectDescendantFrames();
 
-    // The process of disconnecting descendant frames could have already
-    // detached us.
-    if (!confusingAndOftenMisusedAttached())
+    // The process of disconnecting descendant frames could have already detached us.
+    if (!isActive())
         return;
 
     if (DOMWindow* window = this->domWindow())
@@ -2081,7 +2061,7 @@
 
     // If the renderer is gone then we are in the process of destruction.
     // This method will be called before m_frame = 0.
-    if (!topDocument()->renderer())
+    if (!topDocument()->isActive())
         return 0;
 
     return topDocument()->m_axObjectCache.get();
@@ -2099,7 +2079,7 @@
     Document* topDocument = this->topDocument();
 
     // If the document has already been detached, do not make a new axObjectCache.
-    if (!topDocument->renderer())
+    if (!topDocument->isActive())
         return 0;
 
     ASSERT(topDocument == this || !m_axObjectCache);
@@ -2112,8 +2092,8 @@
 {
     m_visuallyOrdered = true;
     // FIXME: How is possible to not have a renderer here?
-    if (renderer())
-        renderer()->style()->setRTLOrdering(VisualOrder);
+    if (renderView())
+        renderView()->style()->setRTLOrdering(VisualOrder);
     setNeedsStyleRecalc();
 }
 
@@ -2365,7 +2345,7 @@
         return;
     }
 
-    RenderObject* renderObject = renderer();
+    RenderView* renderView = this->renderView();
 
     // We used to force a synchronous display and flush here.  This really isn't
     // necessary and can in fact be actively harmful if pages are loading at a rate of > 60fps
@@ -2375,25 +2355,25 @@
         updateStyleIfNeeded();
 
         // Always do a layout after loading if needed.
-        if (view() && renderObject && (!renderObject->firstChild() || renderObject->needsLayout()))
+        if (view() && renderView && (!renderView->firstChild() || renderView->needsLayout()))
             view()->layout();
     }
 
     m_loadEventProgress = LoadEventCompleted;
 
-    if (f && renderObject && AXObjectCache::accessibilityEnabled()) {
+    if (f && renderView && AXObjectCache::accessibilityEnabled()) {
         // The AX cache may have been cleared at this point, but we need to make sure it contains an
         // AX object to send the notification to. getOrCreate will make sure that an valid AX object
         // exists in the cache (we ignore the return value because we don't need it here). This is
         // only safe to call when a layout is not in progress, so it can not be used in postNotification.
         if (AXObjectCache* cache = axObjectCache()) {
-            cache->getOrCreate(renderObject);
+            cache->getOrCreate(renderView);
             if (this == topDocument()) {
-                cache->postNotification(renderObject, AXObjectCache::AXLoadComplete, true);
+                cache->postNotification(renderView, AXObjectCache::AXLoadComplete, true);
             } else {
                 // AXLoadComplete can only be posted on the top document, so if it's a document
                 // in an iframe that just finished loading, post AXLayoutComplete instead.
-                cache->postNotification(renderObject, AXObjectCache::AXLayoutComplete, true);
+                cache->postNotification(renderView, AXObjectCache::AXLayoutComplete, true);
             }
         }
     }
@@ -2983,15 +2963,13 @@
 
 MouseEventWithHitTestResults Document::prepareMouseEvent(const HitTestRequest& request, const LayoutPoint& documentPoint, const PlatformMouseEvent& event)
 {
-    ASSERT(!renderer() || renderer()->isRenderView());
-
     // RenderView::hitTest causes a layout, and we don't want to hit that until the first
     // layout because until then, there is nothing shown on the screen - the user can't
     // have intentionally clicked on something belonging to this page. Furthermore,
     // mousemove events before the first layout should not lead to a premature layout()
     // happening, which could show a flash of white.
     // See also the similar code in EventHandler::hitTestResultAtPoint.
-    if (!renderer() || !view() || !view()->didFirstLayout())
+    if (!isActive() || !view() || !view()->didFirstLayout())
         return MouseEventWithHitTestResults(event, HitTestResult(LayoutPoint()));
 
     HitTestResult result(documentPoint);
@@ -3031,13 +3009,9 @@
     return false;
 }
 
-bool Document::canReplaceChild(Node* newChild, Node* oldChild)
+bool Document::canReplaceChild(Node& newChild, Node& oldChild)
 {
-    if (!oldChild)
-        // ContainerNode::replaceChild will raise a NotFoundError.
-        return true;
-
-    if (oldChild->nodeType() == newChild->nodeType())
+    if (oldChild.nodeType() == newChild.nodeType())
         return true;
 
     int numDoctypes = 0;
@@ -3062,8 +3036,8 @@
     }
 
     // Then, see how many doctypes and elements might be added by the new child.
-    if (newChild->nodeType() == DOCUMENT_FRAGMENT_NODE) {
-        for (Node* c = newChild->firstChild(); c; c = c->nextSibling()) {
+    if (newChild.nodeType() == DOCUMENT_FRAGMENT_NODE) {
+        for (Node* c = newChild.firstChild(); c; c = c->nextSibling()) {
             switch (c->nodeType()) {
             case ATTRIBUTE_NODE:
             case CDATA_SECTION_NODE:
@@ -3086,7 +3060,7 @@
             }
         }
     } else {
-        switch (newChild->nodeType()) {
+        switch (newChild.nodeType()) {
         case ATTRIBUTE_NODE:
         case CDATA_SECTION_NODE:
         case DOCUMENT_FRAGMENT_NODE:
@@ -3172,7 +3146,7 @@
 {
     // Don't bother updating, since we haven't loaded all our style info yet
     // and haven't calculated the style selector for the first time.
-    if (!confusingAndOftenMisusedAttached() || (!m_didCalculateStyleResolver && !haveStylesheetsLoaded())) {
+    if (!isActive() || (!m_didCalculateStyleResolver && !haveStylesheetsLoaded())) {
         m_styleResolver.clear();
         return;
     }
@@ -3509,19 +3483,19 @@
     HashSet<NodeIterator*>::const_iterator nodeIteratorsEnd = m_nodeIterators.end();
     for (HashSet<NodeIterator*>::const_iterator it = m_nodeIterators.begin(); it != nodeIteratorsEnd; ++it) {
         for (Node* n = container->firstChild(); n; n = n->nextSibling())
-            (*it)->nodeWillBeRemoved(n);
+            (*it)->nodeWillBeRemoved(*n);
     }
 
     if (Frame* frame = this->frame()) {
         for (Node* n = container->firstChild(); n; n = n->nextSibling()) {
-            frame->eventHandler().nodeWillBeRemoved(n);
-            frame->selection().nodeWillBeRemoved(n);
-            frame->page()->dragCaretController().nodeWillBeRemoved(n);
+            frame->eventHandler().nodeWillBeRemoved(*n);
+            frame->selection().nodeWillBeRemoved(*n);
+            frame->page()->dragCaretController().nodeWillBeRemoved(*n);
         }
     }
 }
 
-void Document::nodeWillBeRemoved(Node* n)
+void Document::nodeWillBeRemoved(Node& n)
 {
     HashSet<NodeIterator*>::const_iterator nodeIteratorsEnd = m_nodeIterators.end();
     for (HashSet<NodeIterator*>::const_iterator it = m_nodeIterators.begin(); it != nodeIteratorsEnd; ++it)
@@ -3773,42 +3747,15 @@
         return;
     }
 
-    // Both NS and IE specify that changing the domain is only allowed when
-    // the new domain is a suffix of the old domain.
-
-    // If the new domain is the same as the old domain, still call
-    // securityOrigin()->setDomainForDOM. This will change the
-    // security check behavior. For example, if a page loaded on port 8000
-    // assigns its current domain using document.domain, the page will
-    // allow other pages loaded on different ports in the same domain that
-    // have also assigned to access this page.
-    if (equalIgnoringCase(domain(), newDomain)) {
-        securityOrigin()->setDomainFromDOM(newDomain);
-        if (m_frame)
-            m_frame->script().updateSecurityOrigin();
-        return;
-    }
-
-    int oldLength = domain().length();
-    int newLength = newDomain.length();
-    String exceptionMessage =  ExceptionMessages::failedToSet("domain", "Document", "'" + newDomain + "' is not a suffix of '" + domain() + "'.");
-    // e.g. newDomain = subdomain.www.example.com (25) and domain() = www.example.com (15)
-    if (newLength >= oldLength) {
+    String exceptionMessage = ExceptionMessages::failedToSet("domain", "Document", "'" + newDomain + "' is not a suffix of '" + domain() + "'.");
+    if (newDomain.isEmpty()) {
         es.throwSecurityError(exceptionMessage);
         return;
     }
 
-    String test = domain();
-    // Check that it's a complete suffix, not e.g. "ample.com"
-    if (test[oldLength - newLength - 1] != '.') {
-        es.throwSecurityError(exceptionMessage);
-        return;
-    }
-
-    // Now test is "example.com" from domain()
-    // and we check that it's the same thing as newDomain
-    test.remove(0, oldLength - newLength);
-    if (test != newDomain) {
+    OriginAccessEntry::IPAddressSetting ipAddressSetting = settings() && settings()->treatIPAddressAsDomain() ? OriginAccessEntry::TreatIPAddressAsDomain : OriginAccessEntry::TreatIPAddressAsIPAddress;
+    OriginAccessEntry accessEntry(securityOrigin()->protocol(), newDomain, OriginAccessEntry::AllowSubdomains, ipAddressSetting);
+    if (!accessEntry.matchesOrigin(*securityOrigin())) {
         es.throwSecurityError(exceptionMessage);
         return;
     }
@@ -4030,12 +3977,6 @@
     return completeURL(url, m_baseURL);
 }
 
-void Document::documentWillBecomeInactive()
-{
-    if (renderer())
-        renderView()->setIsInWindow(false);
-}
-
 // Support for Javascript execCommand, and related methods
 
 static Editor::Command command(Document* document, const String& commandName, bool userInterface = false)
diff --git a/Source/core/dom/Document.h b/Source/core/dom/Document.h
index 12e5c3f..00a32b9 100644
--- a/Source/core/dom/Document.h
+++ b/Source/core/dom/Document.h
@@ -312,7 +312,7 @@
      */
     PassRefPtr<NodeList> nodesFromRect(int centerX, int centerY,
         unsigned topPadding, unsigned rightPadding, unsigned bottomPadding, unsigned leftPadding,
-        HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::DisallowShadowContent) const;
+        HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::ConfusingAndOftenMisusedDisallowShadowContent) const;
     Element* elementFromPoint(int x, int y) const;
     PassRefPtr<Range> caretRangeFromPoint(int x, int y);
 
@@ -485,6 +485,7 @@
     void prepareForDestruction();
 
     RenderView* renderView() const { return m_renderView; }
+    void clearRenderView() { m_renderView = 0; }
 
     AXObjectCache* existingAXObjectCache() const;
     AXObjectCache* axObjectCache() const;
@@ -648,8 +649,8 @@
     // nodeChildrenWillBeRemoved is used when removing all node children at once.
     void nodeChildrenWillBeRemoved(ContainerNode*);
     // nodeWillBeRemoved is only safe when removing one node at a time.
-    void nodeWillBeRemoved(Node*);
-    bool canReplaceChild(Node* newChild, Node* oldChild);
+    void nodeWillBeRemoved(Node&);
+    bool canReplaceChild(Node& newChild, Node& oldChild);
 
     void didInsertText(Node*, unsigned offset, unsigned length);
     void didRemoveText(Node*, unsigned offset, unsigned length);
@@ -840,8 +841,6 @@
 
     void finishedParsing();
 
-    void documentWillBecomeInactive();
-
     void setDecoder(PassRefPtr<TextResourceDecoder>);
     TextResourceDecoder* decoder() const { return m_decoder.get(); }
 
@@ -884,6 +883,9 @@
     bool processingLoadEvent() const { return m_loadEventProgress == LoadEventInProgress; }
     bool loadEventFinished() const { return m_loadEventProgress >= LoadEventCompleted; }
 
+    void setContainsPlugins() { m_containsPlugins = true; }
+    bool containsPlugins() const { return m_containsPlugins; }
+
     virtual bool isContextThread() const;
     virtual bool isJSExecutionForbidden() const { return false; }
 
@@ -998,6 +1000,8 @@
 
     DocumentLifecycleNotifier& lifecycleNotifier();
     bool isActive() const { return m_lifecyle.state() == DocumentLifecycle::Active; }
+    bool isStopping() const { return m_lifecyle.state() == DocumentLifecycle::Stopping; }
+    bool isStopped() const { return m_lifecyle.state() == DocumentLifecycle::Stopped; }
 
     enum HttpRefreshType {
         HttpRefreshFromHeader,
@@ -1191,6 +1195,7 @@
     bool m_haveExplicitlyDisabledDNSPrefetch;
     bool m_containsValidityStyleRules;
     bool m_updateFocusAppearanceRestoresSelection;
+    bool m_containsPlugins;
 
     // http://www.whatwg.org/specs/web-apps/current-work/#ignore-destructive-writes-counter
     unsigned m_ignoreDestructiveWriteCount;
diff --git a/Source/core/dom/Element.cpp b/Source/core/dom/Element.cpp
index 41c734a..36cdb70 100644
--- a/Source/core/dom/Element.cpp
+++ b/Source/core/dom/Element.cpp
@@ -72,6 +72,7 @@
 #include "core/editing/FrameSelection.h"
 #include "core/editing/TextIterator.h"
 #include "core/editing/htmlediting.h"
+#include "core/editing/markup.h"
 #include "core/events/EventDispatcher.h"
 #include "core/events/FocusEvent.h"
 #include "core/frame/ContentSecurityPolicy.h"
@@ -86,6 +87,7 @@
 #include "core/html/HTMLLabelElement.h"
 #include "core/html/HTMLOptionsCollection.h"
 #include "core/html/HTMLTableRowsCollection.h"
+#include "core/html/HTMLTemplateElement.h"
 #include "core/html/parser/HTMLParserIdioms.h"
 #include "core/page/FocusController.h"
 #include "core/page/Page.h"
@@ -960,7 +962,7 @@
 
 void Element::attributeChanged(const QualifiedName& name, const AtomicString& newValue, AttributeModificationReason reason)
 {
-    if (ElementShadow* parentElementShadow = shadowOfParentForDistribution(this)) {
+    if (ElementShadow* parentElementShadow = shadowWhereNodeCanBeDistributed(*this)) {
         if (shouldInvalidateDistributionWhenAttributeChanged(parentElementShadow, name, newValue))
             parentElementShadow->setNeedsDistributionRecalc();
     }
@@ -1272,14 +1274,7 @@
     if (containsFullScreenElement() && parentElement() && !parentElement()->containsFullScreenElement())
         setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(true);
 
-    if (Element* before = pseudoElement(BEFORE))
-        before->insertedInto(insertionPoint);
-
-    if (Element* after = pseudoElement(AFTER))
-        after->insertedInto(insertionPoint);
-
-    if (Element* backdrop = pseudoElement(BACKDROP))
-        backdrop->insertedInto(insertionPoint);
+    ASSERT(!hasRareData() || !elementRareData()->hasPseudoElements());
 
     if (!insertionPoint->isInTreeScope())
         return InsertionDone;
@@ -1317,15 +1312,7 @@
 {
     bool wasInDocument = insertionPoint->inDocument();
 
-    if (Element* before = pseudoElement(BEFORE))
-        before->removedFrom(insertionPoint);
-
-    if (Element* after = pseudoElement(AFTER))
-        after->removedFrom(insertionPoint);
-
-    if (Element* backdrop = pseudoElement(BACKDROP))
-        backdrop->removedFrom(insertionPoint);
-    document().removeFromTopLayer(this);
+    ASSERT(!hasRareData() || !elementRareData()->hasPseudoElements());
 
     if (containsFullScreenElement())
         setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(false);
@@ -1360,6 +1347,8 @@
             CustomElement::didLeaveDocument(this, insertionPoint->document());
     }
 
+    document().removeFromTopLayer(this);
+
     if (hasRareData())
         elementRareData()->setIsInCanvasSubtree(false);
 }
@@ -1516,7 +1505,7 @@
     }
 
     // Active InsertionPoints have no renderers so they never need to go through a recalc.
-    if ((change >= Inherit || needsStyleRecalc()) && parentRenderStyle() && !isActiveInsertionPoint(this))
+    if ((change >= Inherit || needsStyleRecalc()) && parentRenderStyle() && !isActiveInsertionPoint(*this))
         change = recalcOwnStyle(change);
 
     // If we reattached we don't need to recalc the style of our descendants anymore.
@@ -1678,7 +1667,7 @@
 void Element::didAffectSelector(AffectedSelectorMask mask)
 {
     setNeedsStyleRecalc();
-    if (ElementShadow* elementShadow = shadowOfParentForDistribution(this))
+    if (ElementShadow* elementShadow = shadowWhereNodeCanBeDistributed(*this))
         elementShadow->didAffectSelector(mask);
 }
 
@@ -2202,6 +2191,50 @@
     dispatchScopedEventDispatchMediator(FocusOutEventDispatchMediator::create(FocusEvent::create(eventType, true, false, document().domWindow(), 0, newFocusedElement)));
 }
 
+String Element::innerHTML() const
+{
+    return createMarkup(this, ChildrenOnly);
+}
+
+String Element::outerHTML() const
+{
+    return createMarkup(this);
+}
+
+void Element::setInnerHTML(const String& html, ExceptionState& es)
+{
+    if (RefPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(html, this, AllowScriptingContent, "innerHTML", es)) {
+        ContainerNode* container = this;
+        if (hasTagName(templateTag))
+            container = toHTMLTemplateElement(this)->content();
+        replaceChildrenWithFragment(container, fragment.release(), es);
+    }
+}
+
+void Element::setOuterHTML(const String& html, ExceptionState& es)
+{
+    Node* p = parentNode();
+    if (!p || !p->isElementNode()) {
+        es.throwUninformativeAndGenericDOMException(NoModificationAllowedError);
+        return;
+    }
+    RefPtr<Element> parent = toElement(p);
+    RefPtr<Node> prev = previousSibling();
+    RefPtr<Node> next = nextSibling();
+
+    RefPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(html, parent.get(), AllowScriptingContent, "outerHTML", es);
+    if (es.hadException())
+        return;
+
+    parent->replaceChild(fragment.release(), this, es);
+    RefPtr<Node> node = next ? next->previousSibling() : 0;
+    if (!es.hadException() && node && node->isTextNode())
+        mergeWithNextTextNode(node.release(), es);
+
+    if (!es.hadException() && prev && prev->isTextNode())
+        mergeWithNextTextNode(prev.release(), es);
+}
+
 String Element::innerText()
 {
     // We need to update layout, since plainText uses line boxes in the render tree.
@@ -2580,8 +2613,11 @@
     RefPtr<PseudoElement> element = PseudoElement::create(this, pseudoId);
     if (pseudoId == BACKDROP)
         document().addToTopLayer(element.get(), this);
+    element->insertedInto(this);
     element->attach();
 
+    InspectorInstrumentation::pseudoElementCreated(element.get());
+
     ensureElementRareData().setPseudoElement(pseudoId, element.release());
 }
 
@@ -2607,7 +2643,7 @@
     SelectorQuery* selectorQuery = document().selectorQueryCache().add(selector, document(), es);
     if (!selectorQuery)
         return false;
-    return selectorQuery->matches(this);
+    return selectorQuery->matches(*this);
 }
 
 DOMTokenList* Element::classList()
@@ -3186,6 +3222,11 @@
     return ensureElementRareData().ensureInputMethodContext(toHTMLElement(this));
 }
 
+bool Element::hasInputMethodContext() const
+{
+    return hasRareData() && elementRareData()->hasInputMethodContext();
+}
+
 bool Element::hasPendingResources() const
 {
     return hasRareData() && elementRareData()->hasPendingResources();
diff --git a/Source/core/dom/Element.h b/Source/core/dom/Element.h
index c35fe66..bcdbf85 100644
--- a/Source/core/dom/Element.h
+++ b/Source/core/dom/Element.h
@@ -82,6 +82,11 @@
     static PassRefPtr<Element> create(const QualifiedName&, Document*);
     virtual ~Element();
 
+    String innerHTML() const;
+    String outerHTML() const;
+    void setInnerHTML(const String&, ExceptionState&);
+    void setOuterHTML(const String&, ExceptionState&);
+
     DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecopy);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecut);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(beforepaste);
@@ -501,6 +506,7 @@
     bool hasActiveAnimations() const;
 
     InputMethodContext* inputMethodContext();
+    bool hasInputMethodContext() const;
 
     virtual void setPrefix(const AtomicString&, ExceptionState&) OVERRIDE FINAL;
 
diff --git a/Source/core/dom/Element.idl b/Source/core/dom/Element.idl
index 8d45e7d..3a8d2ba 100644
--- a/Source/core/dom/Element.idl
+++ b/Source/core/dom/Element.idl
@@ -92,6 +92,8 @@
 
     // HTML 5
     NodeList getElementsByClassName([Default=Undefined] optional DOMString name);
+    [TreatNullAs=NullString, CustomElementCallbacks, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds, SetterRaisesException] attribute DOMString innerHTML;
+    [TreatNullAs=NullString, CustomElementCallbacks, SetterRaisesException] attribute DOMString outerHTML;
 
     [Reflect=class, TreatNullAs=NullString, PerWorldBindings] attribute DOMString className;
     [PerWorldBindings] readonly attribute DOMTokenList classList;
diff --git a/Source/core/dom/ElementRareData.h b/Source/core/dom/ElementRareData.h
index d9be4ce..ac97c75 100644
--- a/Source/core/dom/ElementRareData.h
+++ b/Source/core/dom/ElementRareData.h
@@ -30,7 +30,6 @@
 #include "core/dom/shadow/ElementShadow.h"
 #include "core/html/ClassList.h"
 #include "core/html/ime/InputMethodContext.h"
-#include "core/inspector/InspectorInstrumentation.h"
 #include "core/rendering/style/StyleInheritedData.h"
 #include "wtf/OwnPtr.h"
 
@@ -139,6 +138,7 @@
     bool hasPendingResources() const { return m_hasPendingResources; }
     void setHasPendingResources(bool has) { m_hasPendingResources = has; }
 
+    bool hasInputMethodContext() const { return m_inputMethodContext; }
     InputMethodContext* ensureInputMethodContext(HTMLElement* element)
     {
         if (!m_inputMethodContext)
@@ -146,6 +146,8 @@
         return m_inputMethodContext.get();
     }
 
+    bool hasPseudoElements() const;
+
 private:
     short m_tabIndex;
     unsigned short m_childIndex;
@@ -187,7 +189,6 @@
     RefPtr<PseudoElement> m_backdrop;
 
     ElementRareData(RenderObject*);
-    void releasePseudoElement(PseudoElement*);
 };
 
 inline IntSize defaultMinimumSizeForResizing()
@@ -228,26 +229,32 @@
     ASSERT(!m_backdrop);
 }
 
-inline void ElementRareData::setPseudoElement(PseudoId pseudoId, PassRefPtr<PseudoElement> prpElement)
+inline bool ElementRareData::hasPseudoElements() const
 {
-    RefPtr<PseudoElement> element = prpElement;
+    return m_generatedBefore || m_generatedAfter || m_backdrop;
+}
+
+inline void ElementRareData::setPseudoElement(PseudoId pseudoId, PassRefPtr<PseudoElement> element)
+{
     switch (pseudoId) {
     case BEFORE:
-        releasePseudoElement(m_generatedBefore.get());
+        if (m_generatedBefore)
+            m_generatedBefore->dispose();
         m_generatedBefore = element;
         break;
     case AFTER:
-        releasePseudoElement(m_generatedAfter.get());
+        if (m_generatedAfter)
+            m_generatedAfter->dispose();
         m_generatedAfter = element;
         break;
     case BACKDROP:
-        releasePseudoElement(m_backdrop.get());
+        if (m_backdrop)
+            m_backdrop->dispose();
         m_backdrop = element;
         break;
     default:
         ASSERT_NOT_REACHED();
     }
-    InspectorInstrumentation::pseudoElementCreated(element.get());
 }
 
 inline PseudoElement* ElementRareData::pseudoElement(PseudoId pseudoId) const
@@ -264,21 +271,6 @@
     }
 }
 
-inline void ElementRareData::releasePseudoElement(PseudoElement* element)
-{
-    if (!element)
-        return;
-
-    InspectorInstrumentation::pseudoElementDestroyed(element);
-
-    ASSERT(!element->nextSibling());
-    ASSERT(!element->previousSibling());
-
-    element->detach();
-    element->document().removeFromTopLayer(element);
-    element->setParentOrShadowHostNode(0);
-}
-
 inline void ElementRareData::resetStyleState()
 {
     setComputedStyle(0);
diff --git a/Source/core/dom/FullscreenElementStack.cpp b/Source/core/dom/FullscreenElementStack.cpp
index 6d0b514..89c6851 100644
--- a/Source/core/dom/FullscreenElementStack.cpp
+++ b/Source/core/dom/FullscreenElementStack.cpp
@@ -187,7 +187,6 @@
         // FIXME: Does this need to null-check settings()?
         if (!UserGestureIndicator::processingUserGesture() && (!element->isMediaElement() || document()->settings()->mediaFullscreenRequiresUserGesture()))
             break;
-        UserGestureIndicator::consumeUserGesture();
 
         // There is a previously-established user preference, security risk, or platform limitation.
         if (!document()->settings() || !document()->settings()->fullScreenEnabled())
diff --git a/Source/core/dom/MessagePort.cpp b/Source/core/dom/MessagePort.cpp
index b3dce05..91b6484 100644
--- a/Source/core/dom/MessagePort.cpp
+++ b/Source/core/dom/MessagePort.cpp
@@ -69,8 +69,8 @@
     if (ports) {
         for (unsigned int i = 0; i < ports->size(); ++i) {
             MessagePort* dataPort = (*ports)[i].get();
-            if (dataPort == this || m_entangledChannel->isConnectedTo(dataPort)) {
-                es.throwDOMException(DataCloneError, ExceptionMessages::failedToExecute("postMessage", "MessagePort", "Item #" + String::number(i) + " in the array of ports contains the " + (dataPort == this ? "source" : "target") + " port."));
+            if (dataPort == this) {
+                es.throwDOMException(DataCloneError, ExceptionMessages::failedToExecute("postMessage", "MessagePort", "Item #" + String::number(i) + " in the array of ports contains the source port."));
                 return;
             }
         }
@@ -81,7 +81,7 @@
     m_entangledChannel->postMessageToRemote(message, channels.release());
 }
 
-PassRefPtr<MessagePortChannel> MessagePort::disentangle()
+PassOwnPtr<MessagePortChannel> MessagePort::disentangle()
 {
     ASSERT(m_entangledChannel);
 
@@ -124,7 +124,7 @@
     m_closed = true;
 }
 
-void MessagePort::entangle(PassRefPtr<MessagePortChannel> remote)
+void MessagePort::entangle(PassOwnPtr<MessagePortChannel> remote)
 {
     // Only invoked to set our initial entanglement.
     ASSERT(!m_entangledChannel);
@@ -192,7 +192,7 @@
     HashSet<MessagePort*> portSet;
 
     // Walk the incoming array - if there are any duplicate ports, or null ports or cloned ports, throw an error (per section 8.3.3 of the HTML5 spec).
-    for (unsigned int i = 0; i < ports->size(); ++i) {
+    for (unsigned i = 0; i < ports->size(); ++i) {
         MessagePort* port = (*ports)[i].get();
         if (!port || port->isNeutered() || portSet.contains(port)) {
             String type;
@@ -210,10 +210,8 @@
 
     // Passed-in ports passed validity checks, so we can disentangle them.
     OwnPtr<MessagePortChannelArray> portArray = adoptPtr(new MessagePortChannelArray(ports->size()));
-    for (unsigned int i = 0 ; i < ports->size() ; ++i) {
-        RefPtr<MessagePortChannel> channel = (*ports)[i]->disentangle();
-        (*portArray)[i] = channel.release();
-    }
+    for (unsigned i = 0; i < ports->size(); ++i)
+        (*portArray)[i] = (*ports)[i]->disentangle();
     return portArray.release();
 }
 
diff --git a/Source/core/dom/MessagePort.h b/Source/core/dom/MessagePort.h
index 2f2ea5f..4540a9b 100644
--- a/Source/core/dom/MessagePort.h
+++ b/Source/core/dom/MessagePort.h
@@ -60,8 +60,8 @@
     void start();
     void close();
 
-    void entangle(PassRefPtr<MessagePortChannel>);
-    PassRefPtr<MessagePortChannel> disentangle();
+    void entangle(PassOwnPtr<MessagePortChannel>);
+    PassOwnPtr<MessagePortChannel> disentangle();
 
     // Returns 0 if there is an exception, or if the passed-in array is 0/empty.
     static PassOwnPtr<MessagePortChannelArray> disentanglePorts(const MessagePortArray*, ExceptionState&);
@@ -98,7 +98,7 @@
 private:
     explicit MessagePort(ExecutionContext&);
 
-    RefPtr<MessagePortChannel> m_entangledChannel;
+    OwnPtr<MessagePortChannel> m_entangledChannel;
 
     bool m_started;
     bool m_closed;
diff --git a/Source/core/dom/MessagePortChannel.cpp b/Source/core/dom/MessagePortChannel.cpp
index 00fd786..8f5cee3 100644
--- a/Source/core/dom/MessagePortChannel.cpp
+++ b/Source/core/dom/MessagePortChannel.cpp
@@ -39,20 +39,20 @@
 
 namespace WebCore {
 
-PassRefPtr<MessagePortChannel> MessagePortChannel::create(WebKit::WebMessagePortChannel* channel)
+PassOwnPtr<MessagePortChannel> MessagePortChannel::create(WebKit::WebMessagePortChannel* channel)
 {
-    return adoptRef(new MessagePortChannel(channel));
+    return adoptPtr(new MessagePortChannel(channel));
 }
 
 void MessagePortChannel::createChannel(MessagePort* port1, MessagePort* port2)
 {
     // Create proxies for each endpoint.
-    RefPtr<MessagePortChannel> channel1 = create(WebKit::Platform::current()->createMessagePortChannel());
-    RefPtr<MessagePortChannel> channel2 = create(WebKit::Platform::current()->createMessagePortChannel());
+    OwnPtr<MessagePortChannel> channel1 = create(WebKit::Platform::current()->createMessagePortChannel());
+    OwnPtr<MessagePortChannel> channel2 = create(WebKit::Platform::current()->createMessagePortChannel());
 
     // Entangle the two endpoints.
-    channel1->setEntangledChannel(channel2);
-    channel2->setEntangledChannel(channel1);
+    channel1->m_webChannel->entangle(channel2->m_webChannel);
+    channel2->m_webChannel->entangle(channel1->m_webChannel);
 
     // Now entangle the proxies with the appropriate local ports.
     port1->entangle(channel2.release());
@@ -126,14 +126,6 @@
     // Disentangle ourselves from the other end. We still maintain a reference to m_webChannel,
     // since previously-existing messages should still be delivered.
     m_localPort = 0;
-    m_entangledChannel = 0;
-}
-
-bool MessagePortChannel::isConnectedTo(MessagePort* port)
-{
-    MutexLocker lock(m_mutex);
-    // FIXME: Shouldn't the access to m_entangledChannel->m_localPort be protected by m_entangledChannel->m_mutex?
-    return m_entangledChannel && m_entangledChannel->m_localPort == port;
 }
 
 bool MessagePortChannel::hasPendingActivity()
@@ -149,15 +141,6 @@
         m_localPort->messageAvailable();
 }
 
-void MessagePortChannel::setEntangledChannel(PassRefPtr<MessagePortChannel> remote)
-{
-    ASSERT(m_webChannel);
-    m_webChannel->entangle(remote->m_webChannel);
-
-    MutexLocker lock(m_mutex);
-    m_entangledChannel = remote;
-}
-
 WebKit::WebMessagePortChannel* MessagePortChannel::webChannelRelease()
 {
     ASSERT(m_webChannel);
diff --git a/Source/core/dom/MessagePortChannel.h b/Source/core/dom/MessagePortChannel.h
index c6e5b53..799a6b6 100644
--- a/Source/core/dom/MessagePortChannel.h
+++ b/Source/core/dom/MessagePortChannel.h
@@ -51,14 +51,14 @@
 class SerializedScriptValue;
 
 // The overwhelmingly common case is sending a single port, so handle that efficiently with an inline buffer of size 1.
-typedef Vector<RefPtr<MessagePortChannel>, 1> MessagePortChannelArray;
+typedef Vector<OwnPtr<MessagePortChannel>, 1> MessagePortChannelArray;
 
 // MessagePortChannel is a platform-independent interface to the remote side of a message channel.
-class MessagePortChannel : public ThreadSafeRefCounted<MessagePortChannel>, public WebKit::WebMessagePortChannelClient {
+class MessagePortChannel : public WebKit::WebMessagePortChannelClient {
     WTF_MAKE_NONCOPYABLE(MessagePortChannel);
 public:
     static void createChannel(MessagePort*, MessagePort*);
-    static PassRefPtr<MessagePortChannel> create(WebKit::WebMessagePortChannel*);
+    static PassOwnPtr<MessagePortChannel> create(WebKit::WebMessagePortChannel*);
 
     virtual ~MessagePortChannel();
 
@@ -71,9 +71,6 @@
     // Closes the port (ensures that no further messages can be added to either queue).
     void close();
 
-    // Used by MessagePort.postMessage() to prevent callers from passing a port's own entangled port.
-    bool isConnectedTo(MessagePort*);
-
     // Returns true if the proxy currently contains messages for this port.
     bool hasPendingActivity();
 
@@ -89,17 +86,12 @@
 private:
     explicit MessagePortChannel(WebKit::WebMessagePortChannel*);
 
-    void setEntangledChannel(PassRefPtr<MessagePortChannel>);
-
     // WebKit::WebMessagePortChannelClient implementation
     virtual void messageAvailable() OVERRIDE;
 
     // Mutex used to ensure exclusive access to the object internals.
     Mutex m_mutex;
 
-    // Pointer to our entangled pair - cleared when close() is called.
-    RefPtr<MessagePortChannel> m_entangledChannel;
-
     // The port we are connected to - this is the port that is notified when new messages arrive.
     MessagePort* m_localPort;
 
diff --git a/Source/core/dom/Node.cpp b/Source/core/dom/Node.cpp
index 89f80b5..8fdeee7 100644
--- a/Source/core/dom/Node.cpp
+++ b/Source/core/dom/Node.cpp
@@ -383,20 +383,13 @@
     return ensureRareData().ensureNodeLists().ensureChildNodeList(this);
 }
 
-Node *Node::lastDescendant() const
+Node& Node::lastDescendant() const
 {
-    Node *n = const_cast<Node *>(this);
+    Node* n = const_cast<Node*>(this);
     while (n && n->lastChild())
         n = n->lastChild();
-    return n;
-}
-
-Node* Node::firstDescendant() const
-{
-    Node *n = const_cast<Node *>(this);
-    while (n && n->firstChild())
-        n = n->firstChild();
-    return n;
+    ASSERT(n);
+    return *n;
 }
 
 Node* Node::pseudoAwarePreviousSibling() const
@@ -720,7 +713,7 @@
 void Node::setNeedsStyleRecalc(StyleChangeType changeType, StyleChangeSource source)
 {
     ASSERT(changeType != NoStyleChange);
-    if (!confusingAndOftenMisusedAttached()) // changed compared to what?
+    if (!inActiveDocument())
         return;
 
     if (source == StyleChangeFromRenderer)
@@ -924,16 +917,17 @@
     return false;
 }
 
-bool Node::containsIncludingHostElements(const Node* node) const
+bool Node::containsIncludingHostElements(const Node& node) const
 {
-    while (node) {
-        if (node == this)
+    const Node* current = &node;
+    do {
+        if (current == this)
             return true;
-        if (node->isDocumentFragment() && toDocumentFragment(node)->isTemplateContent())
-            node = static_cast<const TemplateContentDocumentFragment*>(node)->host();
+        if (current->isDocumentFragment() && toDocumentFragment(current)->isTemplateContent())
+            current = static_cast<const TemplateContentDocumentFragment*>(current)->host();
         else
-            node = node->parentOrShadowHostNode();
-    }
+            current = current->parentOrShadowHostNode();
+    } while (current);
     return false;
 }
 
@@ -1249,7 +1243,7 @@
     SelectorQuery* selectorQuery = document().selectorQueryCache().add(selectors, document(), es);
     if (!selectorQuery)
         return 0;
-    return selectorQuery->queryFirst(this);
+    return selectorQuery->queryFirst(*this);
 }
 
 PassRefPtr<NodeList> Node::querySelectorAll(const AtomicString& selectors, ExceptionState& es)
@@ -1262,7 +1256,7 @@
     SelectorQuery* selectorQuery = document().selectorQueryCache().add(selectors, document(), es);
     if (!selectorQuery)
         return 0;
-    return selectorQuery->queryAll(this);
+    return selectorQuery->queryAll(*this);
 }
 
 Document* Node::ownerDocument() const
@@ -2518,7 +2512,7 @@
 {
     document().updateDistributionForNodeIfNeeded(this);
     Vector<InsertionPoint*, 8> insertionPoints;
-    collectInsertionPointsWhereNodeIsDistributed(this, insertionPoints);
+    collectDestinationInsertionPoints(*this, insertionPoints);
     Vector<RefPtr<Node> > filteredInsertionPoints;
     for (size_t i = 0; i < insertionPoints.size(); ++i) {
         InsertionPoint* insertionPoint = insertionPoints[i];
diff --git a/Source/core/dom/Node.h b/Source/core/dom/Node.h
index 1fe0467..fe25b60 100644
--- a/Source/core/dom/Node.h
+++ b/Source/core/dom/Node.h
@@ -216,8 +216,7 @@
     String textContent(bool convertBRsToNewlines = false) const;
     void setTextContent(const String&, ExceptionState&);
 
-    Node* lastDescendant() const;
-    Node* firstDescendant() const;
+    Node& lastDescendant() const;
 
     // Other methods (not part of DOM)
 
@@ -501,7 +500,7 @@
     bool isDescendantOf(const Node*) const;
     bool contains(const Node*) const;
     bool containsIncludingShadowDOM(const Node*) const;
-    bool containsIncludingHostElements(const Node*) const;
+    bool containsIncludingHostElements(const Node&) const;
 
     // FIXME: Remove this when crbug.com/265716 cleans up contains semantics.
     bool bindingsContains(const Node* node) const { return containsIncludingShadowDOM(node); }
@@ -922,10 +921,10 @@
 inline bool operator!=(const Node& a, const Node& b) { return !(a == b); }
 inline bool operator!=(const Node& a, const Node* b) { return !(a == b); }
 inline bool operator!=(const Node* a, const Node& b) { return !(a == b); }
-inline bool operator==(const RefPtr<Node>& a, const Node& b) { return a.get() == &b; }
-inline bool operator==(const Node& a, const RefPtr<Node>& b) { return &a == b.get(); }
-inline bool operator!=(const RefPtr<Node>& a, const Node& b) { return !(a == b); }
-inline bool operator!=(const Node& a, const RefPtr<Node>& b) { return !(a == b); }
+inline bool operator==(const PassRefPtr<Node>& a, const Node& b) { return a.get() == &b; }
+inline bool operator==(const Node& a, const PassRefPtr<Node>& b) { return &a == b.get(); }
+inline bool operator!=(const PassRefPtr<Node>& a, const Node& b) { return !(a == b); }
+inline bool operator!=(const Node& a, const PassRefPtr<Node>& b) { return !(a == b); }
 
 
 #define DEFINE_NODE_TYPE_CASTS(thisType, predicate) \
diff --git a/Source/core/dom/NodeChildRemovalTracker.h b/Source/core/dom/NodeChildRemovalTracker.h
index b4faa11..09fa829 100644
--- a/Source/core/dom/NodeChildRemovalTracker.h
+++ b/Source/core/dom/NodeChildRemovalTracker.h
@@ -33,21 +33,21 @@
 
 class NodeChildRemovalTracker {
 public:
-    explicit NodeChildRemovalTracker(Node*);
+    explicit NodeChildRemovalTracker(Node&);
     ~NodeChildRemovalTracker();
 
     static bool isBeingRemoved(Node*);
 
 private:
-    Node* node() const { return m_node; }
+    Node& node() const { return m_node; }
     NodeChildRemovalTracker* previous() { return m_previous; }
 
-    Node* m_node;
+    Node& m_node;
     NodeChildRemovalTracker* m_previous;
     static NodeChildRemovalTracker* s_last;
 };
 
-inline NodeChildRemovalTracker::NodeChildRemovalTracker(Node* node)
+inline NodeChildRemovalTracker::NodeChildRemovalTracker(Node& node)
     : m_node(node)
     , m_previous(s_last)
 {
@@ -62,7 +62,7 @@
 inline bool NodeChildRemovalTracker::isBeingRemoved(Node* node)
 {
     for (NodeChildRemovalTracker* removal = s_last; removal; removal = removal->previous()) {
-        if (removal->node()->containsIncludingShadowDOM(node))
+        if (removal->node().containsIncludingShadowDOM(node))
             return true;
     }
 
diff --git a/Source/core/dom/NodeFilter.idl b/Source/core/dom/NodeFilter.idl
index 989099f..58ac22e 100644
--- a/Source/core/dom/NodeFilter.idl
+++ b/Source/core/dom/NodeFilter.idl
@@ -19,6 +19,7 @@
  */
 
 [
+    DependentLifetime
 ] interface NodeFilter {
     // Constants returned by acceptNode
     const short               FILTER_ACCEPT                  = 1;
diff --git a/Source/core/dom/NodeIterator.cpp b/Source/core/dom/NodeIterator.cpp
index 173edc4..0770aa1 100644
--- a/Source/core/dom/NodeIterator.cpp
+++ b/Source/core/dom/NodeIterator.cpp
@@ -153,43 +153,42 @@
     m_referenceNode.node.clear();
 }
 
-void NodeIterator::nodeWillBeRemoved(Node* removedNode)
+void NodeIterator::nodeWillBeRemoved(Node& removedNode)
 {
     updateForNodeRemoval(removedNode, m_candidateNode);
     updateForNodeRemoval(removedNode, m_referenceNode);
 }
 
-void NodeIterator::updateForNodeRemoval(Node* removedNode, NodePointer& referenceNode) const
+void NodeIterator::updateForNodeRemoval(Node& removedNode, NodePointer& referenceNode) const
 {
     ASSERT(!m_detached);
-    ASSERT(removedNode);
-    ASSERT(root()->document() == removedNode->document());
+    ASSERT(root()->document() == removedNode.document());
 
     // Iterator is not affected if the removed node is the reference node and is the root.
     // or if removed node is not the reference node, or the ancestor of the reference node.
-    if (!removedNode->isDescendantOf(root()))
+    if (!removedNode.isDescendantOf(root()))
         return;
     bool willRemoveReferenceNode = removedNode == referenceNode.node;
-    bool willRemoveReferenceNodeAncestor = referenceNode.node && referenceNode.node->isDescendantOf(removedNode);
+    bool willRemoveReferenceNodeAncestor = referenceNode.node && referenceNode.node->isDescendantOf(&removedNode);
     if (!willRemoveReferenceNode && !willRemoveReferenceNodeAncestor)
         return;
 
     if (referenceNode.isPointerBeforeNode) {
-        Node* node = NodeTraversal::next(removedNode, root());
+        Node* node = NodeTraversal::next(&removedNode, root());
         if (node) {
             // Move out from under the node being removed if the new reference
             // node is a descendant of the node being removed.
-            while (node && node->isDescendantOf(removedNode))
+            while (node && node->isDescendantOf(&removedNode))
                 node = NodeTraversal::next(node, root());
             if (node)
                 referenceNode.node = node;
         } else {
-            node = NodeTraversal::previous(removedNode, root());
+            node = NodeTraversal::previous(&removedNode, root());
             if (node) {
                 // Move out from under the node being removed if the reference node is
                 // a descendant of the node being removed.
                 if (willRemoveReferenceNodeAncestor) {
-                    while (node && node->isDescendantOf(removedNode))
+                    while (node && node->isDescendantOf(&removedNode))
                         node = NodeTraversal::previous(node, root());
                 }
                 if (node) {
@@ -202,23 +201,23 @@
             }
         }
     } else {
-        Node* node = NodeTraversal::previous(removedNode, root());
+        Node* node = NodeTraversal::previous(&removedNode, root());
         if (node) {
             // Move out from under the node being removed if the reference node is
             // a descendant of the node being removed.
             if (willRemoveReferenceNodeAncestor) {
-                while (node && node->isDescendantOf(removedNode))
+                while (node && node->isDescendantOf(&removedNode))
                     node = NodeTraversal::previous(node, root());
             }
             if (node)
                 referenceNode.node = node;
         } else {
             // FIXME: This branch doesn't appear to have any LayoutTests.
-            node = NodeTraversal::next(removedNode, root());
+            node = NodeTraversal::next(&removedNode, root());
             // Move out from under the node being removed if the reference node is
             // a descendant of the node being removed.
             if (willRemoveReferenceNodeAncestor) {
-                while (node && node->isDescendantOf(removedNode))
+                while (node && node->isDescendantOf(&removedNode))
                     node = NodeTraversal::previous(node, root());
             }
             if (node)
diff --git a/Source/core/dom/NodeIterator.h b/Source/core/dom/NodeIterator.h
index 4c504bf..1f06a57 100644
--- a/Source/core/dom/NodeIterator.h
+++ b/Source/core/dom/NodeIterator.h
@@ -51,7 +51,7 @@
     bool pointerBeforeReferenceNode() const { return m_referenceNode.isPointerBeforeNode; }
 
     // This function is called before any node is removed from the document tree.
-    void nodeWillBeRemoved(Node*);
+    void nodeWillBeRemoved(Node&);
 
 private:
     NodeIterator(PassRefPtr<Node>, unsigned whatToShow, PassRefPtr<NodeFilter>);
@@ -66,7 +66,7 @@
         bool moveToPrevious(Node* root);
     };
 
-    void updateForNodeRemoval(Node* nodeToBeRemoved, NodePointer&) const;
+    void updateForNodeRemoval(Node& nodeToBeRemoved, NodePointer&) const;
 
     NodePointer m_referenceNode;
     NodePointer m_candidateNode;
diff --git a/Source/core/dom/NodeIterator.idl b/Source/core/dom/NodeIterator.idl
index 5e52661..9c636c4 100644
--- a/Source/core/dom/NodeIterator.idl
+++ b/Source/core/dom/NodeIterator.idl
@@ -20,7 +20,7 @@
 
 // Introduced in DOM Level 2:
 [
-    CustomToV8
+    SetReference(NodeFilter filter)
 ] interface NodeIterator {
     readonly attribute Node root;
     readonly attribute unsigned long whatToShow;
diff --git a/Source/core/dom/NodeRareData.h b/Source/core/dom/NodeRareData.h
index 8d310c3..38dd440 100644
--- a/Source/core/dom/NodeRareData.h
+++ b/Source/core/dom/NodeRareData.h
@@ -60,7 +60,7 @@
 
     void removeChildNodeList(ChildNodeList* list)
     {
-        ASSERT(m_childNodeList = list);
+        ASSERT(m_childNodeList == list);
         if (deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList(list->ownerNode()))
             return;
         m_childNodeList = 0;
diff --git a/Source/core/dom/NodeRenderingTraversal.cpp b/Source/core/dom/NodeRenderingTraversal.cpp
index 7353a13..d0648bd 100644
--- a/Source/core/dom/NodeRenderingTraversal.cpp
+++ b/Source/core/dom/NodeRenderingTraversal.cpp
@@ -34,7 +34,7 @@
 
 namespace NodeRenderingTraversal {
 
-void ParentDetails::didTraverseInsertionPoint(InsertionPoint* insertionPoint)
+void ParentDetails::didTraverseInsertionPoint(const InsertionPoint* insertionPoint)
 {
     if (!m_insertionPoint) {
         m_insertionPoint = insertionPoint;
@@ -49,10 +49,12 @@
 
 ContainerNode* parent(const Node* node, ParentDetails* details)
 {
+    ASSERT(node);
+    if (isActiveInsertionPoint(*node))
+        return 0;
     // FIXME: Once everything lazy attaches we should assert that we don't need a distribution recalc here.
     ComposedTreeWalker walker(node, ComposedTreeWalker::CanStartFromShadowBoundary);
-    ContainerNode* found = toContainerNode(walker.traverseParent(walker.get(), details));
-    return details->outOfComposition() ? 0 : found;
+    return toContainerNode(walker.traverseParent(walker.get(), details));
 }
 
 Node* nextSibling(const Node* node)
diff --git a/Source/core/dom/NodeRenderingTraversal.h b/Source/core/dom/NodeRenderingTraversal.h
index 135d866..8935ae6 100644
--- a/Source/core/dom/NodeRenderingTraversal.h
+++ b/Source/core/dom/NodeRenderingTraversal.h
@@ -40,28 +40,23 @@
     ParentDetails()
         : m_insertionPoint(0)
         , m_resetStyleInheritance(false)
-        , m_outOfComposition(false)
     { }
 
-    InsertionPoint* insertionPoint() const { return m_insertionPoint; }
+    const InsertionPoint* insertionPoint() const { return m_insertionPoint; }
     bool resetStyleInheritance() const { return m_resetStyleInheritance; }
-    bool outOfComposition() const { return m_outOfComposition; }
 
-    void didTraverseInsertionPoint(InsertionPoint*);
+    void didTraverseInsertionPoint(const InsertionPoint*);
     void didTraverseShadowRoot(const ShadowRoot*);
-    void childWasOutOfComposition() { m_outOfComposition = true; }
 
     bool operator==(const ParentDetails& other)
     {
         return m_insertionPoint == other.m_insertionPoint
-            && m_resetStyleInheritance == other.m_resetStyleInheritance
-            && m_outOfComposition == other.m_outOfComposition;
+            && m_resetStyleInheritance == other.m_resetStyleInheritance;
     }
 
 private:
-    InsertionPoint* m_insertionPoint;
+    const InsertionPoint* m_insertionPoint;
     bool m_resetStyleInheritance;
-    bool m_outOfComposition;
 };
 
 ContainerNode* parent(const Node*);
diff --git a/Source/core/dom/PseudoElement.cpp b/Source/core/dom/PseudoElement.cpp
index f54a507..3900d2f 100644
--- a/Source/core/dom/PseudoElement.cpp
+++ b/Source/core/dom/PseudoElement.cpp
@@ -27,6 +27,7 @@
 #include "config.h"
 #include "core/dom/PseudoElement.h"
 
+#include "core/inspector/InspectorInstrumentation.h"
 #include "core/rendering/RenderObject.h"
 #include "core/rendering/RenderQuote.h"
 #include "core/rendering/style/ContentData.h"
@@ -67,6 +68,19 @@
     return parentOrShadowHostElement()->renderer()->getCachedPseudoStyle(m_pseudoId);
 }
 
+void PseudoElement::dispose()
+{
+    InspectorInstrumentation::pseudoElementDestroyed(this);
+
+    ASSERT(!nextSibling());
+    ASSERT(!previousSibling());
+
+    detach();
+    RefPtr<Element> parent = parentOrShadowHostElement();
+    setParentOrShadowHostNode(0);
+    removedFrom(parent.get());
+}
+
 void PseudoElement::attach(const AttachContext& context)
 {
     ASSERT(!renderer());
diff --git a/Source/core/dom/PseudoElement.h b/Source/core/dom/PseudoElement.h
index fa6c838..6f10933 100644
--- a/Source/core/dom/PseudoElement.h
+++ b/Source/core/dom/PseudoElement.h
@@ -53,6 +53,8 @@
 
     static String pseudoElementNameForEvents(PseudoId);
 
+    void dispose();
+
 private:
     PseudoElement(Element*, PseudoId);
 
diff --git a/Source/core/dom/Range.cpp b/Source/core/dom/Range.cpp
index 74a0ca9..5b2d161 100644
--- a/Source/core/dom/Range.cpp
+++ b/Source/core/dom/Range.cpp
@@ -1035,7 +1035,7 @@
             return;
 
         if (collapsed)
-            m_end.setToBeforeChild(newText.get());
+            m_end.setToBeforeChild(*newText);
     } else {
         RefPtr<Node> lastChild = (newNodeType == Node::DOCUMENT_FRAGMENT_NODE) ? newNode->lastChild() : newNode;
         if (lastChild && lastChild == m_start.childBefore()) {
@@ -1043,7 +1043,7 @@
             // the inserted nodes.
             Node* firstChild = (newNodeType == Node::DOCUMENT_FRAGMENT_NODE) ? newNode->firstChild() : newNode.get();
             ASSERT(firstChild);
-            m_start.setToBeforeChild(firstChild);
+            m_start.setToBeforeChild(*firstChild);
             return;
         }
 
@@ -1694,7 +1694,7 @@
     boundaryNodeChildrenWillBeRemoved(m_end, container);
 }
 
-static inline void boundaryNodeWillBeRemoved(RangeBoundaryPoint& boundary, Node* nodeToBeRemoved)
+static inline void boundaryNodeWillBeRemoved(RangeBoundaryPoint& boundary, Node& nodeToBeRemoved)
 {
     if (boundary.childBefore() == nodeToBeRemoved) {
         boundary.childBeforeWillBeRemoved();
@@ -1709,15 +1709,14 @@
     }
 }
 
-void Range::nodeWillBeRemoved(Node* node)
+void Range::nodeWillBeRemoved(Node& node)
 {
-    ASSERT(node);
-    ASSERT(node->document() == m_ownerDocument);
+    ASSERT(node.document() == m_ownerDocument);
     ASSERT(node != m_ownerDocument);
 
     // FIXME: Once DOMNodeRemovedFromDocument mutation event removed, we
     // should change following if-statement to ASSERT(!node->parentNode).
-    if (!node->parentNode())
+    if (!node.parentNode())
         return;
     boundaryNodeWillBeRemoved(m_start, node);
     boundaryNodeWillBeRemoved(m_end, node);
diff --git a/Source/core/dom/Range.h b/Source/core/dom/Range.h
index 8975552..ab77a96 100644
--- a/Source/core/dom/Range.h
+++ b/Source/core/dom/Range.h
@@ -130,7 +130,7 @@
 
     void nodeChildrenChanged(ContainerNode*);
     void nodeChildrenWillBeRemoved(ContainerNode*);
-    void nodeWillBeRemoved(Node*);
+    void nodeWillBeRemoved(Node&);
 
     void didInsertText(Node*, unsigned offset, unsigned length);
     void didRemoveText(Node*, unsigned offset, unsigned length);
diff --git a/Source/core/dom/RangeBoundaryPoint.h b/Source/core/dom/RangeBoundaryPoint.h
index c1a4625..7574a89 100644
--- a/Source/core/dom/RangeBoundaryPoint.h
+++ b/Source/core/dom/RangeBoundaryPoint.h
@@ -48,7 +48,7 @@
     void set(PassRefPtr<Node> container, int offset, Node* childBefore);
     void setOffset(int offset);
 
-    void setToBeforeChild(Node*);
+    void setToBeforeChild(Node&);
     void setToStartOfNode(PassRefPtr<Node>);
     void setToEndOfNode(PassRefPtr<Node>);
 
@@ -136,12 +136,11 @@
     m_offsetInContainer = offset;
 }
 
-inline void RangeBoundaryPoint::setToBeforeChild(Node* child)
+inline void RangeBoundaryPoint::setToBeforeChild(Node& child)
 {
-    ASSERT(child);
-    ASSERT(child->parentNode());
-    m_childBeforeBoundary = child->previousSibling();
-    m_containerNode = child->parentNode();
+    ASSERT(child.parentNode());
+    m_childBeforeBoundary = child.previousSibling();
+    m_containerNode = child.parentNode();
     m_offsetInContainer = m_childBeforeBoundary ? invalidOffset : 0;
 }
 
diff --git a/Source/core/dom/SelectorQuery.cpp b/Source/core/dom/SelectorQuery.cpp
index 5eeaeee..d1f90af 100644
--- a/Source/core/dom/SelectorQuery.cpp
+++ b/Source/core/dom/SelectorQuery.cpp
@@ -139,27 +139,25 @@
         m_selectors.uncheckedAppend(SelectorData(selector, SelectorCheckerFastPath::canUse(selector)));
 }
 
-inline bool SelectorDataList::selectorMatches(const SelectorData& selectorData, Element* element, const Node* rootNode) const
+inline bool SelectorDataList::selectorMatches(const SelectorData& selectorData, Element& element, const Node& rootNode) const
 {
-    if (selectorData.isFastCheckable && !element->isSVGElement()) {
+    if (selectorData.isFastCheckable && !element.isSVGElement()) {
         SelectorCheckerFastPath selectorCheckerFastPath(selectorData.selector, element);
         if (!selectorCheckerFastPath.matchesRightmostSelector(SelectorChecker::VisitedMatchDisabled))
             return false;
         return selectorCheckerFastPath.matches();
     }
 
-    SelectorChecker selectorChecker(element->document(), SelectorChecker::QueryingRules);
-    SelectorChecker::SelectorCheckingContext selectorCheckingContext(selectorData.selector, element, SelectorChecker::VisitedMatchDisabled);
+    SelectorChecker selectorChecker(element.document(), SelectorChecker::QueryingRules);
+    SelectorChecker::SelectorCheckingContext selectorCheckingContext(selectorData.selector, &element, SelectorChecker::VisitedMatchDisabled);
     selectorCheckingContext.behaviorAtBoundary = SelectorChecker::StaysWithinTreeScope;
-    selectorCheckingContext.scope = !rootNode->isDocumentNode() && rootNode->isContainerNode() ? toContainerNode(rootNode) : 0;
+    selectorCheckingContext.scope = !rootNode.isDocumentNode() && rootNode.isContainerNode() ? &toContainerNode(rootNode) : 0;
     PseudoId ignoreDynamicPseudo = NOPSEUDO;
     return selectorChecker.match(selectorCheckingContext, ignoreDynamicPseudo, DOMSiblingTraversalStrategy()) == SelectorChecker::SelectorMatches;
 }
 
-bool SelectorDataList::matches(Element* targetElement) const
+bool SelectorDataList::matches(Element& targetElement) const
 {
-    ASSERT(targetElement);
-
     unsigned selectorCount = m_selectors.size();
     for (unsigned i = 0; i < selectorCount; ++i) {
         if (selectorMatches(m_selectors[i], targetElement, targetElement))
@@ -169,14 +167,14 @@
     return false;
 }
 
-PassRefPtr<NodeList> SelectorDataList::queryAll(Node* rootNode) const
+PassRefPtr<NodeList> SelectorDataList::queryAll(Node& rootNode) const
 {
     Vector<RefPtr<Node> > result;
     executeQueryAll(rootNode, result);
     return StaticNodeList::adopt(result);
 }
 
-PassRefPtr<Element> SelectorDataList::queryFirst(Node* rootNode) const
+PassRefPtr<Element> SelectorDataList::queryFirst(Node& rootNode) const
 {
     return executeQueryFirst(rootNode);
 }
@@ -187,43 +185,43 @@
     return node->isDocumentNode() || node->isShadowRoot();
 }
 
-void SelectorDataList::collectElementsByClassName(Node* rootNode, const AtomicString& className, Vector<RefPtr<Node> >& traversalRoots) const
+void SelectorDataList::collectElementsByClassName(Node& rootNode, const AtomicString& className, Vector<RefPtr<Node> >& traversalRoots) const
 {
-    for (Element* element = ElementTraversal::firstWithin(rootNode); element; element = ElementTraversal::next(element, rootNode)) {
+    for (Element* element = ElementTraversal::firstWithin(&rootNode); element; element = ElementTraversal::next(element, &rootNode)) {
         if (element->hasClass() && element->classNames().contains(className))
             traversalRoots.append(element);
     }
 }
 
-void SelectorDataList::collectElementsByTagName(Node* rootNode, const QualifiedName& tagName, Vector<RefPtr<Node> >& traversalRoots) const
+void SelectorDataList::collectElementsByTagName(Node& rootNode, const QualifiedName& tagName, Vector<RefPtr<Node> >& traversalRoots) const
 {
-    for (Element* element = ElementTraversal::firstWithin(rootNode); element; element = ElementTraversal::next(element, rootNode)) {
-        if (SelectorChecker::tagMatches(element, tagName))
+    for (Element* element = ElementTraversal::firstWithin(&rootNode); element; element = ElementTraversal::next(element, &rootNode)) {
+        if (SelectorChecker::tagMatches(*element, tagName))
             traversalRoots.append(element);
     }
 }
 
-Element* SelectorDataList::findElementByClassName(Node* rootNode, const AtomicString& className) const
+Element* SelectorDataList::findElementByClassName(Node& rootNode, const AtomicString& className) const
 {
-    for (Element* element = ElementTraversal::firstWithin(rootNode); element; element = ElementTraversal::next(element, rootNode)) {
+    for (Element* element = ElementTraversal::firstWithin(&rootNode); element; element = ElementTraversal::next(element, &rootNode)) {
         if (element->hasClass() && element->classNames().contains(className))
             return element;
     }
     return 0;
 }
 
-Element* SelectorDataList::findElementByTagName(Node* rootNode, const QualifiedName& tagName) const
+Element* SelectorDataList::findElementByTagName(Node& rootNode, const QualifiedName& tagName) const
 {
-    for (Element* element = ElementTraversal::firstWithin(rootNode); element; element = ElementTraversal::next(element, rootNode)) {
-        if (SelectorChecker::tagMatches(element, tagName))
+    for (Element* element = ElementTraversal::firstWithin(&rootNode); element; element = ElementTraversal::next(element, &rootNode)) {
+        if (SelectorChecker::tagMatches(*element, tagName))
             return element;
     }
     return 0;
 }
 
-inline bool SelectorDataList::canUseFastQuery(Node* rootNode) const
+inline bool SelectorDataList::canUseFastQuery(const Node& rootNode) const
 {
-    return m_selectors.size() == 1 && rootNode->inDocument() && !rootNode->document().inQuirksMode();
+    return m_selectors.size() == 1 && rootNode.inDocument() && !rootNode.document().inQuirksMode();
 }
 
 inline bool ancestorHasClassName(Node* rootNode, const AtomicString& className)
@@ -303,11 +301,11 @@
     return adoptPtr(new SingleNodeList(rootNode));
 }
 
-void SelectorDataList::executeSlowQueryAll(Node* rootNode, Vector<RefPtr<Node> >& matchedElements) const
+void SelectorDataList::executeSlowQueryAll(Node& rootNode, Vector<RefPtr<Node> >& matchedElements) const
 {
-    for (Element* element = ElementTraversal::firstWithin(rootNode); element; element = ElementTraversal::next(element, rootNode)) {
+    for (Element* element = ElementTraversal::firstWithin(&rootNode); element; element = ElementTraversal::next(element, &rootNode)) {
         for (unsigned i = 0; i < m_selectors.size(); ++i) {
-            if (selectorMatches(m_selectors[i], element, rootNode)) {
+            if (selectorMatches(m_selectors[i], *element, rootNode)) {
                 matchedElements.append(element);
                 break;
             }
@@ -315,7 +313,7 @@
     }
 }
 
-void SelectorDataList::executeQueryAll(Node* rootNode, Vector<RefPtr<Node> >& matchedElements) const
+void SelectorDataList::executeQueryAll(Node& rootNode, Vector<RefPtr<Node> >& matchedElements) const
 {
     if (!canUseFastQuery(rootNode))
         return executeSlowQueryAll(rootNode, matchedElements);
@@ -330,12 +328,12 @@
         switch (firstSelector->m_match) {
         case CSSSelector::Id:
             {
-                if (rootNode->document().containsMultipleElementsWithId(firstSelector->value()))
+                if (rootNode.document().containsMultipleElementsWithId(firstSelector->value()))
                     break;
 
                 // Just the same as getElementById.
-                Element* element = rootNode->treeScope().getElementById(firstSelector->value());
-                if (element && (isTreeScopeRoot(rootNode) || element->isDescendantOf(rootNode)))
+                Element* element = rootNode.treeScope().getElementById(firstSelector->value());
+                if (element && (isTreeScopeRoot(rootNode) || element->isDescendantOf(&rootNode)))
                     matchedElements.append(element);
                 return;
             }
@@ -349,17 +347,17 @@
     }
 
     bool matchTraverseRoots;
-    OwnPtr<SimpleNodeList> traverseRoots = findTraverseRoots(rootNode, matchTraverseRoots);
+    OwnPtr<SimpleNodeList> traverseRoots = findTraverseRoots(&rootNode, matchTraverseRoots);
     if (traverseRoots->isEmpty())
         return;
 
     const SelectorData& selector = m_selectors[0];
     if (matchTraverseRoots) {
         while (!traverseRoots->isEmpty()) {
-            Node* node = traverseRoots->next();
-            Element* element = toElement(node);
+            Node& node = *traverseRoots->next();
+            Element& element = toElement(node);
             if (selectorMatches(selector, element, rootNode))
-                matchedElements.append(element);
+                matchedElements.append(&element);
         }
         return;
     }
@@ -367,7 +365,7 @@
     while (!traverseRoots->isEmpty()) {
         Node* traverseRoot = traverseRoots->next();
         for (Element* element = ElementTraversal::firstWithin(traverseRoot); element; element = ElementTraversal::next(element, traverseRoot)) {
-            if (selectorMatches(selector, element, rootNode))
+            if (selectorMatches(selector, *element, rootNode))
                 matchedElements.append(element);
         }
     }
@@ -380,31 +378,31 @@
 //
 // The returned Node may be 0, regardless of matchTraverseRoot, if this method finds that the selectors won't
 // match any element.
-Node* SelectorDataList::findTraverseRoot(Node* rootNode, bool& matchTraverseRoot) const
+Node* SelectorDataList::findTraverseRoot(Node& rootNode, bool& matchTraverseRoot) const
 {
     // We need to return the matches in document order. To use id lookup while there is possiblity of multiple matches
     // we would need to sort the results. For now, just traverse the document in that case.
-    ASSERT(rootNode);
     ASSERT(m_selectors.size() == 1);
     ASSERT(m_selectors[0].selector);
 
     bool matchSingleNode = true;
     bool startFromParent = false;
     for (const CSSSelector* selector = m_selectors[0].selector; selector; selector = selector->tagHistory()) {
-        if (selector->m_match == CSSSelector::Id && !rootNode->document().containsMultipleElementsWithId(selector->value())) {
-            Element* element = rootNode->treeScope().getElementById(selector->value());
-            if (element && (isTreeScopeRoot(rootNode) || element->isDescendantOf(rootNode)))
-                rootNode = element;
+        if (selector->m_match == CSSSelector::Id && !rootNode.document().containsMultipleElementsWithId(selector->value())) {
+            Element* element = rootNode.treeScope().getElementById(selector->value());
+            Node* adjustedRootNode = &rootNode;
+            if (element && (isTreeScopeRoot(rootNode) || element->isDescendantOf(&rootNode)))
+                adjustedRootNode = element;
             else if (!element || matchSingleNode)
-                rootNode = 0;
+                adjustedRootNode = 0;
             if (matchSingleNode) {
                 matchTraverseRoot = true;
-                return rootNode;
+                return adjustedRootNode;
             }
-            if (startFromParent && rootNode)
-                rootNode = rootNode->parentNode();
+            if (startFromParent && adjustedRootNode)
+                adjustedRootNode = adjustedRootNode->parentNode();
             matchTraverseRoot = false;
-            return rootNode;
+            return adjustedRootNode;
         }
         if (selector->relation() == CSSSelector::SubSelector)
             continue;
@@ -415,21 +413,21 @@
             startFromParent = false;
     }
     matchTraverseRoot = false;
-    return rootNode;
+    return &rootNode;
 }
 
-Element* SelectorDataList::executeSlowQueryFirst(Node* rootNode) const
+Element* SelectorDataList::executeSlowQueryFirst(Node& rootNode) const
 {
-    for (Element* element = ElementTraversal::firstWithin(rootNode); element; element = ElementTraversal::next(element, rootNode)) {
+    for (Element* element = ElementTraversal::firstWithin(&rootNode); element; element = ElementTraversal::next(element, &rootNode)) {
         for (unsigned i = 0; i < m_selectors.size(); ++i) {
-            if (selectorMatches(m_selectors[i], element, rootNode))
+            if (selectorMatches(m_selectors[i], *element, rootNode))
                 return element;
         }
     }
     return 0;
 }
 
-Element* SelectorDataList::executeQueryFirst(Node* rootNode) const
+Element* SelectorDataList::executeQueryFirst(Node& rootNode) const
 {
     if (!canUseFastQuery(rootNode))
         return executeSlowQueryFirst(rootNode);
@@ -444,10 +442,10 @@
         switch (selector->m_match) {
         case CSSSelector::Id:
             {
-                if (rootNode->document().containsMultipleElementsWithId(selector->value()))
+                if (rootNode.document().containsMultipleElementsWithId(selector->value()))
                     break;
-                Element* element = rootNode->treeScope().getElementById(selector->value());
-                return element && (isTreeScopeRoot(rootNode) || element->isDescendantOf(rootNode)) ? element : 0;
+                Element* element = rootNode.treeScope().getElementById(selector->value());
+                return element && (isTreeScopeRoot(rootNode) || element->isDescendantOf(&rootNode)) ? element : 0;
             }
         case CSSSelector::Class:
             return findElementByClassName(rootNode, selector->value());
@@ -465,12 +463,12 @@
     if (matchTraverseRoot) {
         ASSERT(m_selectors.size() == 1);
         ASSERT(traverseRootNode->isElementNode());
-        Element* element = toElement(traverseRootNode);
-        return selectorMatches(m_selectors[0], element, rootNode) ? element : 0;
+        Element& element = toElement(*traverseRootNode);
+        return selectorMatches(m_selectors[0], element, rootNode) ? &element : 0;
     }
 
     for (Element* element = ElementTraversal::firstWithin(traverseRootNode); element; element = ElementTraversal::next(element, traverseRootNode)) {
-        if (selectorMatches(m_selectors[0], element, rootNode))
+        if (selectorMatches(m_selectors[0], *element, rootNode))
             return element;
     }
     return 0;
@@ -482,17 +480,17 @@
     m_selectors.initialize(m_selectorList);
 }
 
-bool SelectorQuery::matches(Element* element) const
+bool SelectorQuery::matches(Element& element) const
 {
     return m_selectors.matches(element);
 }
 
-PassRefPtr<NodeList> SelectorQuery::queryAll(Node* rootNode) const
+PassRefPtr<NodeList> SelectorQuery::queryAll(Node& rootNode) const
 {
     return m_selectors.queryAll(rootNode);
 }
 
-PassRefPtr<Element> SelectorQuery::queryFirst(Node* rootNode) const
+PassRefPtr<Element> SelectorQuery::queryFirst(Node& rootNode) const
 {
     return m_selectors.queryFirst(rootNode);
 }
diff --git a/Source/core/dom/SelectorQuery.h b/Source/core/dom/SelectorQuery.h
index 2f654c4..bbe607c 100644
--- a/Source/core/dom/SelectorQuery.h
+++ b/Source/core/dom/SelectorQuery.h
@@ -45,9 +45,9 @@
 class SelectorDataList {
 public:
     void initialize(const CSSSelectorList&);
-    bool matches(Element*) const;
-    PassRefPtr<NodeList> queryAll(Node* rootNode) const;
-    PassRefPtr<Element> queryFirst(Node* rootNode) const;
+    bool matches(Element&) const;
+    PassRefPtr<NodeList> queryAll(Node& rootNode) const;
+    PassRefPtr<Element> queryFirst(Node& rootNode) const;
 
 private:
     struct SelectorData {
@@ -56,18 +56,18 @@
         bool isFastCheckable;
     };
 
-    bool canUseFastQuery(Node* rootNode) const;
-    bool selectorMatches(const SelectorData&, Element*, const Node*) const;
-    void collectElementsByClassName(Node* rootNode, const AtomicString& className, Vector<RefPtr<Node> >&) const;
-    Element* findElementByClassName(Node* rootNode, const AtomicString& className) const;
-    void collectElementsByTagName(Node* rootNode, const QualifiedName& tagName, Vector<RefPtr<Node> >&) const;
-    Element* findElementByTagName(Node* rootNode, const QualifiedName& tagName) const;
+    bool canUseFastQuery(const Node& rootNode) const;
+    bool selectorMatches(const SelectorData&, Element&, const Node&) const;
+    void collectElementsByClassName(Node& rootNode, const AtomicString& className, Vector<RefPtr<Node> >&) const;
+    Element* findElementByClassName(Node& rootNode, const AtomicString& className) const;
+    void collectElementsByTagName(Node& rootNode, const QualifiedName& tagName, Vector<RefPtr<Node> >&) const;
+    Element* findElementByTagName(Node& rootNode, const QualifiedName& tagName) const;
     PassOwnPtr<SimpleNodeList> findTraverseRoots(Node* rootNode, bool& matchTraverseRoots) const;
-    void executeSlowQueryAll(Node* rootNode, Vector<RefPtr<Node> >& matchedElements) const;
-    void executeQueryAll(Node* rootNode, Vector<RefPtr<Node> >& matchedElements) const;
-    Node* findTraverseRoot(Node* rootNode, bool& matchTraverseRoot) const;
-    Element* executeSlowQueryFirst(Node* rootNode) const;
-    Element* executeQueryFirst(Node* rootNode) const;
+    void executeSlowQueryAll(Node& rootNode, Vector<RefPtr<Node> >& matchedElements) const;
+    void executeQueryAll(Node& rootNode, Vector<RefPtr<Node> >& matchedElements) const;
+    Node* findTraverseRoot(Node& rootNode, bool& matchTraverseRoot) const;
+    Element* executeSlowQueryFirst(Node& rootNode) const;
+    Element* executeQueryFirst(Node& rootNode) const;
 
     Vector<SelectorData> m_selectors;
 };
@@ -77,9 +77,9 @@
     WTF_MAKE_FAST_ALLOCATED;
 public:
     explicit SelectorQuery(const CSSSelectorList&);
-    bool matches(Element*) const;
-    PassRefPtr<NodeList> queryAll(Node* rootNode) const;
-    PassRefPtr<Element> queryFirst(Node* rootNode) const;
+    bool matches(Element&) const;
+    PassRefPtr<NodeList> queryAll(Node& rootNode) const;
+    PassRefPtr<Element> queryFirst(Node& rootNode) const;
 private:
     SelectorDataList m_selectors;
     CSSSelectorList m_selectorList;
diff --git a/Source/core/dom/StyleSheetScopingNodeList.h b/Source/core/dom/StyleSheetScopingNodeList.h
index 42ebda3..790be13 100644
--- a/Source/core/dom/StyleSheetScopingNodeList.h
+++ b/Source/core/dom/StyleSheetScopingNodeList.h
@@ -39,6 +39,11 @@
     return !node || node->isDocumentNode() || node->isShadowRoot();
 }
 
+inline bool isTreeScopeRoot(const Node& node)
+{
+    return node.isDocumentNode() || node.isShadowRoot();
+}
+
 class StyleSheetScopingNodeList {
     WTF_MAKE_NONCOPYABLE(StyleSheetScopingNodeList); WTF_MAKE_FAST_ALLOCATED;
 public:
diff --git a/Source/core/dom/TreeScope.cpp b/Source/core/dom/TreeScope.cpp
index 8c11f4d..46fe4ca 100644
--- a/Source/core/dom/TreeScope.cpp
+++ b/Source/core/dom/TreeScope.cpp
@@ -230,7 +230,7 @@
     if (!frameView->visibleContentRect().contains(point))
         return 0;
 
-    HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::DisallowShadowContent);
+    HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::ConfusingAndOftenMisusedDisallowShadowContent);
     HitTestResult result(point);
     document->renderView()->hitTest(request, result);
 
diff --git a/Source/core/dom/TreeWalker.idl b/Source/core/dom/TreeWalker.idl
index dd545b8..ac04ba0 100644
--- a/Source/core/dom/TreeWalker.idl
+++ b/Source/core/dom/TreeWalker.idl
@@ -20,7 +20,7 @@
 
 // Introduced in DOM Level 2:
 [
-    CustomToV8
+    SetReference(NodeFilter filter)
 ] interface TreeWalker {
     readonly attribute Node root;
     readonly attribute unsigned long whatToShow;
diff --git a/Source/core/dom/ViewportDescription.h b/Source/core/dom/ViewportDescription.h
index 96cccc0..53eed26 100644
--- a/Source/core/dom/ViewportDescription.h
+++ b/Source/core/dom/ViewportDescription.h
@@ -106,6 +106,7 @@
 
     bool isLegacyViewportType() const { return type >= HandheldFriendlyMeta && type <= ViewportMeta; }
     bool isMetaViewportType() const { return type == ViewportMeta; }
+    bool isSpecifiedByAuthor() const { return type != UserAgentStyleSheet; }
 
 private:
     enum Direction { Horizontal, Vertical };
diff --git a/Source/core/dom/shadow/ComposedTreeWalker.cpp b/Source/core/dom/shadow/ComposedTreeWalker.cpp
index 1e19ddc..b321d06 100644
--- a/Source/core/dom/shadow/ComposedTreeWalker.cpp
+++ b/Source/core/dom/shadow/ComposedTreeWalker.cpp
@@ -31,6 +31,7 @@
 #include "core/dom/Element.h"
 #include "core/dom/shadow/ElementShadow.h"
 #include "core/dom/shadow/InsertionPoint.h"
+#include "core/html/shadow/HTMLShadowElement.h"
 
 namespace WebCore {
 
@@ -41,22 +42,6 @@
     return 0;
 }
 
-static inline bool nodeCanBeDistributed(const Node* node)
-{
-    ASSERT(node);
-    Node* parent = parentNodeForDistribution(node);
-    if (!parent)
-        return false;
-
-    if (ShadowRoot* shadowRoot = parent->isShadowRoot() ? toShadowRoot(parent) : 0)
-        return shadowRoot->insertionPoint();
-
-    if (parent->isElementNode() && toElement(parent)->shadow())
-        return true;
-
-    return false;
-}
-
 Node* ComposedTreeWalker::traverseChild(const Node* node, TraversalDirection direction) const
 {
     ASSERT(node);
@@ -83,7 +68,7 @@
 Node* ComposedTreeWalker::traverseNode(const Node* node, TraversalDirection direction)
 {
     ASSERT(node);
-    if (!isActiveInsertionPoint(node))
+    if (!isActiveInsertionPoint(*node))
         return const_cast<Node*>(node);
     const InsertionPoint* insertionPoint = toInsertionPoint(node);
     if (Node* found = traverseDistributedNodes(direction == TraversalDirectionForward ? insertionPoint->first() : insertionPoint->last(), insertionPoint, direction))
@@ -104,10 +89,10 @@
 {
     ASSERT(node);
 
-    if (!nodeCanBeDistributed(node))
+    if (!shadowWhereNodeCanBeDistributed(*node))
         return traverseSiblingInCurrentTree(node, direction);
 
-    InsertionPoint* insertionPoint = resolveReprojection(node);
+    const InsertionPoint* insertionPoint = resolveReprojection(node);
     if (!insertionPoint)
         return traverseSiblingInCurrentTree(node, direction);
 
@@ -123,7 +108,7 @@
         return found;
     if (Node* next = traverseBackToYoungerShadowRoot(node, direction))
         return next;
-    return escapeFallbackContentElement(node, direction);
+    return 0;
 }
 
 Node* ComposedTreeWalker::traverseBackToYoungerShadowRoot(const Node* node, TraversalDirection direction)
@@ -132,7 +117,7 @@
     if (node->parentNode() && node->parentNode()->isShadowRoot()) {
         ShadowRoot* parentShadowRoot = toShadowRoot(node->parentNode());
         if (!parentShadowRoot->isYoungest()) {
-            InsertionPoint* assignedInsertionPoint = parentShadowRoot->insertionPoint();
+            HTMLShadowElement* assignedInsertionPoint = parentShadowRoot->shadowInsertionPointOfYoungerShadowRoot();
             ASSERT(assignedInsertionPoint);
             return traverseSiblingInCurrentTree(assignedInsertionPoint, direction);
         }
@@ -140,24 +125,6 @@
     return 0;
 }
 
-inline Node* ComposedTreeWalker::escapeFallbackContentElement(const Node* node, TraversalDirection direction)
-{
-    ASSERT(node);
-    if (node->parentNode() && isActiveInsertionPoint(node->parentNode()))
-        return traverseSiblingOrBackToInsertionPoint(node->parentNode(), direction);
-    return 0;
-}
-
-inline Node* ComposedTreeWalker::traverseNodeEscapingFallbackContents(const Node* node, ParentTraversalDetails* details) const
-{
-    ASSERT(node);
-    if (!node->isInsertionPoint())
-        return const_cast<Node*>(node);
-    const InsertionPoint* insertionPoint = toInsertionPoint(node);
-    return insertionPoint->hasDistribution() ? 0 :
-        insertionPoint->isActive() ? traverseParent(node, details) : const_cast<Node*>(node);
-}
-
 // FIXME: Use an iterative algorithm so that it can be inlined.
 // https://bugs.webkit.org/show_bug.cgi?id=90415
 Node* ComposedTreeWalker::traverseParent(const Node* node, ParentTraversalDetails* details) const
@@ -165,16 +132,16 @@
     if (node->isPseudoElement())
         return node->parentOrShadowHostNode();
 
-    if (nodeCanBeDistributed(node)) {
-        if (InsertionPoint* insertionPoint = resolveReprojection(node)) {
+    if (shadowWhereNodeCanBeDistributed(*node)) {
+        if (const InsertionPoint* insertionPoint = resolveReprojection(node)) {
             if (details)
                 details->didTraverseInsertionPoint(insertionPoint);
-            return traverseParent(insertionPoint, details);
+            // The node is distributed. But the distribution was stopped at this insertion point.
+            if (shadowWhereNodeCanBeDistributed(*insertionPoint))
+                return 0;
+            return traverseParentInCurrentTree(insertionPoint, details);
         }
-
-        // The node is a non-distributed light child or older shadow's child.
-        if (details)
-            details->childWasOutOfComposition();
+        return 0;
     }
     return traverseParentInCurrentTree(node, details);
 }
@@ -182,14 +149,14 @@
 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 parent->isShadowRoot() ? traverseParentBackToYoungerShadowRootOrHost(toShadowRoot(parent), details) : parent;
     return 0;
 }
 
 Node* ComposedTreeWalker::traverseParentBackToYoungerShadowRootOrHost(const ShadowRoot* shadowRoot, ParentTraversalDetails* details) const
 {
     ASSERT(shadowRoot);
-    ASSERT(!shadowRoot->insertionPoint());
+    ASSERT(!shadowRoot->shadowInsertionPointOfYoungerShadowRoot());
 
     if (shadowRoot->isYoungest()) {
         if (details)
diff --git a/Source/core/dom/shadow/ComposedTreeWalker.h b/Source/core/dom/shadow/ComposedTreeWalker.h
index 2fb9cf3..2754913 100644
--- a/Source/core/dom/shadow/ComposedTreeWalker.h
+++ b/Source/core/dom/shadow/ComposedTreeWalker.h
@@ -77,7 +77,7 @@
 #ifndef NDEBUG
         ASSERT(m_node);
         ASSERT(!m_node->isShadowRoot());
-        ASSERT(!isActiveInsertionPoint(m_node));
+        ASSERT(!isActiveInsertionPoint(*m_node));
 #endif
     }
 
@@ -106,9 +106,7 @@
     static Node* traverseDistributedNodes(const Node*, const InsertionPoint*, TraversalDirection);
 
     static Node* traverseBackToYoungerShadowRoot(const Node*, TraversalDirection);
-    static Node* escapeFallbackContentElement(const Node*, TraversalDirection);
 
-    Node* traverseNodeEscapingFallbackContents(const Node*, ParentTraversalDetails* = 0) const;
     Node* traverseParentInCurrentTree(const Node*, ParentTraversalDetails* = 0) const;
     Node* traverseParentBackToYoungerShadowRootOrHost(const ShadowRoot*, ParentTraversalDetails* = 0) const;
 
diff --git a/Source/core/dom/shadow/ContentDistribution.cpp b/Source/core/dom/shadow/ContentDistribution.cpp
index e0527ad..a53ff57 100644
--- a/Source/core/dom/shadow/ContentDistribution.cpp
+++ b/Source/core/dom/shadow/ContentDistribution.cpp
@@ -39,7 +39,8 @@
 
 void ContentDistribution::append(PassRefPtr<Node> node)
 {
-    ASSERT(!isActiveInsertionPoint(node.get()));
+    ASSERT(node);
+    ASSERT(!isActiveInsertionPoint(*node));
     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 a75da1b..158addd 100644
--- a/Source/core/dom/shadow/ElementShadow.cpp
+++ b/Source/core/dom/shadow/ElementShadow.cpp
@@ -47,8 +47,8 @@
 private:
     void populateChildren(const ContainerNode*);
     void detachNonDistributedNodes();
-    Vector<Node*> m_nodes;
-    Vector<bool> m_distributed;
+    Vector<Node*, 32> m_nodes;
+    Vector<bool, 32> m_distributed;
 };
 
 inline DistributionPool::DistributionPool(const ContainerNode* parent)
@@ -59,18 +59,11 @@
 
 inline void DistributionPool::populateChildren(const ContainerNode* parent)
 {
-    m_nodes.reserveInitialCapacity(32);
     for (Node* child = parent->firstChild(); child; child = child->nextSibling()) {
-        if (isActiveInsertionPoint(child)) {
+        if (isActiveInsertionPoint(*child)) {
             InsertionPoint* insertionPoint = toInsertionPoint(child);
-            if (insertionPoint->hasDistribution()) {
-                for (size_t i = 0; i < insertionPoint->size(); ++i)
-                    m_nodes.append(insertionPoint->at(i));
-            } else {
-                // Fallback elements.
-                for (Node* fallbackNode = insertionPoint->firstChild(); fallbackNode; fallbackNode = fallbackNode->nextSibling())
-                    m_nodes.append(fallbackNode);
-            }
+            for (size_t i = 0; i < insertionPoint->size(); ++i)
+                m_nodes.append(insertionPoint->at(i));
         } else {
             m_nodes.append(child);
         }
@@ -96,6 +89,13 @@
         m_distributed[i] = true;
     }
 
+    // Distributes fallback elements
+    if (insertionPoint->isContentInsertionPoint() && distribution.isEmpty()) {
+        for (Node* fallbackNode = insertionPoint->firstChild(); fallbackNode; fallbackNode = fallbackNode->nextSibling()) {
+            distribution.append(fallbackNode);
+            elementShadow->didDistributeNode(fallbackNode, insertionPoint);
+        }
+    }
     insertionPoint->setDistribution(distribution);
 }
 
@@ -240,63 +240,70 @@
     return false;
 }
 
-InsertionPoint* ElementShadow::findInsertionPointFor(const Node* key) const
+const InsertionPoint* ElementShadow::finalDestinationInsertionPointFor(const Node* key) const
 {
-    return m_nodeToInsertionPoint.get(key);
+    NodeToDestinationInsertionPoints::const_iterator it = m_nodeToInsertionPoints.find(key);
+    return it == m_nodeToInsertionPoints.end() ? 0: it->value.last().get();
+}
+
+const DestinationInsertionPoints* ElementShadow::destinationInsertionPointsFor(const Node* key) const
+{
+    NodeToDestinationInsertionPoints::const_iterator it = m_nodeToInsertionPoints.find(key);
+    return it == m_nodeToInsertionPoints.end() ? 0: &it->value;
 }
 
 void ElementShadow::distribute()
 {
-    DistributionPool pool(host());
     host()->setNeedsStyleRecalc();
 
-    Vector<HTMLShadowElement*, 32> activeShadowInsertionPoints;
-    for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot()) {
-        HTMLShadowElement* firstActiveShadowInsertionPoint = 0;
+    const ContainerNode* poolContainer = host();
 
+    Vector<HTMLShadowElement*, 32> shadowInsertionPoints;
+    for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot()) {
+        DistributionPool pool(poolContainer);
+
+        HTMLShadowElement* shadowInsertionPoint = 0;
         const Vector<RefPtr<InsertionPoint> >& insertionPoints = root->descendantInsertionPoints();
         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);
+                if (!shadowInsertionPoint)
+                    shadowInsertionPoint = toHTMLShadowElement(point);
             } else {
                 pool.distributeTo(point, this);
-                if (ElementShadow* shadow = shadowOfParentForDistribution(point))
+                if (ElementShadow* shadow = shadowWhereNodeCanBeDistributed(*point))
                     shadow->setNeedsDistributionRecalc();
             }
         }
-
-        if (firstActiveShadowInsertionPoint)
-            activeShadowInsertionPoints.append(firstActiveShadowInsertionPoint);
+        if (shadowInsertionPoint)
+            shadowInsertionPoints.append(shadowInsertionPoint);
+        poolContainer = shadowInsertionPoint;
     }
 
-    for (size_t i = activeShadowInsertionPoints.size(); i > 0; --i) {
-        HTMLShadowElement* shadowElement = activeShadowInsertionPoints[i - 1];
-        ShadowRoot* root = shadowElement->containingShadowRoot();
+    for (size_t i = shadowInsertionPoints.size(); i > 0; --i) {
+        HTMLShadowElement* shadowInsertionPoint = shadowInsertionPoints[i - 1];
+        ShadowRoot* root = shadowInsertionPoint->containingShadowRoot();
         ASSERT(root);
         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()->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.
-            pool.distributeTo(shadowElement, this);
+            distributeNodeChildrenTo(shadowInsertionPoint, root->olderShadowRoot());
+            root->olderShadowRoot()->setShadowInsertionPointOfYoungerShadowRoot(shadowInsertionPoint);
+        } else if (root->isOldest()) {
+            DistributionPool pool(shadowInsertionPoint);
+            pool.distributeTo(shadowInsertionPoint, this);
         }
-        if (ElementShadow* shadow = shadowOfParentForDistribution(shadowElement))
+        if (ElementShadow* shadow = shadowWhereNodeCanBeDistributed(*shadowInsertionPoint))
             shadow->setNeedsDistributionRecalc();
     }
 }
 
 void ElementShadow::didDistributeNode(const Node* node, InsertionPoint* insertionPoint)
 {
-    m_nodeToInsertionPoint.add(node, insertionPoint);
+    NodeToDestinationInsertionPoints::AddResult result = m_nodeToInsertionPoints.add(node, DestinationInsertionPoints());
+    result.iterator->value.append(insertionPoint);
 }
 
 void ElementShadow::distributeNodeChildrenTo(InsertionPoint* insertionPoint, ContainerNode* containerNode)
@@ -353,10 +360,10 @@
 
 void ElementShadow::clearDistribution()
 {
-    m_nodeToInsertionPoint.clear();
+    m_nodeToInsertionPoints.clear();
 
     for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot())
-        root->setInsertionPoint(0);
+        root->setShadowInsertionPointOfYoungerShadowRoot(0);
 }
 
 } // namespace
diff --git a/Source/core/dom/shadow/ElementShadow.h b/Source/core/dom/shadow/ElementShadow.h
index a8e040e..bab1c23 100644
--- a/Source/core/dom/shadow/ElementShadow.h
+++ b/Source/core/dom/shadow/ElementShadow.h
@@ -27,6 +27,7 @@
 #ifndef ElementShadow_h
 #define ElementShadow_h
 
+#include "core/dom/shadow/InsertionPoint.h"
 #include "core/dom/shadow/SelectRuleFeatureSet.h"
 #include "core/dom/shadow/ShadowRoot.h"
 #include "wtf/DoublyLinkedList.h"
@@ -38,8 +39,6 @@
 
 namespace WebCore {
 
-class InsertionPoint;
-
 class ElementShadow {
     WTF_MAKE_NONCOPYABLE(ElementShadow); WTF_MAKE_FAST_ALLOCATED;
 public:
@@ -69,7 +68,8 @@
     void distributeIfNeeded();
     void setNeedsDistributionRecalc();
 
-    InsertionPoint* findInsertionPointFor(const Node*) const;
+    const InsertionPoint* finalDestinationInsertionPointFor(const Node*) const;
+    const DestinationInsertionPoints* destinationInsertionPointsFor(const Node*) const;
 
     void didDistributeNode(const Node*, InsertionPoint*);
 
@@ -81,13 +81,16 @@
 
     void distribute();
     void clearDistribution();
+
     void collectSelectFeatureSetFrom(ShadowRoot*);
     void distributeNodeChildrenTo(InsertionPoint*, ContainerNode*);
 
     bool needsSelectFeatureSet() const { return m_needsSelectFeatureSet; }
     void setNeedsSelectFeatureSet() { m_needsSelectFeatureSet = true; }
 
-    HashMap<const Node*, RefPtr<InsertionPoint> > m_nodeToInsertionPoint;
+    typedef HashMap<const Node*, DestinationInsertionPoints> NodeToDestinationInsertionPoints;
+    NodeToDestinationInsertionPoints m_nodeToInsertionPoints;
+
     SelectRuleFeatureSet m_selectFeatures;
     DoublyLinkedList<ShadowRoot> m_shadowRoots;
     bool m_needsDistributionRecalc;
@@ -124,16 +127,6 @@
     m_needsDistributionRecalc = false;
 }
 
-inline ElementShadow* shadowOfParent(const Node* node)
-{
-    if (!node)
-        return 0;
-    if (Node* parent = node->parentNode())
-        if (parent->isElementNode())
-            return toElement(parent)->shadow();
-    return 0;
-}
-
 } // namespace
 
 #endif
diff --git a/Source/core/dom/shadow/InsertionPoint.cpp b/Source/core/dom/shadow/InsertionPoint.cpp
index 3023d66..a1bb7db 100644
--- a/Source/core/dom/shadow/InsertionPoint.cpp
+++ b/Source/core/dom/shadow/InsertionPoint.cpp
@@ -32,10 +32,13 @@
 #include "core/dom/shadow/InsertionPoint.h"
 
 #include "HTMLNames.h"
+#include "core/dom/ElementTraversal.h"
 #include "core/dom/QualifiedName.h"
 #include "core/dom/StaticNodeList.h"
 #include "core/dom/shadow/ElementShadow.h"
 #include "core/dom/shadow/ShadowRoot.h"
+#include "core/html/shadow/HTMLContentElement.h"
+#include "core/html/shadow/HTMLShadowElement.h"
 
 namespace WebCore {
 
@@ -128,20 +131,53 @@
     return isActive() && !hasDistribution();
 }
 
-bool InsertionPoint::isActive() const
+bool InsertionPoint::canBeActive() const
 {
-    if (!containingShadowRoot())
+    if (!isInShadowTree())
         return false;
-    const Node* node = parentNode();
-    while (node) {
-        if (node->isInsertionPoint())
-            return false;
-
-        node = node->parentNode();
+    bool foundShadowElementInAncestors = false;
+    bool thisIsContentHTMLElement = isHTMLContentElement(this);
+    for (Node* node = parentNode(); node; node = node->parentNode()) {
+        if (node->isInsertionPoint()) {
+            // For HTMLContentElement, at most one HTMLShadowElement may appear in its ancestors.
+            if (thisIsContentHTMLElement && isHTMLShadowElement(node) && !foundShadowElementInAncestors)
+                foundShadowElementInAncestors = true;
+            else
+                return false;
+        }
     }
     return true;
 }
 
+bool InsertionPoint::isActive() const
+{
+    if (!canBeActive())
+        return false;
+    ShadowRoot* shadowRoot = containingShadowRoot();
+    ASSERT(shadowRoot);
+    if (!isHTMLShadowElement(this) || shadowRoot->descendantShadowElementCount() <= 1)
+        return true;
+
+    // Slow path only when there are more than one shadow elements in a shadow tree. That should be a rare case.
+    const Vector<RefPtr<InsertionPoint> >& insertionPoints = shadowRoot->descendantInsertionPoints();
+    for (size_t i = 0; i < insertionPoints.size(); ++i) {
+        InsertionPoint* point = insertionPoints[i].get();
+        if (isHTMLShadowElement(point))
+            return point == this;
+    }
+    return true;
+}
+
+bool InsertionPoint::isShadowInsertionPoint() const
+{
+    return isHTMLShadowElement(this) && isActive();
+}
+
+bool InsertionPoint::isContentInsertionPoint() const
+{
+    return isHTMLContentElement(this) && isActive();
+}
+
 PassRefPtr<NodeList> InsertionPoint::getDistributedNodes()
 {
     document().updateDistributionForNodeIfNeeded(this);
@@ -171,11 +207,10 @@
 Node::InsertionNotificationRequest InsertionPoint::insertedInto(ContainerNode* insertionPoint)
 {
     HTMLElement::insertedInto(insertionPoint);
-
     if (ShadowRoot* root = containingShadowRoot()) {
         if (ElementShadow* rootOwner = root->owner()) {
             rootOwner->setNeedsDistributionRecalc();
-            if (isActive() && !m_registeredWithShadowRoot && insertionPoint->treeScope().rootNode() == root) {
+            if (canBeActive() && !m_registeredWithShadowRoot && insertionPoint->treeScope().rootNode() == root) {
                 m_registeredWithShadowRoot = true;
                 root->didAddInsertionPoint(this);
                 rootOwner->didAffectApplyAuthorStyles();
@@ -239,53 +274,43 @@
     setBooleanAttribute(reset_style_inheritanceAttr, value);
 }
 
-InsertionPoint* resolveReprojection(const Node* projectedNode)
+const InsertionPoint* resolveReprojection(const Node* projectedNode)
 {
-    InsertionPoint* insertionPoint = 0;
+    ASSERT(projectedNode);
+    const InsertionPoint* insertionPoint = 0;
     const Node* current = projectedNode;
-
-    while (current) {
-        if (ElementShadow* shadow = shadowOfParentForDistribution(current)) {
-            if (InsertionPoint* insertedTo = shadow->findInsertionPointFor(projectedNode)) {
-                current = insertedTo;
-                insertionPoint = insertedTo;
-                continue;
-            }
-        }
-
-        if (Node* parent = parentNodeForDistribution(current)) {
-            if (InsertionPoint* insertedTo = parent->isShadowRoot() ? toShadowRoot(parent)->insertionPoint() : 0) {
-                current = insertedTo;
-                insertionPoint = insertedTo;
-                continue;
-            }
-        }
-
-        break;
+    ElementShadow* lastElementShadow = 0;
+    while (true) {
+        ElementShadow* shadow = shadowWhereNodeCanBeDistributed(*current);
+        if (!shadow || shadow == lastElementShadow)
+            break;
+        lastElementShadow = shadow;
+        const InsertionPoint* insertedTo = shadow->finalDestinationInsertionPointFor(projectedNode);
+        if (!insertedTo)
+            break;
+        ASSERT(current != insertedTo);
+        current = insertedTo;
+        insertionPoint = insertedTo;
     }
-
     return insertionPoint;
 }
 
-void collectInsertionPointsWhereNodeIsDistributed(const Node* node, Vector<InsertionPoint*, 8>& results)
+void collectDestinationInsertionPoints(const Node& node, Vector<InsertionPoint*, 8>& results)
 {
-    const Node* current = node;
+    const Node* current = &node;
+    ElementShadow* lastElementShadow = 0;
     while (true) {
-        if (ElementShadow* shadow = shadowOfParentForDistribution(current)) {
-            if (InsertionPoint* insertedTo = shadow->findInsertionPointFor(node)) {
-                current = insertedTo;
-                results.append(insertedTo);
-                continue;
-            }
-        }
-        if (Node* parent = parentNodeForDistribution(current)) {
-            if (InsertionPoint* insertedTo = parent->isShadowRoot() ? toShadowRoot(parent)->insertionPoint() : 0) {
-                current = insertedTo;
-                results.append(insertedTo);
-                continue;
-            }
-        }
-        return;
+        ElementShadow* shadow = shadowWhereNodeCanBeDistributed(*current);
+        if (!shadow || shadow == lastElementShadow)
+            return;
+        lastElementShadow = shadow;
+        const DestinationInsertionPoints* insertionPoints = shadow->destinationInsertionPointsFor(&node);
+        if (!insertionPoints)
+            return;
+        for (size_t i = 0; i < insertionPoints->size(); ++i)
+            results.append(insertionPoints->at(i).get());
+        ASSERT(current != insertionPoints->last().get());
+        current = insertionPoints->last().get();
     }
 }
 
diff --git a/Source/core/dom/shadow/InsertionPoint.h b/Source/core/dom/shadow/InsertionPoint.h
index d12423b..639a52f 100644
--- a/Source/core/dom/shadow/InsertionPoint.h
+++ b/Source/core/dom/shadow/InsertionPoint.h
@@ -33,6 +33,7 @@
 
 #include "core/css/CSSSelectorList.h"
 #include "core/dom/shadow/ContentDistribution.h"
+#include "core/dom/shadow/ShadowRoot.h"
 #include "core/html/HTMLElement.h"
 #include "wtf/Forward.h"
 
@@ -46,6 +47,10 @@
     void setDistribution(ContentDistribution&);
     void clearDistribution() { m_distribution.clear(); }
     bool isActive() const;
+    bool canBeActive() const;
+
+    bool isShadowInsertionPoint() const;
+    bool isContentInsertionPoint() const;
 
     PassRefPtr<NodeList> getDistributedNodes();
 
@@ -76,11 +81,12 @@
     virtual void willRecalcStyle(StyleRecalcChange) OVERRIDE;
 
 private:
-
     ContentDistribution m_distribution;
     bool m_registeredWithShadowRoot;
 };
 
+typedef Vector<RefPtr<InsertionPoint> > DestinationInsertionPoints;
+
 inline InsertionPoint* toInsertionPoint(Node* node)
 {
     ASSERT_WITH_SECURITY_IMPLICATION(!node || node->isInsertionPoint());
@@ -93,46 +99,39 @@
     return static_cast<const InsertionPoint*>(node);
 }
 
-inline bool isActiveInsertionPoint(const Node* node)
+inline const InsertionPoint& toInsertionPoint(const Node& node)
 {
-    return node->isInsertionPoint() && toInsertionPoint(node)->isActive();
+    ASSERT_WITH_SECURITY_IMPLICATION(node.isInsertionPoint());
+    return static_cast<const InsertionPoint&>(node);
 }
 
-inline Node* parentNodeForDistribution(const Node* node)
+inline bool isActiveInsertionPoint(const Node& node)
 {
-    ASSERT(node);
+    return node.isInsertionPoint() && toInsertionPoint(node).isActive();
+}
 
-    if (Node* parent = node->parentNode()) {
-        if (parent->isInsertionPoint() && toInsertionPoint(parent)->shouldUseFallbackElements())
-            return parent->parentNode();
-        return parent;
-    }
+inline bool isActiveShadowInsertionPoint(const Node& node)
+{
+    return node.isInsertionPoint() && toInsertionPoint(node).isShadowInsertionPoint();
+}
 
+inline ElementShadow* shadowWhereNodeCanBeDistributed(const Node& node)
+{
+    Node* parent = node.parentNode();
+    if (!parent)
+        return 0;
+    if (parent->isShadowRoot() && !toShadowRoot(parent)->isYoungest())
+        return node.shadowHost()->shadow();
+    if (isActiveInsertionPoint(*parent))
+        return node.shadowHost()->shadow();
+    if (parent->isElementNode())
+        return toElement(parent)->shadow();
     return 0;
 }
 
-inline Element* parentElementForDistribution(const Node* node)
-{
-    if (Node* parent = parentNodeForDistribution(node)) {
-        if (parent->isElementNode())
-            return toElement(parent);
-    }
+const InsertionPoint* resolveReprojection(const Node*);
 
-    return 0;
-}
-
-inline ElementShadow* shadowOfParentForDistribution(const Node* node)
-{
-    ASSERT(node);
-    if (Element* parent = parentElementForDistribution(node))
-        return parent->shadow();
-
-    return 0;
-}
-
-InsertionPoint* resolveReprojection(const Node*);
-
-void collectInsertionPointsWhereNodeIsDistributed(const Node*, Vector<InsertionPoint*, 8>& results);
+void collectDestinationInsertionPoints(const Node&, Vector<InsertionPoint*, 8>& results);
 
 } // namespace WebCore
 
diff --git a/Source/core/dom/shadow/ShadowRoot.cpp b/Source/core/dom/shadow/ShadowRoot.cpp
index 508585a..95865b8 100644
--- a/Source/core/dom/shadow/ShadowRoot.cpp
+++ b/Source/core/dom/shadow/ShadowRoot.cpp
@@ -294,7 +294,7 @@
 void ShadowRoot::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
 {
     ContainerNode::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
-    if (InsertionPoint* point = insertionPoint()) {
+    if (InsertionPoint* point = shadowInsertionPointOfYoungerShadowRoot()) {
         if (ShadowRoot* root = point->containingShadowRoot())
             root->owner()->setNeedsDistributionRecalc();
     }
@@ -337,16 +337,21 @@
     return m_shadowRootRareData ? m_shadowRootRareData->containsShadowRoots() : 0;
 }
 
-InsertionPoint* ShadowRoot::insertionPoint() const
+unsigned ShadowRoot::descendantShadowElementCount() const
 {
-    return m_shadowRootRareData ? m_shadowRootRareData->insertionPoint() : 0;
+    return m_shadowRootRareData ? m_shadowRootRareData->descendantShadowElementCount() : 0;
 }
 
-void ShadowRoot::setInsertionPoint(PassRefPtr<InsertionPoint> insertionPoint)
+HTMLShadowElement* ShadowRoot::shadowInsertionPointOfYoungerShadowRoot() const
 {
-    if (!m_shadowRootRareData && !insertionPoint)
+    return m_shadowRootRareData ? m_shadowRootRareData->shadowInsertionPointOfYoungerShadowRoot() : 0;
+}
+
+void ShadowRoot::setShadowInsertionPointOfYoungerShadowRoot(PassRefPtr<HTMLShadowElement> shadowInsertionPoint)
+{
+    if (!m_shadowRootRareData && !shadowInsertionPoint)
         return;
-    ensureShadowRootRareData()->setInsertionPoint(insertionPoint);
+    ensureShadowRootRareData()->setShadowInsertionPointOfYoungerShadowRoot(shadowInsertionPoint);
 }
 
 void ShadowRoot::didAddInsertionPoint(InsertionPoint* insertionPoint)
diff --git a/Source/core/dom/shadow/ShadowRoot.h b/Source/core/dom/shadow/ShadowRoot.h
index 84ad90b..876dcbf 100644
--- a/Source/core/dom/shadow/ShadowRoot.h
+++ b/Source/core/dom/shadow/ShadowRoot.h
@@ -38,6 +38,7 @@
 
 class ElementShadow;
 class ExceptionState;
+class HTMLShadowElement;
 class InsertionPoint;
 class ShadowRootRareData;
 
@@ -85,11 +86,13 @@
     bool containsInsertionPoints() const { return containsShadowElements() || containsContentElements(); }
     bool containsShadowRoots() const;
 
+    unsigned descendantShadowElementCount() const;
+
     // For Internals, don't use this.
     unsigned childShadowRootCount() const;
 
-    InsertionPoint* insertionPoint() const;
-    void setInsertionPoint(PassRefPtr<InsertionPoint>);
+    HTMLShadowElement* shadowInsertionPointOfYoungerShadowRoot() const;
+    void setShadowInsertionPointOfYoungerShadowRoot(PassRefPtr<HTMLShadowElement>);
 
     void didAddInsertionPoint(InsertionPoint*);
     void didRemoveInsertionPoint(InsertionPoint*);
diff --git a/Source/core/dom/shadow/ShadowRootRareData.h b/Source/core/dom/shadow/ShadowRootRareData.h
index 6ed6376..dae72a7 100644
--- a/Source/core/dom/shadow/ShadowRootRareData.h
+++ b/Source/core/dom/shadow/ShadowRootRareData.h
@@ -48,8 +48,8 @@
     {
     }
 
-    InsertionPoint* insertionPoint() const { return m_insertionPoint.get(); }
-    void setInsertionPoint(PassRefPtr<InsertionPoint> insertionPoint) { m_insertionPoint = insertionPoint; }
+    HTMLShadowElement* shadowInsertionPointOfYoungerShadowRoot() const { return m_shadowInsertionPointOfYoungerShadowRoot.get(); }
+    void setShadowInsertionPointOfYoungerShadowRoot(PassRefPtr<HTMLShadowElement> shadowInsertionPoint) { m_shadowInsertionPointOfYoungerShadowRoot = shadowInsertionPoint; }
 
     void didAddInsertionPoint(InsertionPoint*);
     void didRemoveInsertionPoint(InsertionPoint*);
@@ -58,6 +58,8 @@
     bool containsContentElements() const { return m_descendantContentElementCount; }
     bool containsShadowRoots() const { return m_childShadowRootCount; }
 
+    unsigned descendantShadowElementCount() const { return m_descendantShadowElementCount; }
+
     void didAddChildShadowRoot() { ++m_childShadowRootCount; }
     void didRemoveChildShadowRoot() { ASSERT(m_childShadowRootCount > 0); --m_childShadowRootCount; }
 
@@ -71,7 +73,7 @@
     void setStyleSheets(PassRefPtr<StyleSheetList> styleSheetList) { m_styleSheetList = styleSheetList; }
 
 private:
-    RefPtr<InsertionPoint> m_insertionPoint;
+    RefPtr<HTMLShadowElement> m_shadowInsertionPointOfYoungerShadowRoot;
     unsigned m_descendantShadowElementCount;
     unsigned m_descendantContentElementCount;
     unsigned m_childShadowRootCount;