Position Position::trailingWhitespacePosition(EAffinity affinity, bool considerNonCollapsibleWhitespace) const
{
    if (isNull())
        return Position();

    if (node()->isTextNode()) {
        TextImpl *textNode = static_cast<TextImpl *>(node());
        if (offset() < (long)textNode->length()) {
            DOMString string = static_cast<TextImpl *>(node())->data();
            const QChar &c = string[offset()];
            if (considerNonCollapsibleWhitespace ? (c.isSpace() || c.unicode() == 0xa0) : isCollapsibleWhitespace(c))
                return *this;
            return Position();
        }
    }

    if (downstream(StayInBlock).node()->id() == ID_BR)
        return Position();

    Position next = nextCharacterPosition(affinity);
    if (next != *this && next.node()->inSameContainingBlockFlowElement(node()) && next.node()->isTextNode()) {
        DOMString string = static_cast<TextImpl *>(next.node())->data();
        const QChar &c = string[0];
        if (considerNonCollapsibleWhitespace ? (c.isSpace() || c.unicode() == 0xa0) : isCollapsibleWhitespace(c))
            return next;
    }

    return Position();
}
QChar VisiblePosition::character() const
{
    Position pos = position();
    NodeImpl *node = pos.node();
    if (!node || !node->isTextNode()) {
        return QChar();
    }
    TextImpl *textNode = static_cast<TextImpl *>(pos.node());
    long offset = pos.offset();
    if ((unsigned)offset >= textNode->length()) {
        return QChar();
    }
    return textNode->data()[offset];
}