bool QScriptValueIteratorImpl::hasPrevious()
{
    if (m_foundMember.isValid() && !m_foundForward) {
        // we have the information about the previous element already
        return true;
    }

    QScriptValueImpl obj = m_object;

    if (m_searchClassDataIterator) {
        Q_ASSERT(m_classDataIterator != 0);
        if (m_foundMember.isValid()) {
            // undo effect of hasNext()
            m_foundMember.invalidate();
            QScript::Member dummy;
            m_classDataIterator->previous(&dummy);
        }
        while (m_classDataIterator->hasPrevious()) {
            QScript::Member m;
            m_classDataIterator->previous(&m);
            if (acceptsMember(obj, m)) {
                m_foundObject = obj;
                m_foundMember = m;
                m_foundForward = false;
                return true;
            }
        }
        m_searchClassDataIterator = false;
        m_searchIndex = obj.memberCount();
        m_foundMember.invalidate();
    }

    // search object members
    int i = m_searchIndex - 1;
    if (m_foundMember.isValid()) {
        // undo effect of hasPrevious()
        m_foundMember.invalidate();
        --i;
    }
    for ( ; i >= 0; --i) {
        QScript::Member m;
        obj.member(i, &m);
        if (acceptsMember(obj, m)) {
            m_foundObject = obj;
            m_foundMember = m;
            m_foundForward = false;
            m_searchIndex = i;
            return true;
        }
    }

    return false;
}
/*!
  Returns true if there is at least one item ahead of the iterator
  (i.e. the iterator is \e not at the back of the property sequence);
  otherwise returns false.

  \sa next(), hasPrevious()
*/
bool QScriptValueIterator::hasNext() const
{
    Q_D(const QScriptValueIterator);
    if ((d->nextIndex != -1) && d->forward)
        return true;

    if (!d->object.isObject())
        return false;

    QScriptValueImpl v = QScriptValuePrivate::valueOf(d->object);
    int i = d->index;
    if ((i != -1) && !d->forward)
        --i;

    int count = v.memberCount();
    bool found = false;
    while (! found && ++i < count) {
        QScript::Member member;
        v.member(i, &member);
        found = member.isValid();
        if (found && (member.isObjectProperty() || v.isArray())) {
            QScriptValueImpl vv;
            v.get(member, &vv);
            found = vv.isValid();
        }
    }

    QScriptValueIteratorPrivate *that;
    that = const_cast<QScriptValueIteratorPrivate*>(d);
    if (found) {
        that->forward = true;
        that->nextIndex = i;
        return true;
    } else {
        that->nextIndex = -1;
        return false;
    }
}
bool QScriptValueIteratorImpl::hasNext()
{
    if (m_foundMember.isValid() && m_foundForward) {
        // we have the information about the next element already
        return true;
    }

    int idx, count;
    QScriptValueImpl obj = m_object;

    if (m_searchClassDataIterator) {
        Q_ASSERT(m_classDataIterator != 0);
        if (m_foundMember.isValid()) {
            // undo effect of hasPrevious()
            m_foundMember.invalidate();
            QScript::Member dummy;
            m_classDataIterator->next(&dummy);
        }
        goto LSearchClassData;
    }

    idx = m_searchIndex;
    if (m_foundMember.isValid()) {
        // undo effect of hasPrevious()
        m_foundMember.invalidate();
        ++idx;
    }

 LSearchObjectData:
    count = obj.memberCount();
    for (int i = idx; i < count; ++i) {
        QScript::Member m;
        obj.member(i, &m);
        if (acceptsMember(obj, m)) {
            m_foundObject = obj;
            m_foundMember = m;
            m_foundForward = true;
            m_searchIndex = i + 1;
            return true;
        }
    }

    if (!m_classDataIterator) {
        QScriptClassData *data = obj.classInfo()->data();
        if (!data)
            goto LNext;
        m_classDataIterator = data->newIterator(obj);
        if (!m_classDataIterator)
            goto LNext;
    }
    m_searchClassDataIterator = true;

 LSearchClassData:
    Q_ASSERT(m_classDataIterator != 0);
    while (m_classDataIterator->hasNext()) {
        QScript::Member m;
        m_classDataIterator->next(&m);
        if (acceptsMember(obj, m)) {
            m_foundObject = obj;
            m_foundMember = m;
            m_foundForward = true;
            return true;
        }
    }

 LNext:
    if (!m_enumerateProto || !obj.prototype().isObject())
        return false;

    // look in prototype
    obj = obj.prototype();
    idx = 0;
    if (m_classDataIterator) {
        delete m_classDataIterator;
        m_classDataIterator = 0;
        m_searchClassDataIterator = false;
    }
    goto LSearchObjectData;
}