Node* FlatTreeTraversal::lastWithin(const Node& node)
{
    assertPrecondition(node);
    Node* descendant = traverseLastChild(node);
    for (Node* child = descendant; child; child = lastChild(*child))
        descendant = child;
    assertPostcondition(descendant);
    return descendant;
}
Node* previousInScope(const Node* node)
{
    ASSERT(!isActiveInsertionPoint(node));

    if (Node* current = traversePreviousSibling(node)) {
        while (Node* child = traverseLastChild(current, DontCrossShadowRoot))
            current = child;
        return current;
    }
    return traverseParent(node, DontCrossShadowRoot);
}
void ComposedShadowTreeWalker::previous()
{
    assertPrecondition();
    if (Node* n = traversePreviousSibling(m_node)) {
        while (Node* child = traverseLastChild(n))
            n = child;
        m_node = n;
    } else
        parent();
    assertPostcondition();
}
// TODO(yosin) We should consider introducing template class to share code
// between DOM tree traversal and flat tree tarversal.
Node* FlatTreeTraversal::previousPostOrder(const Node& current, const Node* stayWithin)
{
    assertPrecondition(current);
    if (stayWithin)
        assertPrecondition(*stayWithin);
    if (Node* lastChild = traverseLastChild(current)) {
        assertPostcondition(lastChild);
        return lastChild;
    }
    if (current == stayWithin)
        return nullptr;
    if (Node* previousSibling = traversePreviousSibling(current)) {
        assertPostcondition(previousSibling);
        return previousSibling;
    }
    return previousAncestorSiblingPostOrder(current, stayWithin);
}
Node* previousSiblingSlow(const Node* node)
{
    ASSERT(!node->isShadowRoot());

    Node* previousSibling = 0;
    if (node->isAfterPseudoElement()) {
        ContainerNode* parent = traverseParent(node, CrossShadowRoot);
        previousSibling = traverseLastChild(parent, CrossShadowRoot);
    } else
        previousSibling = traversePreviousSibling(node);

    if (previousSibling || node->isBeforePseudoElement())
        return previousSibling;

    ContainerNode* parent = traverseParent(node, CrossShadowRoot);
    if (parent && parent->isElementNode())
        return toElement(parent)->beforePseudoElement();

    return 0;
}
Node* lastChildInScope(const Node* node)
{
    ASSERT(!isActiveInsertionPoint(node));

    return traverseLastChild(node, DontCrossShadowRoot);
}
void ComposedShadowTreeWalker::lastChild()
{
    assertPrecondition();
    m_node = traverseLastChild(m_node);
    assertPostcondition();
}