/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtScxml module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qscxmlstatemachine_p.h"
#include "qscxmlexecutablecontent_p.h"
#include "qscxmlevent_p.h"
#include "qscxmlinvokableservice.h"
#include "qscxmldatamodel_p.h"

#include <qfile.h>
#include <qhash.h>
#include <qloggingcategory.h>
#include <qstring.h>
#include <qtimer.h>
#include <qthread.h>

#include <functional>

QT_BEGIN_NAMESPACE

Q_LOGGING_CATEGORY(qscxmlLog, "qt.scxml.statemachine")
Q_LOGGING_CATEGORY(scxmlLog, "scxml.statemachine")

/*!
 * \class QScxmlStateMachine
 * \brief The QScxmlStateMachine class provides an interface to the state machines
 * created from SCXML files.
 * \since 5.7
 * \inmodule QtScxml
 *
 * QScxmlStateMachine is an implementation of the
 * \l{SCXML Specification}{State Chart XML (SCXML)}.
 *
 * All states that are defined in the SCXML file
 * are accessible as properties of QScxmlStateMachine.
 * These properties are boolean values and indicate
 * whether the state is active or inactive.
 *
 * \note The QScxmlStateMachine needs a QEventLoop to work correctly. The event loop is used to
 *       implement the \c delay attribute for events and to schedule the processing of a state
 *       machine when events are received from nested (or parent) state machines.
 */

/*!
    \qmltype ScxmlStateMachine
    \instantiates QScxmlStateMachine
    \inqmlmodule QtScxml
    \since 5.7

    \brief Provides an interface to the state machines created from SCXML files.

    The ScxmlStateMachine type is an implementation of the
    \l{SCXML Specification}{State Chart XML (SCXML)}.

    All states that are defined in the SCXML file are accessible as properties
    of this type. These properties are boolean values and indicate whether the
    state is active or inactive.
*/

/*!
    \fn template<typename PointerToMemberFunction> QMetaObject::Connection QScxmlStateMachine::connectToEvent(
                                           const QString &scxmlEventSpec,
                                           const typename QtPrivate::FunctionPointer<PointerToMemberFunction>::Object *receiver,
                                           PointerToMemberFunction method,
                                           Qt::ConnectionType type)

    Creates a connection of the given \a type from the event specified by
    \a scxmlEventSpec to \a method in the \a receiver object.

    The receiver's \a method must take a QScxmlEvent as a parameter.

    In contrast to event specifications in SCXML documents, spaces are not
    allowed in the \a scxmlEventSpec here. In order to connect to multiple
    events with different prefixes, connectToEvent() has to be called multiple
    times.

    Returns a handle to the connection, which can be used later to disconnect.
*/

/*!
    \fn template<typename Functor> typename QtPrivate::QEnableIf<!QtPrivate::FunctionPointer<Functor>::IsPointerToMemberFunction && !std::is_same<const char*, Functor>::value, QMetaObject::Connection>::Type QScxmlStateMachine::connectToEvent(
                                           const QString &scxmlEventSpec,
                                           Functor functor,
                                           Qt::ConnectionType type)

    Creates a connection of the given \a type from the event specified by
    \a scxmlEventSpec to \a functor.

    The \a functor must take a QScxmlEvent as a parameter.

    In contrast to event specifications in SCXML documents, spaces are not
    allowed in the \a scxmlEventSpec here. In order to connect to multiple
    events with different prefixes, connectToEvent() has to be called multiple
    times.

    Returns a handle to the connection, which can be used later to disconnect.
*/

/*!
    \fn template<typename Functor> typename QtPrivate::QEnableIf<!QtPrivate::FunctionPointer<Functor>::IsPointerToMemberFunction && !std::is_same<const char*, Functor>::value, QMetaObject::Connection>::Type QScxmlStateMachine::connectToEvent(
                                           const QString &scxmlEventSpec,
                                           const QObject *context,
                                           Functor functor,
                                           Qt::ConnectionType type)

    Creates a connection of the given \a type from the event specified by
    \a scxmlEventSpec to \a functor using \a context as context.

    The \a functor must take a QScxmlEvent as a parameter.

    In contrast to event specifications in SCXML documents, spaces are not
    allowed in the \a scxmlEventSpec here. In order to connect to multiple
    events with different prefixes, connectToEvent() has to be called multiple
    times.

    Returns a handle to the connection, which can be used later to disconnect.
*/

/*!
    \fn template<typename PointerToMemberFunction> QMetaObject::Connection QScxmlStateMachine::connectToState(
                                           const QString &scxmlStateName,
                                           const typename QtPrivate::FunctionPointer<PointerToMemberFunction>::Object *receiver,
                                           PointerToMemberFunction method,
                                           Qt::ConnectionType type)

    Creates a connection of the given \a type from the state specified by
    \a scxmlStateName to \a method in the \a receiver object.

    The receiver's \a method must take a boolean argument that indicates
    whether the state connected became active or inactive.

    Returns a handle to the connection, which can be used later to disconnect.
*/

/*!
    \fn template<typename Functor> typename QtPrivate::QEnableIf<!QtPrivate::FunctionPointer<Functor>::IsPointerToMemberFunction && !std::is_same<const char*, Functor>::value, QMetaObject::Connection>::Type QScxmlStateMachine::connectToState(
                                           const QString &scxmlStateName,
                                           Functor functor,
                                           Qt::ConnectionType type)

    Creates a connection of the given \a type from the state specified by
    \a scxmlStateName to \a functor.

    The \a functor must take a boolean argument that indicates whether the
    state connected became active or inactive.

    Returns a handle to the connection, which can be used later to disconnect.
*/

/*!
    \fn template<typename Functor> typename QtPrivate::QEnableIf<!QtPrivate::FunctionPointer<Functor>::IsPointerToMemberFunction && !std::is_same<const char*, Functor>::value, QMetaObject::Connection>::Type QScxmlStateMachine::connectToState(
                                           const QString &scxmlStateName,
                                           const QObject *context,
                                           Functor functor,
                                           Qt::ConnectionType type)

    Creates a connection of the given \a type from the state specified by
    \a scxmlStateName to \a functor using \a context as context.

    The \a functor must take a boolean argument that indicates whether the
    state connected became active or inactive.

    Returns a handle to the connection, which can be used later to disconnect.
*/

/*!
    \fn std::function<void(bool)> QScxmlStateMachine::onEntry(
            const QObject *receiver, const char *method)

    Returns a functor that accepts a boolean argument and calls the given
    \a method on \a receiver using QMetaObject::invokeMethod() if that argument
    is \c true and \a receiver has not been deleted, yet.

    The given \a method must not accept any arguments. \a method is the plain
    method name, not enclosed in \c SIGNAL() or \c SLOT().

    This is useful to wrap handlers for connectToState() that should only
    be executed when the state is entered.
 */

/*!
    \fn std::function<void(bool)> QScxmlStateMachine::onExit(
            const QObject *receiver, const char *method)

    Returns a functor that accepts a boolean argument and calls the given
    \a method on \a receiver using QMetaObject::invokeMethod() if that argument
    is \c false and \a receiver has not been deleted, yet.

    The given \a method must not accept any arguments. \a method is the plain
    method name, not enclosed in SIGNAL(...) or SLOT(...).

    This is useful to wrap handlers for connectToState() that should only
    be executed when the state is left.
 */

/*!
    \fn template<typename Functor> std::function<void(bool)> QScxmlStateMachine::onEntry(
            Functor functor)

    Returns a functor that accepts a boolean argument and calls the given
    \a functor if that argument is \c true. The given \a functor must not
    accept any arguments.

    This is useful to wrap handlers for connectToState() that should only
    be executed when the state is entered.
 */

/*!
    \fn template<typename Functor> std::function<void(bool)> QScxmlStateMachine::onExit(Functor functor)

    Returns a functor that accepts a boolean argument and calls the given
    \a functor if that argument is \c false. The given \a functor must not
    accept any arguments.

    This is useful to wrap handlers for connectToState() that should only
    be executed when the state is left.
 */

/*!
    \fn template<typename PointerToMemberFunction> std::function<void(bool)> QScxmlStateMachine::onEntry(
            const typename QtPrivate::FunctionPointer<PointerToMemberFunction>::Object *receiver,
            PointerToMemberFunction method)

    Returns a functor that accepts a boolean argument and calls the given
    \a method on \a receiver if that argument is \c true and the \a receiver
    has not been deleted, yet. The given \a method must not accept any
    arguments.

    This is useful to wrap handlers for connectToState() that should only
    be executed when the state is entered.
 */

/*!
    \fn template<typename PointerToMemberFunction> std::function<void(bool)> QScxmlStateMachine::onExit(
            const typename QtPrivate::FunctionPointer<PointerToMemberFunction>::Object *receiver,
            PointerToMemberFunction method)

    Returns a functor that accepts a boolean argument and calls the given
    \a method on \a receiver if that argument is \c false and the \a receiver
    has not been deleted, yet. The given \a method must not accept any
    arguments.

    This is useful to wrap handlers for connectToState() that should only
    be executed when the state is left.
 */

namespace QScxmlInternal {

static int signalIndex(const QMetaObject *meta, const QByteArray &signalName)
{
    Q_ASSERT(meta);

    int signalIndex = meta->indexOfSignal(signalName.constData());

    // If signal doesn't exist, return negative value
    if (signalIndex < 0)
        return signalIndex;

    // signal belongs to class whose meta object was passed, not some derived class.
    Q_ASSERT(meta->methodOffset() <= signalIndex);

    // Duplicate of computeOffsets in qobject.cpp
    const QMetaObject *m = meta->d.superdata;
    while (m) {
        const QMetaObjectPrivate *d = QMetaObjectPrivate::get(m);
        signalIndex = signalIndex - d->methodCount + d->signalCount;
        m = m->d.superdata;
    }

    // Asserting about the signal not being cloned would be nice, too, but not practical.

    return signalIndex;
}

void EventLoopHook::queueProcessEvents()
{
    if (smp->m_isProcessingEvents)
        return;

    QMetaObject::invokeMethod(this, "doProcessEvents", Qt::QueuedConnection);
}

void EventLoopHook::doProcessEvents()
{
    smp->processEvents();
}

void EventLoopHook::timerEvent(QTimerEvent *timerEvent)
{
    const int timerId = timerEvent->timerId();
    for (auto it = smp->m_delayedEvents.begin(), eit = smp->m_delayedEvents.end(); it != eit; ++it) {
        if (it->first == timerId) {
            QScxmlEvent *scxmlEvent = it->second;
            smp->m_delayedEvents.erase(it);
            smp->routeEvent(scxmlEvent);
            killTimer(timerId);
            return;
        }
    }
}

void ScxmlEventRouter::route(const QStringList &segments, QScxmlEvent *event)
{
    emit eventOccurred(*event);
    if (!segments.isEmpty()) {
        auto it = children.find(segments.first());
        if (it != children.end())
            it.value()->route(segments.mid(1), event);
    }
}

static QString nextSegment(const QStringList &segments)
{
    if (segments.isEmpty())
        return QString();

    const QString &segment = segments.first();
    return segment == QLatin1String("*") ? QString() : segment;
}

ScxmlEventRouter *ScxmlEventRouter::child(const QString &segment)
{
    ScxmlEventRouter *&child = children[segment];
    if (child == nullptr)
        child = new ScxmlEventRouter(this);
    return child;
}

void ScxmlEventRouter::disconnectNotify(const QMetaMethod &signal)
{
    Q_UNUSED(signal);

    // Defer the actual work, as this may be called from a destructor, or the signal may not
    // actually be disconnected, yet.
    QTimer::singleShot(0, this, [this] {
        if (!children.isEmpty() || receivers(SIGNAL(eventOccurred(QScxmlEvent))) > 0)
            return;

        ScxmlEventRouter *parentRouter = qobject_cast<ScxmlEventRouter *>(parent());
        if (!parentRouter) // root node
            return;

        QHash<QString, ScxmlEventRouter *>::Iterator it = parentRouter->children.begin(),
                end = parentRouter->children.end();
        for (; it != end; ++it) {
            if (it.value() == this) {
                parentRouter->children.erase(it);
                parentRouter->disconnectNotify(QMetaMethod());
                break;
            }
        }

        deleteLater(); // The parent might delete itself, triggering QObject delete cascades.
    });
}

QMetaObject::Connection ScxmlEventRouter::connectToEvent(const QStringList &segments,
                                                         const QObject *receiver,
                                                         const char *method,
                                                         Qt::ConnectionType type)
{
    QString segment = nextSegment(segments);
    return segment.isEmpty() ?
                connect(this, SIGNAL(eventOccurred(QScxmlEvent)), receiver, method, type) :
                child(segment)->connectToEvent(segments.mid(1), receiver, method, type);
}

QMetaObject::Connection ScxmlEventRouter::connectToEvent(const QStringList &segments,
                                                         const QObject *receiver, void **slot,
                                                         QtPrivate::QSlotObjectBase *method,
                                                         Qt::ConnectionType type)
{
    QString segment = nextSegment(segments);
    if (segment.isEmpty()) {
        const int *types = nullptr;
        if (type == Qt::QueuedConnection || type == Qt::BlockingQueuedConnection)
            types = QtPrivate::ConnectionTypes<QtPrivate::List<QScxmlEvent> >::types();

        const QMetaObject *meta = metaObject();
        static const int eventOccurredIndex = signalIndex(meta, "eventOccurred(QScxmlEvent)");
        return QObjectPrivate::connectImpl(this, eventOccurredIndex, receiver, slot, method, type,
                                           types, meta);
    } else {
        return child(segment)->connectToEvent(segments.mid(1), receiver, slot, method, type);
    }
}

} // namespace QScxmlInternal

QAtomicInt QScxmlStateMachinePrivate::m_sessionIdCounter = QAtomicInt(0);

QScxmlStateMachinePrivate::QScxmlStateMachinePrivate(const QMetaObject *metaObject)
    : QObjectPrivate()
    , m_sessionId(QScxmlStateMachinePrivate::generateSessionId(QStringLiteral("session-")))
    , m_isInvoked(false)
    , m_isInitialized(false)
    , m_isProcessingEvents(false)
    , m_dataModel(nullptr)
    , m_loader(&m_defaultLoader)
    , m_executionEngine(nullptr)
    , m_tableData(nullptr)
    , m_parentStateMachine(nullptr)
    , m_eventLoopHook(this)
    , m_metaObject(metaObject)
    , m_infoSignalProxy(nullptr)
{
    static int metaType = qRegisterMetaType<QScxmlStateMachine *>();
    Q_UNUSED(metaType);
}

QScxmlStateMachinePrivate::~QScxmlStateMachinePrivate()
{
    for (const InvokedService &invokedService : m_invokedServices)
        delete invokedService.service;
    qDeleteAll(m_cachedFactories);
    delete m_executionEngine;
}

QScxmlStateMachinePrivate::ParserData *QScxmlStateMachinePrivate::parserData()
{
    if (m_parserData.isNull())
        m_parserData.reset(new ParserData);
    return m_parserData.data();
}

void QScxmlStateMachinePrivate::addService(int invokingState)
{
    Q_Q(QScxmlStateMachine);

    const int arrayId = m_stateTable->state(invokingState).serviceFactoryIds;
    if (arrayId == StateTable::InvalidIndex)
        return;

    const auto &ids = m_stateTable->array(arrayId);
    for (int id : ids) {
        auto factory = serviceFactory(id);
        auto service = factory->invoke(q);
        if (service == nullptr)
            continue; // service failed to start
        const QString serviceName = service->name();
        m_invokedServices[size_t(id)] = { invokingState, service, serviceName };
        service->start();
    }
    emitInvokedServicesChanged();
}

void QScxmlStateMachinePrivate::removeService(int invokingState)
{
    const int arrayId = m_stateTable->state(invokingState).serviceFactoryIds;
    if (arrayId == StateTable::InvalidIndex)
        return;

    for (size_t i = 0, ei = m_invokedServices.size(); i != ei; ++i) {
        auto &it = m_invokedServices[i];
        QScxmlInvokableService *service = it.service;
        if (it.invokingState == invokingState && service != nullptr) {
            it.service = nullptr;
            delete service;
        }
    }
    emitInvokedServicesChanged();
}

QScxmlInvokableServiceFactory *QScxmlStateMachinePrivate::serviceFactory(int id)
{
    Q_ASSERT(id <= m_stateTable->maxServiceId && id >= 0);
    QScxmlInvokableServiceFactory *& factory = m_cachedFactories[size_t(id)];
    if (factory == nullptr)
        factory = m_tableData->serviceFactory(id);
    return factory;
}

bool QScxmlStateMachinePrivate::executeInitialSetup()
{
    return m_executionEngine->execute(m_tableData->initialSetup());
}

void QScxmlStateMachinePrivate::routeEvent(QScxmlEvent *event)
{
    Q_Q(QScxmlStateMachine);

    if (!event)
        return;

    QString origin = event->origin();
    if (origin == QStringLiteral("#_parent")) {
        if (auto psm = m_parentStateMachine) {
            qCDebug(qscxmlLog) << q << "routing event" << event->name() << "from" << q->name() << "to parent" << psm->name();
                                 QScxmlStateMachinePrivate::get(psm)->postEvent(event);
        } else {
            qCDebug(qscxmlLog) << this << "is not invoked, so it cannot route a message to #_parent";
            delete event;
        }
    } else if (origin.startsWith(QStringLiteral("#_")) && origin != QStringLiteral("#_internal")) {
        // route to children
        auto originId = origin.midRef(2);
        for (const auto &invokedService : m_invokedServices) {
            auto service = invokedService.service;
            if (service == nullptr)
                continue;
            if (service->id() == originId) {
                qCDebug(qscxmlLog) << q << "routing event" << event->name()
                                   << "from" << q->name()
                                   << "to child" << service->id();
                service->postEvent(new QScxmlEvent(*event));
            }
        }
        delete event;
    } else {
        postEvent(event);
    }
}

void QScxmlStateMachinePrivate::postEvent(QScxmlEvent *event)
{
    Q_Q(QScxmlStateMachine);

    if (!event->name().startsWith(QStringLiteral("done.invoke."))) {
        for (int id = 0, end = static_cast<int>(m_invokedServices.size()); id != end; ++id) {
            auto service = m_invokedServices[id].service;
            if (service == nullptr)
                continue;
            auto factory = serviceFactory(id);
            if (event->invokeId() == service->id()) {
                setEvent(event);

                const QScxmlExecutableContent::ContainerId finalize
                        = factory->invokeInfo().finalize;
                if (finalize != QScxmlExecutableContent::NoContainer) {
                    auto psm = service->parentStateMachine();
                    qCDebug(qscxmlLog) << psm << "running finalize on event";
                    auto smp = QScxmlStateMachinePrivate::get(psm);
                    smp->m_executionEngine->execute(finalize);
                }

                resetEvent();
            }
            if (factory->invokeInfo().autoforward) {
                qCDebug(qscxmlLog) << q << "auto-forwarding event" << event->name()
                                   << "from" << q->name()
                                   << "to child" << service->id();
                service->postEvent(new QScxmlEvent(*event));
            }
        }
    }

    if (event->eventType() == QScxmlEvent::ExternalEvent)
        m_router.route(event->name().split(QLatin1Char('.')), event);

    if (event->eventType() == QScxmlEvent::ExternalEvent) {
        qCDebug(qscxmlLog) << q << "posting external event" << event->name();
        m_externalQueue.enqueue(event);
    } else {
        qCDebug(qscxmlLog) << q << "posting internal event" << event->name();
        m_internalQueue.enqueue(event);
    }

    m_eventLoopHook.queueProcessEvents();
}

void QScxmlStateMachinePrivate::submitDelayedEvent(QScxmlEvent *event)
{
    Q_ASSERT(event);
    Q_ASSERT(event->delay() > 0);

    const int timerId = m_eventLoopHook.startTimer(event->delay());
    if (timerId == 0) {
        qWarning("QScxmlStateMachinePrivate::submitDelayedEvent: "
                 "failed to start timer for event '%s' (%p)",
                 qPrintable(event->name()), event);
        delete event;
        return;
    }
    m_delayedEvents.push_back(std::make_pair(timerId, event));

    qCDebug(qscxmlLog) << q_func()
                       << ": delayed event" << event->name()
                       << "(" << event << ") got id:" << timerId;
}

/*!
 * Submits an error event to the external event queue of this state machine.
 *
 * The type of the error is specified by \a type. The value of type has to begin
 * with the string \e error. For example \c {error.execution}. The message,
 * \a message, decribes the error and is passed to the event as the
 * \c errorMessage property. The \a sendId of the message causing the error is specified, if it has
 * one.
 */
void QScxmlStateMachinePrivate::submitError(const QString &type, const QString &message,
                                            const QString &sendId)
{
    Q_Q(QScxmlStateMachine);
    qCDebug(qscxmlLog) << q << "had error" << type << ":" << message;
    if (!type.startsWith(QStringLiteral("error.")))
        qCWarning(qscxmlLog) << q << "Message type of error message does not start with 'error.'!";
    q->submitEvent(QScxmlEventBuilder::errorEvent(q, type, message, sendId));
}

void QScxmlStateMachinePrivate::start()
{
    Q_Q(QScxmlStateMachine);

    if (m_stateTable->binding == StateTable::LateBinding)
        m_isFirstStateEntry.resize(m_stateTable->stateCount, true);

    bool running = isRunnable() && !isPaused();
    m_runningState = Starting;
    Q_ASSERT(m_stateTable->initialTransition != StateTable::InvalidIndex);

    if (!running)
        emit q->runningChanged(true);
}

void QScxmlStateMachinePrivate::pause()
{
    Q_Q(QScxmlStateMachine);

    if (isRunnable() && !isPaused()) {
        m_runningState = Paused;
        emit q->runningChanged(false);
    }
}

void QScxmlStateMachinePrivate::processEvents()
{
    if (m_isProcessingEvents || (!isRunnable() && !isPaused()))
        return;

    m_isProcessingEvents = true;

    Q_Q(QScxmlStateMachine);
    qCDebug(qscxmlLog) << q_func() << "starting macrostep";

    while (isRunnable() && !isPaused()) {
        if (m_runningState == Starting) {
            enterStates({m_stateTable->initialTransition});
            if (m_runningState == Starting)
                m_runningState = Running;
            continue;
        }

        OrderedSet enabledTransitions;
        std::vector<int> configurationInDocumentOrder = m_configuration.list();
        std::sort(configurationInDocumentOrder.begin(), configurationInDocumentOrder.end());
        selectTransitions(enabledTransitions, configurationInDocumentOrder, nullptr);
        if (!enabledTransitions.isEmpty()) {
            microstep(enabledTransitions);
        } else if (!m_internalQueue.isEmpty()) {
            auto event = m_internalQueue.dequeue();
            setEvent(event);
            selectTransitions(enabledTransitions, configurationInDocumentOrder, event);
            if (!enabledTransitions.isEmpty()) {
                microstep(enabledTransitions);
            }
            resetEvent();
            delete event;
        } else if (!m_externalQueue.isEmpty()) {
            auto event = m_externalQueue.dequeue();
            setEvent(event);
            selectTransitions(enabledTransitions, configurationInDocumentOrder, event);
            if (!enabledTransitions.isEmpty()) {
                microstep(enabledTransitions);
            }
            resetEvent();
            delete event;
        } else {
            // nothing to do, so:
            break;
        }
    }

    if (!m_statesToInvoke.empty()) {
        for (int stateId : m_statesToInvoke)
            addService(stateId);
        m_statesToInvoke.clear();
    }

    qCDebug(qscxmlLog) << q_func()
                       << "finished macrostep, runnable:" << isRunnable()
                       << "paused:" << isPaused();
    emit q->reachedStableState();
    if (!isRunnable() && !isPaused()) {
        exitInterpreter();
        emit q->finished();
    }

    m_isProcessingEvents = false;
}

void QScxmlStateMachinePrivate::setEvent(QScxmlEvent *event)
{
    Q_ASSERT(event);
    m_dataModel->setScxmlEvent(*event);
}

void QScxmlStateMachinePrivate::resetEvent()
{
    m_dataModel->setScxmlEvent(QScxmlEvent());
}

void QScxmlStateMachinePrivate::emitStateActive(int stateIndex, bool active)
{
    Q_Q(QScxmlStateMachine);
    void *args[] = { nullptr, const_cast<void*>(reinterpret_cast<const void*>(&active)) };
    const int signalIndex = m_stateIndexToSignalIndex.value(stateIndex, -1);
    if (signalIndex >= 0)
        QMetaObject::activate(q, m_metaObject, signalIndex, args);
}

void QScxmlStateMachinePrivate::emitInvokedServicesChanged()
{
    Q_Q(QScxmlStateMachine);
    emit q->invokedServicesChanged(q->invokedServices());
}

void QScxmlStateMachinePrivate::attach(QScxmlStateMachineInfo *info)
{
    Q_Q(QScxmlStateMachine);

    if (!m_infoSignalProxy)
        m_infoSignalProxy = new QScxmlInternal::StateMachineInfoProxy(q);

    QObject::connect(m_infoSignalProxy, &QScxmlInternal::StateMachineInfoProxy::statesEntered,
                     info, &QScxmlStateMachineInfo::statesEntered);
    QObject::connect(m_infoSignalProxy, &QScxmlInternal::StateMachineInfoProxy::statesExited,
                     info, &QScxmlStateMachineInfo::statesExited);
    QObject::connect(m_infoSignalProxy,&QScxmlInternal::StateMachineInfoProxy::transitionsTriggered,
                     info, &QScxmlStateMachineInfo::transitionsTriggered);
}

void QScxmlStateMachinePrivate::updateMetaCache()
{
    m_stateIndexToSignalIndex.clear();
    m_stateNameToSignalIndex.clear();

    if (!m_tableData)
        return;

    if (!m_stateTable)
        return;

    int signalIndex = 0;
    const int methodOffset = QMetaObjectPrivate::signalOffset(m_metaObject);
    for (int i = 0; i < m_stateTable->stateCount; ++i) {
        const auto &s = m_stateTable->state(i);
        if (!s.isHistoryState() && s.type != StateTable::State::Invalid) {
            m_stateIndexToSignalIndex.insert(i, signalIndex);
            m_stateNameToSignalIndex.insert(m_tableData->string(s.name),
                                            signalIndex + methodOffset);

            ++signalIndex;
        }
    }
}

QStringList QScxmlStateMachinePrivate::stateNames(const std::vector<int> &stateIndexes) const
{
    QStringList names;
    for (int idx : stateIndexes)
        names.append(m_tableData->string(m_stateTable->state(idx).name));
    return names;
}

std::vector<int> QScxmlStateMachinePrivate::historyStates(int stateIdx) const {
    const StateTable::Array kids = m_stateTable->array(m_stateTable->state(stateIdx).childStates);
    std::vector<int> res;
    if (!kids.isValid()) return res;
    for (int k : kids) {
        if (m_stateTable->state(k).isHistoryState())
            res.push_back(k);
    }
    return res;
}

void QScxmlStateMachinePrivate::exitInterpreter()
{
    qCDebug(qscxmlLog) << q_func() << "exiting SCXML processing";

    for (auto it : m_delayedEvents) {
        m_eventLoopHook.killTimer(it.first);
        delete it.second;
    }
    m_delayedEvents.clear();

    auto statesToExitSorted = m_configuration.list();
    std::sort(statesToExitSorted.begin(), statesToExitSorted.end(), std::greater<int>());
    for (int stateIndex : statesToExitSorted) {
        const auto &state = m_stateTable->state(stateIndex);
        if (state.exitInstructions != StateTable::InvalidIndex) {
            m_executionEngine->execute(state.exitInstructions);
        }
        removeService(stateIndex);
        if (state.type == StateTable::State::Final && state.parentIsScxmlElement()) {
            returnDoneEvent(state.doneData);
        }
    }
}

void QScxmlStateMachinePrivate::returnDoneEvent(QScxmlExecutableContent::ContainerId doneData)
{
    Q_Q(QScxmlStateMachine);

    m_executionEngine->execute(doneData, QVariant());
    if (m_isInvoked) {
        auto e = new QScxmlEvent;
        e->setName(QStringLiteral("done.invoke.") + q->sessionId());
        e->setInvokeId(q->sessionId());
        QScxmlStateMachinePrivate::get(m_parentStateMachine)->postEvent(e);
    }
}

bool QScxmlStateMachinePrivate::nameMatch(const StateTable::Array &patterns,
                                          QScxmlEvent *event) const
{
    const QString eventName = event->name();
    bool selected = false;
    for (int eventSelectorIter = 0; eventSelectorIter < patterns.size(); ++eventSelectorIter) {
        QString eventStr = m_tableData->string(patterns[eventSelectorIter]);
        if (eventStr == QStringLiteral("*")) {
            selected = true;
            break;
        }
        if (eventStr.endsWith(QStringLiteral(".*")))
            eventStr.chop(2);
        if (eventName.startsWith(eventStr)) {
            QChar nextC = QLatin1Char('.');
            if (eventName.size() > eventStr.size())
                nextC = eventName.at(eventStr.size());
            if (nextC == QLatin1Char('.') || nextC == QLatin1Char('(')) {
                selected = true;
                break;
            }
        }
    }
    return selected;
}

void QScxmlStateMachinePrivate::selectTransitions(OrderedSet &enabledTransitions,
                                                  const std::vector<int> &configInDocumentOrder,
                                                  QScxmlEvent *event) const
{
    if (event == nullptr) {
        qCDebug(qscxmlLog) << q_func() << "selectEventlessTransitions";
    } else {
        qCDebug(qscxmlLog) << q_func() << "selectTransitions with event"
                           << QScxmlEventPrivate::debugString(event).constData();
    }

    std::vector<int> states;
    states.reserve(16);
    for (int configStateIdx : configInDocumentOrder) {
        if (m_stateTable->state(configStateIdx).isAtomic()) {
            states.clear();
            states.push_back(configStateIdx);
            getProperAncestors(&states, configStateIdx, -1);
            for (int stateIdx : states) {
                bool finishedWithThisConfigState  = false;

                if (stateIdx == -1) {
                    // the state machine has no transitions (other than the initial one, which has
                    // already been taken at this point)
                    continue;
                }
                const auto &state = m_stateTable->state(stateIdx);
                const StateTable::Array transitions = m_stateTable->array(state.transitions);
                if (!transitions.isValid())
                    continue;
                std::vector<int> sortedTransitions(transitions.size(), -1);
                std::copy(transitions.begin(), transitions.end(), sortedTransitions.begin());
                for (int transitionIndex : sortedTransitions) {
                    const StateTable::Transition &t = m_stateTable->transition(transitionIndex);
                    bool enabled = false;
                    if (event == nullptr) {
                        if (t.events == -1) {
                            if (t.condition == -1) {
                                enabled = true;
                            } else {
                                bool ok = false;
                                enabled = m_dataModel->evaluateToBool(t.condition, &ok) && ok;
                            }
                        }
                    } else {
                        if (t.events != -1 && nameMatch(m_stateTable->array(t.events), event)) {
                            if (t.condition == -1) {
                                enabled = true;
                            } else {
                                bool ok = false;
                                enabled = m_dataModel->evaluateToBool(t.condition, &ok) && ok;
                            }
                        }
                    }
                    if (enabled) {
                        enabledTransitions.add(transitionIndex);
                        finishedWithThisConfigState = true;
                        break; // stop iterating over transitions
                    }
                }

                if (finishedWithThisConfigState)
                    break; // stop iterating over ancestors
            }
        }
    }
    if (!enabledTransitions.isEmpty())
        removeConflictingTransitions(&enabledTransitions);
}

void QScxmlStateMachinePrivate::removeConflictingTransitions(OrderedSet *enabledTransitions) const
{
    Q_ASSERT(enabledTransitions);

    auto sortedTransitions = enabledTransitions->takeList();
    std::sort(sortedTransitions.begin(), sortedTransitions.end(), [this](int t1, int t2) -> bool {
        auto descendantDepth = [this](int state, int ancestor)->int {
            int depth = 0;
            for (int it = state; it != -1; it = m_stateTable->state(it).parent) {
                if (it == ancestor)
                    break;
                ++depth;
            }
            return depth;
        };

        const auto &s1 = m_stateTable->transition(t1).source;
        const auto &s2 = m_stateTable->transition(t2).source;
        if (s1 == s2) {
            return t1 < t2;
        } else if (isDescendant(s1, s2)) {
            return true;
        } else if (isDescendant(s2, s1)) {
            return false;
        } else {
            const int lcca = findLCCA({ s1, s2 });
            const int s1Depth = descendantDepth(s1, lcca);
            const int s2Depth = descendantDepth(s2, lcca);
            if (s1Depth == s2Depth)
                return s1 < s2;
            else
                return s1Depth > s2Depth;
        }
    });

    OrderedSet filteredTransitions;
    for (int t1 : sortedTransitions) {
        OrderedSet transitionsToRemove;
        bool t1Preempted = false;
        OrderedSet exitSetT1;
        computeExitSet({t1}, exitSetT1);
        const int source1 = m_stateTable->transition(t1).source;
        for (int t2 : filteredTransitions) {
            OrderedSet exitSetT2;
            computeExitSet({t2}, exitSetT2);
            if (exitSetT1.intersectsWith(exitSetT2)) {
                const int source2 = m_stateTable->transition(t2).source;
                if (isDescendant(source1, source2)) {
                    transitionsToRemove.add(t2);
                } else {
                    t1Preempted = true;
                    break;
                }
            }
        }
        if (!t1Preempted) {
            for (int t3 : transitionsToRemove) {
                filteredTransitions.remove(t3);
            }
            filteredTransitions.add(t1);
        }
    }
    *enabledTransitions = filteredTransitions;
}

void QScxmlStateMachinePrivate::getProperAncestors(std::vector<int> *ancestors, int state1,
                                                   int state2) const
{
    Q_ASSERT(ancestors);

    if (state1 == -1) {
        return;
    }

    int parent = state1;
    do {
        parent = m_stateTable->state(parent).parent;
        if (parent == state2) {
            break;
        }
        ancestors->push_back(parent);
    } while (parent != -1);
}

void QScxmlStateMachinePrivate::microstep(const OrderedSet &enabledTransitions)
{
    if (qscxmlLog().isDebugEnabled()) {
        qCDebug(qscxmlLog) << q_func()
                           << "starting microstep, configuration:"
                           << stateNames(m_configuration.list());
        qCDebug(qscxmlLog) << q_func() << "enabled transitions:";
        for (int t : enabledTransitions) {
            const auto &transition = m_stateTable->transition(t);
            QString from = QStringLiteral("(none)");
            if (transition.source != StateTable::InvalidIndex)
                from = m_tableData->string(m_stateTable->state(transition.source).name);
            QStringList to;
            if (transition.targets == StateTable::InvalidIndex) {
                to.append(QStringLiteral("(none)"));
            } else {
                for (int t : m_stateTable->array(transition.targets))
                    to.append(m_tableData->string(m_stateTable->state(t).name));
            }
            qCDebug(qscxmlLog) << q_func() << "\t" << t << ":" << from << "->"
                               << to.join(QLatin1Char(','));
        }
    }

    exitStates(enabledTransitions);
    executeTransitionContent(enabledTransitions);
    enterStates(enabledTransitions);

    qCDebug(qscxmlLog) << q_func() << "finished microstep, configuration:"
                       << stateNames(m_configuration.list());
}

void QScxmlStateMachinePrivate::exitStates(const OrderedSet &enabledTransitions)
{
    OrderedSet statesToExit;
    computeExitSet(enabledTransitions, statesToExit);
    auto statesToExitSorted = statesToExit.takeList();
    std::sort(statesToExitSorted.begin(), statesToExitSorted.end(), std::greater<int>());
    qCDebug(qscxmlLog) << q_func() << "exiting states" << stateNames(statesToExitSorted);
    for (int s : statesToExitSorted) {
        const auto &state = m_stateTable->state(s);
        if (state.serviceFactoryIds != StateTable::InvalidIndex)
            m_statesToInvoke.remove(s);
    }
    for (int s : statesToExitSorted) {
        for (int h : historyStates(s)) {
            const auto &hState = m_stateTable->state(h);
            QVector<int> history;

            for (int s0 : m_configuration) {
                const auto &s0State = m_stateTable->state(s0);
                if (hState.type == StateTable::State::DeepHistory) {
                    if (s0State.isAtomic() && isDescendant(s0, s))
                        history.append(s0);
                } else {
                    if (s0State.parent == s)
                        history.append(s0);
                }
            }

            m_historyValue[h] = history;
        }
    }
    for (int s : statesToExitSorted) {
        const auto &state = m_stateTable->state(s);
        if (state.exitInstructions != StateTable::InvalidIndex)
            m_executionEngine->execute(state.exitInstructions);
        m_configuration.remove(s);
        emitStateActive(s, false);
        removeService(s);
    }

    if (m_infoSignalProxy) {
        emit m_infoSignalProxy->statesExited(
                QVector<QScxmlStateMachineInfo::StateId>(statesToExitSorted.begin(),
                                                         statesToExitSorted.end()));
    }
}

void QScxmlStateMachinePrivate::computeExitSet(const OrderedSet &enabledTransitions,
                                               OrderedSet &statesToExit) const
{
    for (int t : enabledTransitions) {
        const auto &transition = m_stateTable->transition(t);
        if (transition.targets == StateTable::InvalidIndex) {
            // nothing to do here: there is no exit set
        } else {
            const int domain = getTransitionDomain(t);
            for (int s : m_configuration) {
                if (isDescendant(s, domain))
                    statesToExit.add(s);
            }
        }
    }
}

void QScxmlStateMachinePrivate::executeTransitionContent(const OrderedSet &enabledTransitions)
{
    for (int t : enabledTransitions) {
        const auto &transition = m_stateTable->transition(t);
        if (transition.transitionInstructions != StateTable::InvalidIndex)
            m_executionEngine->execute(transition.transitionInstructions);
    }

    if (m_infoSignalProxy) {
        emit m_infoSignalProxy->transitionsTriggered(
                QVector<QScxmlStateMachineInfo::TransitionId>(enabledTransitions.list().begin(),
                                                              enabledTransitions.list().end()));
    }
}

void QScxmlStateMachinePrivate::enterStates(const OrderedSet &enabledTransitions)
{
    Q_Q(QScxmlStateMachine);

    OrderedSet statesToEnter, statesForDefaultEntry;
    HistoryContent defaultHistoryContent;
    computeEntrySet(enabledTransitions, &statesToEnter, &statesForDefaultEntry,
                    &defaultHistoryContent);
    auto sortedStates = statesToEnter.takeList();
    std::sort(sortedStates.begin(), sortedStates.end());
    qCDebug(qscxmlLog) << q_func() << "entering states" << stateNames(sortedStates);
    for (int s : sortedStates) {
        const auto &state = m_stateTable->state(s);
        m_configuration.add(s);
        if (state.serviceFactoryIds != StateTable::InvalidIndex)
            m_statesToInvoke.insert(s);
        if (m_stateTable->binding == StateTable::LateBinding && m_isFirstStateEntry[s]) {
            if (state.initInstructions != StateTable::InvalidIndex)
                m_executionEngine->execute(state.initInstructions);
            m_isFirstStateEntry[s] = false;
        }
        if (state.entryInstructions != StateTable::InvalidIndex)
            m_executionEngine->execute(state.entryInstructions);
        if (statesForDefaultEntry.contains(s)) {
            const auto &initialTransition = m_stateTable->transition(state.initialTransition);
            if (initialTransition.transitionInstructions != StateTable::InvalidIndex)
                m_executionEngine->execute(initialTransition.transitionInstructions);
        }
        const int dhc = defaultHistoryContent.value(s);
        if (dhc != StateTable::InvalidIndex)
            m_executionEngine->execute(dhc);
        if (state.type == StateTable::State::Final) {
            if (state.parentIsScxmlElement()) {
                bool running = isRunnable() && !isPaused();
                m_runningState = Finished;
                if (running)
                    emit q->runningChanged(false);
            } else {
                const auto &parent = m_stateTable->state(state.parent);
                m_executionEngine->execute(state.doneData, m_tableData->string(parent.name));
                if (parent.parent != StateTable::InvalidIndex) {
                    const auto &grandParent = m_stateTable->state(parent.parent);
                    if (grandParent.isParallel()) {
                        if (allInFinalStates(getChildStates(grandParent))) {
                            auto e = new QScxmlEvent;
                            e->setEventType(QScxmlEvent::InternalEvent);
                            e->setName(QStringLiteral("done.state.")
                                       + m_tableData->string(grandParent.name));
                            q->submitEvent(e);
                        }
                    }
                }
            }
        }
    }
    for (int s : sortedStates)
        emitStateActive(s, true);
    if (m_infoSignalProxy) {
        emit m_infoSignalProxy->statesEntered(
                QVector<QScxmlStateMachineInfo::StateId>(sortedStates.begin(),
                                                         sortedStates.end()));
    }
}

void QScxmlStateMachinePrivate::computeEntrySet(const OrderedSet &enabledTransitions,
                                                OrderedSet *statesToEnter,
                                                OrderedSet *statesForDefaultEntry,
                                                HistoryContent *defaultHistoryContent) const
{
    Q_ASSERT(statesToEnter);
    Q_ASSERT(statesForDefaultEntry);
    Q_ASSERT(defaultHistoryContent);

    for (int t : enabledTransitions) {
        const auto &transition = m_stateTable->transition(t);
        if (transition.targets == StateTable::InvalidIndex)
            // targetless transition, so nothing to do
            continue;
        for (int s : m_stateTable->array(transition.targets))
            addDescendantStatesToEnter(s, statesToEnter, statesForDefaultEntry,
                                       defaultHistoryContent);
        auto ancestor = getTransitionDomain(t);
        OrderedSet targets;
        getEffectiveTargetStates(&targets, t);
        for (auto s : targets)
            addAncestorStatesToEnter(s, ancestor, statesToEnter, statesForDefaultEntry,
                                     defaultHistoryContent);
    }
}

void QScxmlStateMachinePrivate::addDescendantStatesToEnter(
        int stateIndex, OrderedSet *statesToEnter, OrderedSet *statesForDefaultEntry,
        HistoryContent *defaultHistoryContent) const
{
    Q_ASSERT(statesToEnter);
    Q_ASSERT(statesForDefaultEntry);
    Q_ASSERT(defaultHistoryContent);

    const auto &state = m_stateTable->state(stateIndex);
    if (state.isHistoryState()) {
        HistoryValues::const_iterator historyValueIter = m_historyValue.find(stateIndex);
        if (historyValueIter != m_historyValue.end()) {
            auto historyValue = historyValueIter.value();
            for (int s : historyValue)
                addDescendantStatesToEnter(s, statesToEnter, statesForDefaultEntry,
                                           defaultHistoryContent);
            for (int s : historyValue)
                addAncestorStatesToEnter(s, state.parent, statesToEnter, statesForDefaultEntry,
                                         defaultHistoryContent);
        } else {
            const auto transitionIdx = m_stateTable->array(state.transitions)[0];
            const auto &defaultHistoryTransition = m_stateTable->transition(transitionIdx);
            defaultHistoryContent->operator[](state.parent) =
                    defaultHistoryTransition.transitionInstructions;
            StateTable::Array targetStates = m_stateTable->array(defaultHistoryTransition.targets);
            for (int s : targetStates)
                addDescendantStatesToEnter(s, statesToEnter, statesForDefaultEntry,
                                           defaultHistoryContent);
            for (int s : targetStates)
                addAncestorStatesToEnter(s, state.parent, statesToEnter, statesForDefaultEntry,
                                         defaultHistoryContent);
        }
    } else {
        statesToEnter->add(stateIndex);
        if (state.isCompound()) {
            statesForDefaultEntry->add(stateIndex);
            if (state.initialTransition != StateTable::InvalidIndex) {
                auto initialTransition = m_stateTable->transition(state.initialTransition);
                auto initialTransitionTargets = m_stateTable->array(initialTransition.targets);
                for (int targetStateIndex : initialTransitionTargets)
                    addDescendantStatesToEnter(targetStateIndex, statesToEnter,
                                               statesForDefaultEntry, defaultHistoryContent);
                for (int targetStateIndex : initialTransitionTargets)
                    addAncestorStatesToEnter(targetStateIndex, stateIndex, statesToEnter,
                                             statesForDefaultEntry, defaultHistoryContent);
            }
        } else {
            if (state.isParallel()) {
                for (int child : getChildStates(state)) {
                    if (!hasDescendant(*statesToEnter, child))
                        addDescendantStatesToEnter(child, statesToEnter, statesForDefaultEntry,
                                                   defaultHistoryContent);
                }
            }
        }
    }
}

void QScxmlStateMachinePrivate::addAncestorStatesToEnter(
        int stateIndex, int ancestorIndex, OrderedSet *statesToEnter,
        OrderedSet *statesForDefaultEntry, HistoryContent *defaultHistoryContent) const
{
    Q_ASSERT(statesToEnter);
    Q_ASSERT(statesForDefaultEntry);
    Q_ASSERT(defaultHistoryContent);

    std::vector<int> ancestors;
    getProperAncestors(&ancestors, stateIndex, ancestorIndex);
    for (int anc : ancestors) {
        if (anc == -1) {
            // we can't enter the state machine itself, so:
            continue;
        }
        statesToEnter->add(anc);
        const auto &ancState = m_stateTable->state(anc);
        if (ancState.isParallel()) {
            for (int child : getChildStates(ancState)) {
                if (!hasDescendant(*statesToEnter, child))
                    addDescendantStatesToEnter(child, statesToEnter, statesForDefaultEntry,
                                               defaultHistoryContent);
            }
        }
    }
}

std::vector<int> QScxmlStateMachinePrivate::getChildStates(
        const QScxmlExecutableContent::StateTable::State &state) const
{
    std::vector<int> childStates;
    auto kids = m_stateTable->array(state.childStates);
    if (kids.isValid()) {
        childStates.reserve(kids.size());
        for (int kiddo : kids) {
            switch (m_stateTable->state(kiddo).type) {
            case StateTable::State::Normal:
            case StateTable::State::Final:
            case StateTable::State::Parallel:
                childStates.push_back(kiddo);
                break;
            default:
                break;
            }
        }
    }
    return childStates;
}

bool QScxmlStateMachinePrivate::hasDescendant(const OrderedSet &statesToEnter, int childIdx) const
{
    for (int s : statesToEnter) {
        if (isDescendant(s, childIdx))
            return true;
    }
    return false;
}

bool QScxmlStateMachinePrivate::allDescendants(const OrderedSet &statesToEnter, int childdx) const
{
    for (int s : statesToEnter) {
        if (!isDescendant(s, childdx))
            return false;
    }
    return true;
}

bool QScxmlStateMachinePrivate::isDescendant(int state1, int state2) const
{
    int parent = state1;
    do {
        parent = m_stateTable->state(parent).parent;
        if (parent == state2)
            return true;
    } while (parent != -1);
    return false;
}

bool QScxmlStateMachinePrivate::allInFinalStates(const std::vector<int> &states) const
{
    if (states.empty())
        return false;

    for (int idx : states) {
        if (!isInFinalState(idx))
            return false;
    }

    return true;
}

bool QScxmlStateMachinePrivate::someInFinalStates(const std::vector<int> &states) const
{
    for (int stateIndex : states) {
        const auto &state = m_stateTable->state(stateIndex);
        if (state.type == StateTable::State::Final && m_configuration.contains(stateIndex))
            return true;
    }
    return false;
}

bool QScxmlStateMachinePrivate::isInFinalState(int stateIndex) const
{
    const auto &state = m_stateTable->state(stateIndex);
    if (state.isCompound())
        return someInFinalStates(getChildStates(state)) && m_configuration.contains(stateIndex);
    else if (state.isParallel())
        return allInFinalStates(getChildStates(state));
    else
        return false;
}

int QScxmlStateMachinePrivate::getTransitionDomain(int transitionIndex) const
{
    const auto &transition = m_stateTable->transition(transitionIndex);
    if (transition.source == -1)
        //oooh, we have the initial transition of the state machine.
        return -1;

    OrderedSet tstates;
    getEffectiveTargetStates(&tstates, transitionIndex);
    if (tstates.isEmpty()) {
        return StateTable::InvalidIndex;
    } else {
        const auto &sourceState = m_stateTable->state(transition.source);
        if (transition.type == StateTable::Transition::Internal
                && sourceState.isCompound()
                && allDescendants(tstates, transition.source)) {
            return transition.source;
        } else {
            tstates.add(transition.source);
            return findLCCA(std::move(tstates));
        }
    }
}

int QScxmlStateMachinePrivate::findLCCA(OrderedSet &&states) const
{
    std::vector<int> ancestors;
    const int head = *states.begin();
    OrderedSet tail(std::move(states));
    tail.removeHead();

    getProperAncestors(&ancestors, head, StateTable::InvalidIndex);
    for (int anc : ancestors) {
        if (anc != -1) { // the state machine itself is always compound
            const auto &ancState = m_stateTable->state(anc);
            if (!ancState.isCompound())
                continue;
        }

        if (allDescendants(tail, anc))
            return anc;
    }

    return StateTable::InvalidIndex;
}

void QScxmlStateMachinePrivate::getEffectiveTargetStates(OrderedSet *targets,
                                                         int transitionIndex) const
{
    Q_ASSERT(targets);

    const auto &transition = m_stateTable->transition(transitionIndex);
    for (int s : m_stateTable->array(transition.targets)) {
        const auto &state = m_stateTable->state(s);
        if (state.isHistoryState()) {
            HistoryValues::const_iterator historyValueIter = m_historyValue.find(s);
            if (historyValueIter != m_historyValue.end()) {
                for (int historyState : historyValueIter.value()) {
                    targets->add(historyState);
                }
            } else {
                getEffectiveTargetStates(targets, m_stateTable->array(state.transitions)[0]);
            }
        } else {
            targets->add(s);
        }
    }
}

/*!
 * Creates a state machine from the SCXML file specified by \a fileName.
 *
 * This method will always return a state machine. If errors occur while reading the SCXML file,
 * the state machine cannot be started. The errors can be retrieved by calling the parseErrors()
 * method.
 *
 * \sa parseErrors()
 */
QScxmlStateMachine *QScxmlStateMachine::fromFile(const QString &fileName)
{
    QFile scxmlFile(fileName);
    if (!scxmlFile.open(QIODevice::ReadOnly)) {
        auto stateMachine = new QScxmlStateMachine(&QScxmlStateMachine::staticMetaObject);
        QScxmlError err(scxmlFile.fileName(), 0, 0, QStringLiteral("cannot open for reading"));
        QScxmlStateMachinePrivate::get(stateMachine)->parserData()->m_errors.append(err);
        return stateMachine;
    }

    QScxmlStateMachine *stateMachine = fromData(&scxmlFile, fileName);
    scxmlFile.close();
    return stateMachine;
}

/*!
 * Creates a state machine by reading from the QIODevice specified by \a data.
 *
 * This method will always return a state machine. If errors occur while reading the SCXML file,
 * \a fileName, the state machine cannot be started. The errors can be retrieved by calling the
 * parseErrors() method.
 *
 * \sa parseErrors()
 */
QScxmlStateMachine *QScxmlStateMachine::fromData(QIODevice *data, const QString &fileName)
{
    QXmlStreamReader xmlReader(data);
    QScxmlCompiler compiler(&xmlReader);
    compiler.setFileName(fileName);
    return compiler.compile();
}

QVector<QScxmlError> QScxmlStateMachine::parseErrors() const
{
    Q_D(const QScxmlStateMachine);
    return d->m_parserData ? d->m_parserData->m_errors : QVector<QScxmlError>();
}

QScxmlStateMachine::QScxmlStateMachine(const QMetaObject *metaObject, QObject *parent)
    : QObject(*new QScxmlStateMachinePrivate(metaObject), parent)
{
    Q_D(QScxmlStateMachine);
    d->m_executionEngine = new QScxmlExecutionEngine(this);
}

QScxmlStateMachine::QScxmlStateMachine(QScxmlStateMachinePrivate &dd, QObject *parent)
    : QObject(dd, parent)
{
    Q_D(QScxmlStateMachine);
    d->m_executionEngine = new QScxmlExecutionEngine(this);
}

/*!
    \property QScxmlStateMachine::running

    \brief the running state of this state machine

    \sa start()
 */

/*!
    \qmlproperty bool ScxmlStateMachine::running

    The running state of this state machine.
*/

/*!
    \property QScxmlStateMachine::dataModel

    \brief The data model to be used for this state machine.

    SCXML data models are described in
    \l {SCXML Specification - 5 Data Model and Data Manipulation}. For more
    information about supported data models, see \l {SCXML Compliance}.

    Changing the data model when the state machine has been \c initialized is
    not specified in the SCXML standard and leads to undefined behavior.

    \sa QScxmlDataModel, QScxmlNullDataModel, QScxmlEcmaScriptDataModel,
        QScxmlCppDataModel
*/

/*!
    \qmlproperty ScxmlDataModel ScxmlStateMachine::dataModel

    The data model to be used for this state machine.

    SCXML data models are described in
    \l {SCXML Specification - 5 Data Model and Data Manipulation}. For more
    information about supported data models, see \l {SCXML Compliance}.

    Changing the data model when the state machine has been \l initialized is
    not specified in the SCXML standard and leads to undefined behavior.

    \sa QScxmlDataModel, QScxmlNullDataModel, QScxmlEcmaScriptDataModel,
        QScxmlCppDataModel
*/

/*!
    \property QScxmlStateMachine::initialized

    \brief Whether the state machine has been initialized.

    It is \c true if the state machine has been initialized, \c false otherwise.

    \sa QScxmlStateMachine::init(), QScxmlDataModel
*/

/*!
    \qmlproperty bool ScxmlStateMachine::initialized

    This read-only property is set to \c true if the state machine has been
    initialized, \c false otherwise.
*/

/*!
    \property QScxmlStateMachine::initialValues

    \brief The initial values to be used for setting up the data model.

    \sa QScxmlStateMachine::init(), QScxmlDataModel
*/

/*!
    \qmlproperty var ScxmlStateMachine::initialValues

    The initial values to be used for setting up the data model.
*/

/*!
    \property QScxmlStateMachine::sessionId

    \brief The session ID of the current state machine.

    The session ID is used for message routing between parent and child state machines. If a state
    machine is started by an \c <invoke> element, any event it sends will have the \c invokeid field
    set to the session ID. The state machine will use the origin of an event (which is set by the
    \e target or \e targetexpr attribute in a \c <send> element) to dispatch messages to the correct
    child state machine.

    \sa QScxmlEvent::invokeId()
 */

/*!
    \qmlproperty string ScxmlStateMachine::sessionId

    The session ID of the current state machine.

    The session ID is used for message routing between parent and child state
    machines. If a state machine is started by an \c <invoke> element, any event
    it sends will have the \c invokeid field set to the session ID. The state
    machine will use the origin of an event (which is set by the \e target or
    \e targetexpr attribute in a \c <send> element) to dispatch messages to the
    correct child state machine.
*/

/*!
    \property QScxmlStateMachine::name

    \brief The name of the state machine as set by the \e name attribute of the \c <scxml> tag.
 */

/*!
    \qmlproperty string ScxmlStateMachine::name

    The name of the state machine as set by the \e name attribute of the
    \c <scxml> tag.
*/

/*!
    \property QScxmlStateMachine::invoked

    \brief Whether the state machine was invoked from an outer state machine.

    \c true when the state machine was started as a service with the \c <invoke> element,
    \c false otherwise.
 */

/*!
    \qmlproperty bool ScxmlStateMachine::invoked

    Whether the state machine was invoked from an outer state machine.

    This read-only property is set to \c true when the state machine was started
    as a service with the \c <invoke> element, \c false otherwise.
 */

/*!
    \property QScxmlStateMachine::parseErrors

    \brief The list of parse errors that occurred while creating a state machine from an SCXML file.
 */

/*!
    \qmlproperty var ScxmlStateMachine::parseErrors

    The list of parse errors that occurred while creating a state machine from
    an SCXML file.
 */

/*!
    \property QScxmlStateMachine::loader

    \brief The loader that is currently used to resolve and load URIs for the state machine.
 */

/*!
    \qmlproperty Loader ScxmlStateMachine::loader

    The loader that is currently used to resolve and load URIs for the state
    machine.
 */

/*!
    \property QScxmlStateMachine::tableData

    \brief The table data that is used when generating C++ from an SCXML file.

    The class implementing
    the state machine will use this property to assign the generated table
    data. The state machine does not assume ownership of the table data.
 */

QString QScxmlStateMachine::sessionId() const
{
    Q_D(const QScxmlStateMachine);

    return d->m_sessionId;
}

QString QScxmlStateMachinePrivate::generateSessionId(const QString &prefix)
{
    int id = ++QScxmlStateMachinePrivate::m_sessionIdCounter;
    return prefix + QString::number(id);
}

bool QScxmlStateMachine::isInvoked() const
{
    Q_D(const QScxmlStateMachine);
    return d->m_isInvoked;
}

bool QScxmlStateMachine::isInitialized() const
{
    Q_D(const QScxmlStateMachine);
    return d->m_isInitialized;
}

/*!
 * Sets the data model for this state machine to \a model. There is a 1:1
 * relation between state machines and models. After setting the model once you
 * cannot change it anymore. Any further attempts to set the model using this
 * method will be ignored.
 */
void QScxmlStateMachine::setDataModel(QScxmlDataModel *model)
{
    Q_D(QScxmlStateMachine);

    if (d->m_dataModel == nullptr && model != nullptr) {
        d->m_dataModel = model;
        if (model)
            model->setStateMachine(this);
        emit dataModelChanged(model);
    }
}

/*!
 * Returns the data model used by the state machine.
 */
QScxmlDataModel *QScxmlStateMachine::dataModel() const
{
    Q_D(const QScxmlStateMachine);

    return d->m_dataModel;
}

void QScxmlStateMachine::setLoader(QScxmlCompiler::Loader *loader)
{
    Q_D(QScxmlStateMachine);

    if (loader != d->m_loader) {
        d->m_loader = loader;
        emit loaderChanged(loader);
    }
}

QScxmlCompiler::Loader *QScxmlStateMachine::loader() const
{
    Q_D(const QScxmlStateMachine);

    return d->m_loader;
}

QScxmlTableData *QScxmlStateMachine::tableData() const
{
    Q_D(const QScxmlStateMachine);

    return d->m_tableData;
}

void QScxmlStateMachine::setTableData(QScxmlTableData *tableData)
{
    Q_D(QScxmlStateMachine);

    if (d->m_tableData == tableData)
        return;

    d->m_tableData = tableData;
    if (tableData) {
        d->m_stateTable = reinterpret_cast<const QScxmlExecutableContent::StateTable *>(
                    tableData->stateMachineTable());
        if (objectName().isEmpty()) {
            setObjectName(tableData->name());
        }
        if (d->m_stateTable->maxServiceId != QScxmlExecutableContent::StateTable::InvalidIndex) {
            const size_t serviceCount = size_t(d->m_stateTable->maxServiceId + 1);
            d->m_invokedServices.resize(serviceCount, { -1, nullptr, QString() });
            d->m_cachedFactories.resize(serviceCount, nullptr);
        }

        if (d->m_stateTable->version != Q_QSCXMLC_OUTPUT_REVISION) {
           qFatal("Cannot mix incompatible state table (version 0x%x) with this library "
                  "(version 0x%x)", d->m_stateTable->version, Q_QSCXMLC_OUTPUT_REVISION);
        }
        Q_ASSERT(tableData->stateMachineTable()[d->m_stateTable->arrayOffset +
                                                d->m_stateTable->arraySize]
                == QScxmlExecutableContent::StateTable::terminator);
    }

    d->updateMetaCache();

    emit tableDataChanged(tableData);
}

/*!
    \qmlmethod ScxmlStateMachine::stateNames(bool compress)

    Retrieves a list of state names of all states.

    When \a compress is \c true (the default), the states that contain child
    states is filtered out and only the \e {leaf states} is returned.  When it
    is \c false, the full list of all states is returned.

    The returned list does not contain the states of possible nested state
    machines.

    \note The order of the state names in the list is the order in which the
    states occurred in the SCXML document.
*/

/*!
 * Retrieves a list of state names of all states.
 *
 * When \a compress is \c true (the default), the states that contain child states
 * will be filtered out and only the \e {leaf states} will be returned.
 * When it is \c false, the full list of all states will be returned.
 *
 * The returned list does not contain the states of possible nested state machines.
 *
 * \note The order of the state names in the list is the order in which the states occurred in
 *       the SCXML document.
 */
QStringList QScxmlStateMachine::stateNames(bool compress) const
{
    Q_D(const QScxmlStateMachine);

    QStringList names;
    for (int i = 0; i < d->m_stateTable->stateCount; ++i) {
        const auto &state = d->m_stateTable->state(i);
        if (!compress || state.isAtomic())
            names.append(d->m_tableData->string(state.name));
    }
    return names;
}

/*!
    \qmlmethod ScxmlStateMachine::activeStateNames(bool compress)

    Retrieves a list of state names of all active states.

    When a state is active, all its parent states are active by definition. When
    \a compress is \c true (the default), the parent states are filtered out and
    only the \e {leaf states} are returned. When it is \c false, the full list
    of active states is returned.
*/

/*!
 * Retrieves a list of state names of all active states.
 *
 * When a state is active, all its parent states are active by definition. When \a compress
 * is \c true (the default), the parent states will be filtered out and only the \e {leaf states}
 * will be returned. When it is \c false, the full list of active states will be returned.
 */
QStringList QScxmlStateMachine::activeStateNames(bool compress) const
{
    Q_D(const QScxmlStateMachine);

    QStringList result;
    for (int stateIdx : d->m_configuration) {
        const auto &state = d->m_stateTable->state(stateIdx);
        if (state.isAtomic() || !compress)
            result.append(d->m_tableData->string(state.name));
    }
    return result;
}

/*!
    \qmlmethod ScxmlStateMachine::isActive(string scxmlStateName)

    Returns \c true if the state specified by \a scxmlStateName is active,
    \c false otherwise.
*/

/*!
 * Returns \c true if the state specified by \a scxmlStateName is active, \c false otherwise.
 */
bool QScxmlStateMachine::isActive(const QString &scxmlStateName) const
{
    Q_D(const QScxmlStateMachine);

    for (int stateIndex : d->m_configuration) {
        const auto &state = d->m_stateTable->state(stateIndex);
        if (d->m_tableData->string(state.name) == scxmlStateName)
            return true;
    }

    return false;
}

QMetaObject::Connection QScxmlStateMachine::connectToStateImpl(const QString &scxmlStateName,
                                                               const QObject *receiver, void **slot,
                                                               QtPrivate::QSlotObjectBase *slotObj,
                                                               Qt::ConnectionType type)
{
    const int *types = nullptr;
    if (type == Qt::QueuedConnection || type == Qt::BlockingQueuedConnection)
        types = QtPrivate::ConnectionTypes<QtPrivate::List<bool> >::types();

    Q_D(QScxmlStateMachine);
    const int signalIndex = d->m_stateNameToSignalIndex.value(scxmlStateName);
    return signalIndex < 0 ? QMetaObject::Connection()
                           : QObjectPrivate::connectImpl(this, signalIndex, receiver, slot, slotObj,
                                                         type, types, d->m_metaObject);
}

/*!
    Creates a connection of the given \a type from the state identified by \a scxmlStateName
    to the \a method in the \a receiver object. The receiver's \a method
    may take a boolean argument that indicates whether the state connected
    became active or inactive. For example:

    \code
    void mySlot(bool active);
    \endcode

    Returns a handle to the connection, which can be used later to disconnect.
 */
QMetaObject::Connection QScxmlStateMachine::connectToState(const QString &scxmlStateName,
                                                           const QObject *receiver,
                                                           const char *method,
                                                           Qt::ConnectionType type)
{
    QByteArray signalName = QByteArray::number(QSIGNAL_CODE) + scxmlStateName.toUtf8()
            + "Changed(bool)";
    return QObject::connect(this, signalName.constData(), receiver, method, type);
}

/*!
    Creates a connection of the specified \a type from the event specified by
    \a scxmlEventSpec to the \a method in the \a receiver object. The receiver's
    \a method may take a QScxmlEvent as a parameter. For example:

    \code
    void mySlot(const QScxmlEvent &event);
    \endcode

    In contrast to event specifications in SCXML documents, spaces are not
    allowed in the \a scxmlEventSpec here. In order to connect to multiple
    events with different prefixes, connectToEvent() has to be called multiple
    times.

    Returns a handle to the connection, which can be used later to disconnect.
*/
QMetaObject::Connection QScxmlStateMachine::connectToEvent(const QString &scxmlEventSpec,
                                                           const QObject *receiver,
                                                           const char *method,
                                                           Qt::ConnectionType type)
{
    Q_D(QScxmlStateMachine);
    return d->m_router.connectToEvent(scxmlEventSpec.split(QLatin1Char('.')), receiver, method,
                                      type);
}

QMetaObject::Connection QScxmlStateMachine::connectToEventImpl(const QString &scxmlEventSpec,
                                                               const QObject *receiver, void **slot,
                                                               QtPrivate::QSlotObjectBase *slotObj,
                                                               Qt::ConnectionType type)
{
    Q_D(QScxmlStateMachine);
    return d->m_router.connectToEvent(scxmlEventSpec.split(QLatin1Char('.')), receiver, slot,
                                      slotObj, type);
}

/*!
    \qmlmethod ScxmlStateMachine::init()

    Initializes the state machine by setting the initial values for \c <data>
    elements and executing any \c <script> tags of the \c <scxml> tag. The
    initial data values are taken from the \l initialValues property.

    Returns \c false if parse errors occur or if any of the initialization steps
    fail. Returns \c true otherwise.
*/

/*!
 * Initializes the state machine.
 *
 * State machine initialization consists of calling QScxmlDataModel::setup(), setting the initial
 * values for \c <data> elements, and executing any \c <script> tags of the \c <scxml> tag. The
 * initial data values are taken from the \c initialValues property.
 *
 * Returns \c false if parse errors occur or if any of the initialization steps fail.
 * Returns \c true otherwise.
 */
bool QScxmlStateMachine::init()
{
    Q_D(QScxmlStateMachine);

    if (d->m_isInitialized)
        return false;

    if (!parseErrors().isEmpty())
        return false;

    if (!dataModel() || !dataModel()->setup(d->m_initialValues))
        return false;

    if (!d->executeInitialSetup())
        return false;

    d->m_isInitialized = true;
    emit initializedChanged(true);
    return true;
}

/*!
 * Returns \c true if the state machine is running, \c false otherwise.
 *
 * \sa setRunning(), runningChanged()
 */
bool QScxmlStateMachine::isRunning() const
{
    Q_D(const QScxmlStateMachine);

    return d->isRunnable() && !d->isPaused();
}

/*!
 * Starts the state machine if \a running is \c true, or stops it otherwise.
 *
 * \sa start(), stop(), isRunning(), runningChanged()
 */
void QScxmlStateMachine::setRunning(bool running)
{
    if (running)
        start();
    else
        stop();
}

QVariantMap QScxmlStateMachine::initialValues()
{
    Q_D(const QScxmlStateMachine);
    return d->m_initialValues;
}

void QScxmlStateMachine::setInitialValues(const QVariantMap &initialValues)
{
    Q_D(QScxmlStateMachine);
    if (initialValues != d->m_initialValues) {
        d->m_initialValues = initialValues;
        emit initialValuesChanged(initialValues);
    }
}

QString QScxmlStateMachine::name() const
{
    return tableData()->name();
}

/*!
    \qmlmethod ScxmlStateMachine::submitEvent(event)

    Submits the SCXML event \a event to the internal or external event queue
    depending on the priority of the event.

    When a delay is set, the event will be queued for delivery after the timeout
    has passed. The state machine takes ownership of the event and deletes it
    after processing.

    \sa QScxmlEvent
 */

/*!
 * Submits the SCXML event \a event to the internal or external event queue depending on the
 * priority of the event.
 *
 * When a delay is set, the event will be queued for delivery after the timeout has passed.
 * The state machine takes ownership of \a event and deletes it after processing.
 */
void QScxmlStateMachine::submitEvent(QScxmlEvent *event)
{
    Q_D(QScxmlStateMachine);

    if (!event)
        return;

    if (event->delay() > 0) {
        qCDebug(qscxmlLog) << this << "submitting event" << event->name()
                           << "with delay" << event->delay() << "ms:"
                           << QScxmlEventPrivate::debugString(event).constData();

        Q_ASSERT(event->eventType() == QScxmlEvent::ExternalEvent);
        d->submitDelayedEvent(event);
    } else {
        qCDebug(qscxmlLog) << this << "submitting event" << event->name()
                           << ":" << QScxmlEventPrivate::debugString(event).constData();

        d->routeEvent(event);
    }
}

/*!
 * A utility method to create and submit an external event with the specified
 * \a eventName as the name.
 */
void QScxmlStateMachine::submitEvent(const QString &eventName)
{
    QScxmlEvent *e = new QScxmlEvent;
    e->setName(eventName);
    e->setEventType(QScxmlEvent::ExternalEvent);
    submitEvent(e);
}
/*!
    \qmlmethod ScxmlStateMachine::submitEvent(string eventName, var data)

    A utility method to create and submit an external event with the specified
    \a eventName as the name and \a data as the payload data (optional).
*/

/*!
 * A utility method to create and submit an external event with the specified
 * \a eventName as the name and \a data as the payload data.
 */
void QScxmlStateMachine::submitEvent(const QString &eventName, const QVariant &data)
{
    QScxmlEvent *e = new QScxmlEvent;
    e->setName(eventName);
    e->setEventType(QScxmlEvent::ExternalEvent);
    e->setData(data);
    submitEvent(e);
}

/*!
    \qmlmethod ScxmlStateMachine::cancelDelayedEvent(string sendId)

    Cancels a delayed event with the specified \a sendId.
*/

/*!
 * Cancels a delayed event with the specified \a sendId.
 */
void QScxmlStateMachine::cancelDelayedEvent(const QString &sendId)
{
    Q_D(QScxmlStateMachine);

    for (auto it = d->m_delayedEvents.begin(), eit = d->m_delayedEvents.end(); it != eit; ++it) {
        if (it->second->sendId() == sendId) {
            qCDebug(qscxmlLog) << this
                               << "canceling event" << sendId
                               << "with timer id" << it->first;
            d->m_eventLoopHook.killTimer(it->first);
            delete it->second;
            d->m_delayedEvents.erase(it);
            return;
        }
    }
}

/*!
    \qmlmethod ScxmlStateMachine::isDispatchableTarget(string target)

    Returns \c true if a message to \a target can be dispatched by this state
    machine.

    Valid targets are:
    \list
    \li \c #_parent for the parent state machine if the current state machine
        is started by \c <invoke>
    \li \c #_internal for the current state machine
    \li \c #_scxml_sessionid, where \c sessionid is the session ID of the
        current state machine
    \li \c #_servicename, where \c servicename is the ID or name of a service
        started with \c <invoke> by this state machine
    \endlist
 */

/*!
 * Returns \c true if a message to \a target can be dispatched by this state machine.
 *
 * Valid targets are:
 * \list
 * \li  \c #_parent for the parent state machine if the current state machine is started by
 *      \c <invoke>
 * \li  \c #_internal for the current state machine
 * \li  \c #_scxml_sessionid, where \c sessionid is the session ID of the current state machine
 * \li  \c #_servicename, where \c servicename is the ID or name of a service started with
 *      \c <invoke> by this state machine
 * \endlist
 */
bool QScxmlStateMachine::isDispatchableTarget(const QString &target) const
{
    Q_D(const QScxmlStateMachine);

    if (isInvoked() && target == QStringLiteral("#_parent"))
        return true; // parent state machine, if we're <invoke>d.
    if (target == QStringLiteral("#_internal")
            || target == QStringLiteral("#_scxml_%1").arg(sessionId()))
        return true; // that's the current state machine

    if (target.startsWith(QStringLiteral("#_"))) {
        QStringRef targetId = target.midRef(2);
        for (auto invokedService : d->m_invokedServices) {
            if (invokedService.service && invokedService.service->id() == targetId)
                return true;
        }
    }

    return false;
}

/*!
    \qmlproperty list ScxmlStateMachine::invokedServices

    A list of SCXML services that were invoked from the main state machine
    (possibly recursively).
*/

/*!
    \property QScxmlStateMachine::invokedServices
    \brief A list of SCXML services that were invoked from the main
    state machine (possibly recursively).
*/

QVector<QScxmlInvokableService *> QScxmlStateMachine::invokedServices() const
{
    Q_D(const QScxmlStateMachine);

    QVector<QScxmlInvokableService *> result;
    for (int i = 0, ei = int(d->m_invokedServices.size()); i != ei; ++i) {
        if (auto service = d->m_invokedServices[size_t(i)].service)
            result.append(service);
    }
    return result;
}

/*!
  \fn QScxmlStateMachine::runningChanged(bool running)

  This signal is emitted when the \c running property is changed with \a running as argument.
*/

/*!
  \fn QScxmlStateMachine::log(const QString &label, const QString &msg)

  This signal is emitted if a \c <log> tag is used in the SCXML. \a label is the value of the
  \e label attribute of the \c <log> tag. \a msg is the value of the evaluated \e expr attribute
  of the \c <log> tag. If there is no \e expr attribute, a null string will be returned.
*/

/*!
    \qmlsignal ScxmlStateMachine::log(string label, string msg)

    This signal is emitted if a \c <log> tag is used in the SCXML. \a label is
    the value of the \e label attribute of the \c <log> tag. \a msg is the value
    of the evaluated \e expr attribute of the \c <log> tag. If there is no
    \e expr attribute, a null string will be returned.

    The corresponding signal handler is \c onLog().
*/

/*!
  \fn QScxmlStateMachine::reachedStableState()

  This signal is emitted when the event queue is empty at the end of a macro step or when a final
  state is reached.
*/

/*!
    \qmlsignal ScxmlStateMachine::reachedStableState()

    This signal is emitted when the event queue is empty at the end of a macro
    step or when a final state is reached.

    The corresponding signal handler is \c onreachedStableState().
*/

/*!
  \fn QScxmlStateMachine::finished()

  This signal is emitted when the state machine reaches a top-level final state.

  \sa running
*/

/*!
    \qmlsignal ScxmlStateMachine::finished()

    This signal is emitted when the state machine reaches a top-level final
    state.

    The corresponding signal handler is \c onFinished().
*/

/*!
    \qmlmethod ScxmlStateMachine::start()

    Starts this state machine. The machine resets its configuration and
    transitions to the initial state. When a final top-level state
    is entered, the machine emits the finished() signal.

    \sa stop(), finished()
*/

/*!
  Starts this state machine. The machine will reset its configuration and
  transition to the initial state. When a final top-level state
  is entered, the machine will emit the finished() signal.

  \note A state machine will not run without a running event loop, such as
  the main application event loop started with QCoreApplication::exec() or
  QApplication::exec().

  \sa runningChanged(), setRunning(), stop(), finished()
*/
void QScxmlStateMachine::start()
{
    Q_D(QScxmlStateMachine);

    if (!parseErrors().isEmpty())
        return;

    // Failure to initialize doesn't prevent start(). See w3c-ecma/test487 in the scion test suite.
    if (!isInitialized() && !init())
        qCDebug(qscxmlLog) << this << "cannot be initialized on start(). Starting anyway ...";

    d->start();
    d->m_eventLoopHook.queueProcessEvents();
}

/*!
    \qmlmethod ScxmlStateMachine::stop()

    Stops this state machine. The machine will not execute any further state
    transitions. Its \l running property is set to \c false.

    \sa start(), finished()
*/

/*!
  Stops this state machine. The machine will not execute any further state
  transitions. Its \c running property is set to \c false.

  \sa runningChanged(), start(), setRunning()
 */
void QScxmlStateMachine::stop()
{
    Q_D(QScxmlStateMachine);
    d->pause();
}

/*!
  Returns \c true if the state with the ID \a stateIndex is active.

  This method is part of the interface to the compiled representation of SCXML
  state machines. It should only be used internally and by state machines
  compiled from SCXML documents.
 */
bool QScxmlStateMachine::isActive(int stateIndex) const
{
    Q_D(const QScxmlStateMachine);
    return d->m_configuration.contains(stateIndex);
}

QT_END_NAMESPACE
