/****************************************************************************
**
** Copyright (C) 2007-2008 Trolltech ASA. All rights reserved.
**
** This file is part of the Qt Script Debug project on Trolltech Labs.
**
** This file may be used under the terms of the GNU General Public
** License version 2.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of
** this file.  Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
** http://www.trolltech.com/products/qt/opensource.html
**
** If you are unsure which license is appropriate for your use, please
** review the following information:
** http://www.trolltech.com/products/qt/licensing.html or contact the
** sales department at sales@trolltech.com.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/

#include "qscriptdebuggerfrontend.h"

#include "qscriptdebuggerfrontend_p.h"
#include "qscriptdebuggerclient.h"
#include "qscriptdebuggerclient_p.h"
#include "qscriptdebuggercommand.h"
#include "qscriptdebuggervalue.h"
#include "qscriptbreakpointinfo.h"
#include <QtCore/qcoreapplication.h>
#include <QtCore/qcoreevent.h>

Q_DECLARE_METATYPE(QScriptDebuggerValue)
Q_DECLARE_METATYPE(QScriptDebuggerValueList)
Q_DECLARE_METATYPE(QScriptBreakpointInfo)

/*!
  \class QScriptDebuggerFrontend

  \brief The QScriptDebuggerFrontend class is the base class of debugger front-ends.

  The class works asynchronously, so there are no blocking functions.
  Use the scheduleXXX functions to schedule commands for execution.
  The scheduling functions all return a unique identifier that allows
  you to keep track of commands that are being executed. Responses to
  issued commands, as well as debugging events (e.g. step
  notification) are delivered to the front-end's client. The client is
  set by calling the setClient() function.

  The QScriptDebuggerFrontend API does not provide direct access to
  the QScriptEngine being debugged. This is because the engine can be
  running in a separate process or on a remote machine. The
  QScriptDebuggerValue class is used to communicate script values
  between the front-end and the underlying engine.

  Commands can be divided into the folllowing major categories:

  \list

  \o Context commands. Used to query the script execution stack.
  Examples: scheduleGetContextCount(), scheduleGetContextInfo().

  \o Script commands. Used to query loaded scripts.
  Examples: scheduleListScripts(), scheduleGetScriptContents().

  \o Engine commands. Used to perform operations on the underlying
  script engine.
  Examples: scheduleEvaluate(), scheduleNewObject().

  \o Value commands. Used to perform operations on a script value.
  Examples: scheduleGetProperty(), scheduleToString().

  \o Iterator commands. Used to construct and perform operations on
  a script value iterator.
  Examples: scheduleNewIterator(), scheduleIteratorHasNext().

  \o Execution commands. Used to control script execution.
  Examples: scheduleContinue(), scheduleStepOver().

  \o Breakpoints commands. Used to manipulate breakpoints.
  Examples: scheduleSetBreakpoint(), scheduleDeleteBreakpoint().

  \endlist

  \section1 Subclassing

  When subclassing QScriptDebuggerFrontend, you must implement the
  pure virtual processCommand() function. This function is responsible
  for carrying out the given command, typically by forwarding it to a
  QScriptDebuggerBackend (see
  QScriptDebuggerBackend::applyCommand()). You should call the
  notifyCommandFinished() function when execution of the command is
  complete; this will ensure that the client() is notified. The
  notification is done asynchronously, e.g. notifyCommandFinished()
  will schedule a later execution of
  QScriptDebuggerClient::commandFinished().

  You should call the notifyEvent() function to notify the client() of
  events that are generated by the front-end back-end (step into, step
  over and so on). (See QScriptDebuggerBackend::event().)

  If you implement your own custom debugger commands, you can call
  scheduleCommand() to schedule them.
*/

QScriptDebuggerFrontendPrivate::QScriptDebuggerFrontendPrivate()
{
    client = 0;
    nextCommandId = 0;
}

QScriptDebuggerFrontendPrivate::~QScriptDebuggerFrontendPrivate()
{
}

bool QScriptDebuggerFrontendPrivate::event(QEvent *e)
{
    Q_Q(QScriptDebuggerFrontend);
    if (e->type() == QEvent::User+1) {
        // process commands
        while (!pendingCommands.isEmpty()) {
            QScriptDebuggerCommand command(pendingCommands.takeFirst());
            int id = pendingCommandIds.takeFirst();
            q->processCommand(id, command);
        }
        return true;
    }
    return false;
}

/*!
  Constructs a QScriptDebuggerFrontend object.
*/
QScriptDebuggerFrontend::QScriptDebuggerFrontend()
    : d_ptr(new QScriptDebuggerFrontendPrivate)
{
    d_ptr->q_ptr = this;
}

/*!
  \internal
*/
QScriptDebuggerFrontend::QScriptDebuggerFrontend(QScriptDebuggerFrontendPrivate &dd)
    : d_ptr(&dd)
{
    d_ptr->q_ptr = this;
}

/*!
  Destroys this QScriptDebuggerFrontend.
*/
QScriptDebuggerFrontend::~QScriptDebuggerFrontend()
{
    delete d_ptr;
    d_ptr = 0;
}

/*!
  Returns the client that is notified of command responses and events
  pertaining to this front-end, or 0 if there is no client.
*/
QScriptDebuggerClient *QScriptDebuggerFrontend::client() const
{
    Q_D(const QScriptDebuggerFrontend);
    return d->client;
}

/*!
  Sets the \a client that will be notified of events and command
  completion pertaining to this front-end.

  The front-end does not take ownership of the client.
*/
void QScriptDebuggerFrontend::setClient(QScriptDebuggerClient *client)
{
    Q_D(QScriptDebuggerFrontend);
    d->client = client;
}

/*!
  Subclasses should call this function when the command identified by
  the given \a id has finished and produced the given \a response.

  \sa processCommand(), notifyEvent()
*/
void QScriptDebuggerFrontend::notifyCommandFinished(int id, const QScriptDebuggerResponse &response)
{
    Q_D(QScriptDebuggerFrontend);
    if (d->client) {
        QScriptDebuggerClientPrivate *client_p = QScriptDebuggerClientPrivate::get(d->client);
        client_p->postCommandFinished(id, response);
    }
}

/*!
  Subclasses should call this function when the given \a event is
  received from the back-end.

  \sa notifyCommandFinished(), QScriptDebuggerBackend::event()
*/
void QScriptDebuggerFrontend::notifyEvent(const QScriptDebuggerEvent &event)
{
    Q_D(QScriptDebuggerFrontend);
    if (d->client) {
        QScriptDebuggerClientPrivate *client_p = QScriptDebuggerClientPrivate::get(d->client);
        client_p->postEvent(event);
    }
}

/*!
  Schedules the given \a command for execution by this front-end,
  and returns a unique identifier associated with this command.

  Subclasses can call this function to schedule custom commands.

  \sa notifyCommandFinished()
*/
int QScriptDebuggerFrontend::scheduleCommand(const QScriptDebuggerCommand &command)
{
    Q_D(QScriptDebuggerFrontend);
    int id = ++d->nextCommandId;
    d->pendingCommands.append(command);
    d->pendingCommandIds.append(id);
    if (d->pendingCommands.size() == 1) {
        QEvent *e = new QEvent(QEvent::Type(QEvent::User+1));
        QCoreApplication::postEvent(d, e);
    }
    return id;
}

/*!
  Instructs the front-end to obtain the number of active contexts
  (frames), and returns a unique identifier associated with this
  command.
*/
int QScriptDebuggerFrontend::scheduleGetContextCount()
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::GetContextCount);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to obtain a QScriptContextInfo describing the
  context at the given \a index, and returns a unique identifier
  associated with this command.
*/
int QScriptDebuggerFrontend::scheduleGetContextInfo(int index)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::GetContextInfo);
    cmd.setAttribute(QScriptDebuggerCommand::ContextIndex, index);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to obtain a list of QScriptContextInfo
  objects describing the contexts (frames), and returns a unique
  identifier associated with this command..
*/
int QScriptDebuggerFrontend::scheduleGetContextInfos()
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::GetContextInfos);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to obtain the string representation of the
  context at the given \a index, and returns a unique identifier
  associated with this command.
*/
int QScriptDebuggerFrontend::scheduleGetContextString(int index)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::GetContextString);
    cmd.setAttribute(QScriptDebuggerCommand::ContextIndex, index);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to obtain the id of the script associated
  with the context at the given \a contextIndex, and returns a unique
  identifier associated with this command.
*/
int QScriptDebuggerFrontend::scheduleGetScriptId(int contextIndex)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::GetScriptID);
    cmd.setAttribute(QScriptDebuggerCommand::ContextIndex, contextIndex);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to obtain the backtrace of the context at the
  given \a contextIndex, and returns a unique identifier associated
  with this command.

  \sa QScriptContext::backtrace()
*/
int QScriptDebuggerFrontend::scheduleGetBacktrace(int contextIndex)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::GetBacktrace);
    cmd.setAttribute(QScriptDebuggerCommand::ContextIndex, contextIndex);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to obtain the this object of the context at
  the given \a contextIndex, and returns a unique identifier
  associated with this command.

  \sa QScriptContext::thisObject()
*/
int QScriptDebuggerFrontend::scheduleGetThisObject(int contextIndex)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::GetThisObject);
    cmd.setAttribute(QScriptDebuggerCommand::ContextIndex, contextIndex);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to set the this object of the context at the
  given \a contextIndex to the given \a object, and returns a unique
  identifier associated with this command.

  \sa QScriptContext::setThisObject()
*/
int QScriptDebuggerFrontend::scheduleSetThisObject(int contextIndex,
                                                   const QScriptDebuggerValue &object)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::SetThisObject);
    cmd.setAttribute(QScriptDebuggerCommand::ContextIndex, contextIndex);
    cmd.setAttribute(QScriptDebuggerCommand::Value, qVariantFromValue(object));
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to obtain the activation object of the
  context at the given \a contextIndex, and returns a unique
  identifier associated with this command.

  \sa QScriptContext::activationObject()
*/
int QScriptDebuggerFrontend::scheduleGetActivationObject(int contextIndex)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::GetActivationObject);
    cmd.setAttribute(QScriptDebuggerCommand::ContextIndex, contextIndex);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to set the activation object of the context
  at the given \a contextIndex to the given \a object, and returns a
  unique identifier associated with this command.

  \sa QScriptContext::setActivationObject()
*/
int QScriptDebuggerFrontend::scheduleSetActivationObject(int contextIndex,
                                                         const QScriptDebuggerValue &object)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::SetActivationObject);
    cmd.setAttribute(QScriptDebuggerCommand::ContextIndex, contextIndex);
    cmd.setAttribute(QScriptDebuggerCommand::Value, qVariantFromValue(object));
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to obtain the scope chain of the context at
  the given \a contextIndex, and returns a unique identifier
  associated with this command.
*/
int QScriptDebuggerFrontend::scheduleGetScopeChain(int contextIndex)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::GetScopeChain);
    cmd.setAttribute(QScriptDebuggerCommand::ContextIndex, contextIndex);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to obtain the arguments object of the context
  at the given \a contextIndex, and returns a unique identifier
  associated with this command.

  \sa QScriptContext::argumentsObject()
*/
int QScriptDebuggerFrontend::scheduleGetArgumentsObject(int contextIndex)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::GetArgumentsObject);
    cmd.setAttribute(QScriptDebuggerCommand::ContextIndex, contextIndex);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to obtain the argument count of the context
  at the given \a contextIndex, and returns a unique identifier
  associated with this command.

  \sa QScriptContext::argumentCount()
*/
int QScriptDebuggerFrontend::scheduleGetArgumentCount(int contextIndex)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::GetArgumentCount);
    cmd.setAttribute(QScriptDebuggerCommand::ContextIndex, contextIndex);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to obtain the argument at the given \a
  argIndex of the context at the given \a contextIndex, and returns a
  unique identifier associated with this command.

  \sa QScriptContext::argument()
*/
int QScriptDebuggerFrontend::scheduleGetArgument(int contextIndex, int argIndex)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::GetArgument);
    cmd.setAttribute(QScriptDebuggerCommand::ContextIndex, contextIndex);
    cmd.setAttribute(QScriptDebuggerCommand::ArgumentIndex, argIndex);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to obtain a list of arguments of the context
  at the given \a contextIndex, and returns a unique identifier
  associated with this command.
*/
int QScriptDebuggerFrontend::scheduleGetArguments(int contextIndex)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::GetArguments);
    cmd.setAttribute(QScriptDebuggerCommand::ContextIndex, contextIndex);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to obtain the callee of the context at the
  given \a contextIndex, and returns a unique identifier associated
  with this command.

  \sa QScriptContext::callee()
*/
int QScriptDebuggerFrontend::scheduleGetCallee(int contextIndex)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::GetCallee);
    cmd.setAttribute(QScriptDebuggerCommand::ContextIndex, contextIndex);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to obtain whether the callee of the context
  at the given \a contextIndex was called as a constructor, and
  returns a unique identifier associated with this command.

  \sa QScriptContext::isCalledAsConstructor()
*/
int QScriptDebuggerFrontend::scheduleIsCalledAsConstructor(int contextIndex)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::IsCalledAsConstructor);
    cmd.setAttribute(QScriptDebuggerCommand::ContextIndex, contextIndex);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to obtain the contents of the script
  identified by \a scriptId, and returns a unique identifier
  associated with this command.
*/
int QScriptDebuggerFrontend::scheduleGetScriptContents(qint64 scriptId)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::GetScriptContents);
    cmd.setAttribute(QScriptDebuggerCommand::ScriptID, scriptId);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to obtain \a count number of lines starting
  at \a lineNumber of the script identified by \a scriptId, and
  returns a unique identifier associated with this command.
*/
int QScriptDebuggerFrontend::scheduleGetScriptLines(qint64 scriptId, int lineNumber, int count)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::GetScriptLines);
    cmd.setAttribute(QScriptDebuggerCommand::ScriptID, scriptId);
    cmd.setAttribute(QScriptDebuggerCommand::LineNumber, lineNumber);
    cmd.setAttribute(QScriptDebuggerCommand::Count, count);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to break at the next script statement, and
  returns a unique identifier associated with this command.

  When the next script statement is encountered, the client will be
  notified, and the front-end will be ready to accept commands.

  \sa scheduleContinue()
*/
int QScriptDebuggerFrontend::scheduleBreak()
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::Break);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to check whether the given \a program can be
  evaluated by the front-end back-end, and returns a unique identifier
  associated with this command.

  \sa QScriptEngine::canEvaluate()
*/
int QScriptDebuggerFrontend::scheduleCanEvaluate(const QString &program)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::CanEvaluate);
    cmd.setAttribute(QScriptDebuggerCommand::Program, program);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to evaluate the given \a program, and returns
  a unique identifier associated with this command.

  \sa QScriptEngine::evaluate()
*/
int QScriptDebuggerFrontend::scheduleEvaluate(const QString &program,
                                              const QString &fileName,
                                              int lineNumber)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::Evaluate);
    cmd.setAttribute(QScriptDebuggerCommand::Program, program);
    cmd.setAttribute(QScriptDebuggerCommand::FileName, fileName);
    cmd.setAttribute(QScriptDebuggerCommand::LineNumber, lineNumber);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to abort the current evaluation with the
  given \a result, and returns a unique identifier associated with
  this command.

  \sa QScriptEngine::abortEvaluation()
*/
int QScriptDebuggerFrontend::scheduleAbortEvaluation(const QScriptDebuggerValue &result)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::AbortEvaluation);
    cmd.setAttribute(QScriptDebuggerCommand::Value, qVariantFromValue(result));
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to clear exceptions in the target engine, and
  returns a unique identifier associated with this command.

  \sa QScriptEngine::clearExceptions()
*/
int QScriptDebuggerFrontend::scheduleClearExceptions()
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::ClearExceptions);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to collect garbage in the target engine, and
  returns a unique identifier associated with this command.

  \sa QScriptEngine::collectGarbage()
*/
int QScriptDebuggerFrontend::scheduleCollectGarbage()
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::CollectGarbage);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to obtain the Global Object of the target
  engine, and returns a unique identifier associated with this
  command.

  \sa QScriptEngine::globalObject()
*/
int QScriptDebuggerFrontend::scheduleGetGlobalObject()
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::GetGlobalObject);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to create a new array object with the given
  \a length in the target engine, and returns a unique identifier
  associated with this command.

  \sa QScriptEngine::newArray()
*/
int QScriptDebuggerFrontend::scheduleNewArray(uint length)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::NewArray);
    cmd.setAttribute(QScriptDebuggerCommand::Length, length);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to create a new script object in the target
  engine, and returns a unique identifier associated with this
  command.

  \sa QScriptEngine::newObject()
*/
int QScriptDebuggerFrontend::scheduleNewObject()
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::NewObject);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to push a new context in the target engine,
  and returns a unique identifier associated with this command.

  \sa QScriptEngine::pushContext()
*/
int QScriptDebuggerFrontend::schedulePushContext()
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::PushContext);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to pop a context in the target engine, and
  returns a unique identifier associated with this command.

  \sa QScriptEngine::popContext()
*/
int QScriptDebuggerFrontend::schedulePopContext()
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::PopContext);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to obtain whether target engine's has an
  uncaught exception, and returns a unique identifier associated with
  this command.

  \sa QScriptEngine::hasUncaughtException()
*/
int QScriptDebuggerFrontend::scheduleHasUncaughtException()
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::HasUncaughtException);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to obtain the target engine's uncaught
  exception, and returns a unique identifier associated with this
  command.

  \sa QScriptEngine::uncaughtException()
*/
int QScriptDebuggerFrontend::scheduleGetUncaughtException()
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::GetUncaughtException);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to obtain the line number of the last
  uncaught exception in the target engine, and returns a unique
  identifier associated with this command.

  \sa QScriptEngine::uncaughtExceptionLineNumber()
*/
int QScriptDebuggerFrontend::scheduleGetUncaughtExceptionLineNumber()
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::GetUncaughtExceptionLineNumber);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to obtain the backtrace of the
  uncaught exception in the target engine, and returns a unique
  identifier associated with this command.

  \sa QScriptEngine::uncaughtExceptionBacktrace()
*/
int QScriptDebuggerFrontend::scheduleGetUncaughtExceptionBacktrace()
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::GetUncaughtExceptionBacktrace);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to call the given \a function using the given
  \a thisObject and passing the given \a arguments, and returns a
  unique identifier associated with this command.

  \sa QScriptValue::call()
*/
int QScriptDebuggerFrontend::scheduleCall(const QScriptDebuggerValue &function,
                                          const QScriptDebuggerValue &thisObject,
                                          const QScriptDebuggerValueList &arguments)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::Call);
    cmd.setAttribute(QScriptDebuggerCommand::FunctionObject, qVariantFromValue(function));
    cmd.setAttribute(QScriptDebuggerCommand::ThisObject, qVariantFromValue(thisObject));
    cmd.setAttribute(QScriptDebuggerCommand::FunctionArguments, qVariantFromValue(arguments));
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to call the given \a function as a
  constructor and passing the given \a arguments, and returns a unique
  identifier associated with this command.

  \sa QScriptValue::construct()
*/
int QScriptDebuggerFrontend::scheduleConstruct(const QScriptDebuggerValue &function,
                                               const QScriptDebuggerValueList &arguments)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::Construct);
    cmd.setAttribute(QScriptDebuggerCommand::FunctionObject, qVariantFromValue(function));
    cmd.setAttribute(QScriptDebuggerCommand::FunctionArguments, qVariantFromValue(arguments));
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to get the property with the given \a
  propertyName of the given \a object, and returns a unique identifier
  associated with this command.

  \sa QScriptValue::property()
*/
int QScriptDebuggerFrontend::scheduleGetProperty(const QScriptDebuggerValue &object,
                                                 const QString &propertyName)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::GetProperty);
    cmd.setAttribute(QScriptDebuggerCommand::Object, qVariantFromValue(object));
    cmd.setAttribute(QScriptDebuggerCommand::PropertyName, propertyName);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to set the property with the given \a
  propertyName of the given \a object to the given \a value, and
  returns a unique identifier associated with this command.

  \sa QScriptValue::setProperty()
*/
int QScriptDebuggerFrontend::scheduleSetProperty(const QScriptDebuggerValue &object,
                                                 const QString &propertyName,
                                                 const QScriptDebuggerValue &value)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::SetProperty);
    cmd.setAttribute(QScriptDebuggerCommand::Object, qVariantFromValue(object));
    cmd.setAttribute(QScriptDebuggerCommand::PropertyName, propertyName);
    cmd.setAttribute(QScriptDebuggerCommand::Value, qVariantFromValue(value));
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to get the flags of the property with the
  given \a propertyName of the given \a object, and returns a unique
  identifier associated with this command.

  \sa QScriptValue::propertyFlags()
*/
int QScriptDebuggerFrontend::scheduleGetPropertyFlags(const QScriptDebuggerValue &object,
                                                      const QString &propertyName)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::GetPropertyFlags);
    cmd.setAttribute(QScriptDebuggerCommand::Object, qVariantFromValue(object));
    cmd.setAttribute(QScriptDebuggerCommand::PropertyName, propertyName);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to get the names of the properties of the
  given \a object, and returns a unique identifier associated with
  this command.
*/
int QScriptDebuggerFrontend::scheduleGetPropertyNames(const QScriptDebuggerValue &object)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::GetPropertyNames);
    cmd.setAttribute(QScriptDebuggerCommand::Object, qVariantFromValue(object));
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to get the properties named by \a
  propertyNames of the given \a object, and returns a unique
  identifier associated with this command.
*/
int QScriptDebuggerFrontend::scheduleGetProperties(const QScriptDebuggerValue &object,
                                                   const QStringList &propertyNames)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::GetProperties);
    cmd.setAttribute(QScriptDebuggerCommand::Object, qVariantFromValue(object));
    cmd.setAttribute(QScriptDebuggerCommand::PropertyNames, propertyNames);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to get the prototype of the given \a object,
  and returns a unique identifier associated with this command.

  \sa QScriptValue::prototype()
*/
int QScriptDebuggerFrontend::scheduleGetPrototype(const QScriptDebuggerValue &object)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::GetPrototype);
    cmd.setAttribute(QScriptDebuggerCommand::Object, qVariantFromValue(object));
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to set the \a prototype of the given \a
  object, and returns a unique identifier associated with this
  command.

  \sa QScriptValue::setPrototype()
*/
int QScriptDebuggerFrontend::scheduleSetPrototype(const QScriptDebuggerValue &object,
                                                  const QScriptDebuggerValue &prototype)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::SetPrototype);
    cmd.setAttribute(QScriptDebuggerCommand::Object, qVariantFromValue(object));
    cmd.setAttribute(QScriptDebuggerCommand::Value, qVariantFromValue(prototype));
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to convert the given \a value to a boolean,
  and returns a unique identifier associated with this command.

  \sa QScriptValue::toBoolean()
*/
int QScriptDebuggerFrontend::scheduleToBoolean(const QScriptDebuggerValue &value)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::ToBoolean);
    cmd.setAttribute(QScriptDebuggerCommand::Value, qVariantFromValue(value));
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to convert the given \a value to a QDateTime,
  and returns a unique identifier associated with this command.

  \sa QScriptValue::toDateTime()
*/
int QScriptDebuggerFrontend::scheduleToDateTime(const QScriptDebuggerValue &value)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::ToDateTime);
    cmd.setAttribute(QScriptDebuggerCommand::Value, qVariantFromValue(value));
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to convert the given \a value to a number,
  and returns a unique identifier associated with this command.

  \sa QScriptValue::toNumber()
*/
int QScriptDebuggerFrontend::scheduleToNumber(const QScriptDebuggerValue &value)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::ToNumber);
    cmd.setAttribute(QScriptDebuggerCommand::Value, qVariantFromValue(value));
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to convert the given \a value to an object,
  and returns a unique identifier associated with this command.

  \sa QScriptValue::toObject()
*/
int QScriptDebuggerFrontend::scheduleToObject(const QScriptDebuggerValue &value)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::ToObject);
    cmd.setAttribute(QScriptDebuggerCommand::Value, qVariantFromValue(value));
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to convert the given \a value to a QRegExp,
  and returns a unique identifier associated with this command.

  \sa QScriptValue::toRegExp()
*/
int QScriptDebuggerFrontend::scheduleToRegExp(const QScriptDebuggerValue &value)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::ToRegExp);
    cmd.setAttribute(QScriptDebuggerCommand::Value, qVariantFromValue(value));
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to convert the given \a value to a string,
  and returns a unique identifier associated with this command.

  \sa QScriptValue::toString()
*/
int QScriptDebuggerFrontend::scheduleToString(const QScriptDebuggerValue &value)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::ToString);
    cmd.setAttribute(QScriptDebuggerCommand::Value, qVariantFromValue(value));
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to create a new iterator for the given \a object,
  and returns a unique identifier associated with this command.

  \sa QScriptValueIterator
*/
int QScriptDebuggerFrontend::scheduleNewIterator(const QScriptDebuggerValue &object)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::NewIterator);
    cmd.setAttribute(QScriptDebuggerCommand::Object, qVariantFromValue(object));
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to fetch the flags of the last property that
  was jumped over in the iterator identified by the given \a id, and
  returns a unique identifier associated with this command.

  \sa QScriptValueIterator::flags()
*/
int QScriptDebuggerFrontend::scheduleIteratorFlags(int id)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::IteratorFlags);
    cmd.setAttribute(QScriptDebuggerCommand::IteratorID, id);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to check whether the iterator identified by
  the given \a id has a next property, and returns a unique identifier
  associated with this command.

  \sa QScriptValueIterator::hasNext()
*/
int QScriptDebuggerFrontend::scheduleIteratorHasNext(int id)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::IteratorHasNext);
    cmd.setAttribute(QScriptDebuggerCommand::IteratorID, id);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to check whether the iterator identified by
  the given \a id has a previous property, and returns a unique
  identifier associated with this command.

  \sa QScriptValueIterator::hasPrevious()
*/
int QScriptDebuggerFrontend::scheduleIteratorHasPrevious(int id)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::IteratorHasPrevious);
    cmd.setAttribute(QScriptDebuggerCommand::IteratorID, id);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to obtain the name of the last property that
  was jumped over in the iterator identified by the given \a id, and
  returns a unique identifier associated with this command.

  \sa QScriptValueIterator::name()
*/
int QScriptDebuggerFrontend::scheduleIteratorName(int id)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::IteratorName);
    cmd.setAttribute(QScriptDebuggerCommand::IteratorID, id);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to advance the iterator identified by the
  given \a id by one position, and returns a unique identifier
  associated with this command.

  \sa QScriptValueIterator::next()
*/
int QScriptDebuggerFrontend::scheduleIteratorNext(int id)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::IteratorNext);
    cmd.setAttribute(QScriptDebuggerCommand::IteratorID, id);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to advance the iterator identified by the
  given \a id by one position, and returns a unique identifier
  associated with this command.

  \sa QScriptValueIterator::previous()
*/
int QScriptDebuggerFrontend::scheduleIteratorPrevious(int id)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::IteratorPrevious);
    cmd.setAttribute(QScriptDebuggerCommand::IteratorID, id);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to remove the last property that was jumped
  over in the iterator identified by the given \a id, and returns a
  unique identifier associated with this command.

  \sa QScriptValueIterator::remove()
*/
int QScriptDebuggerFrontend::scheduleIteratorRemove(int id)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::IteratorRemove);
    cmd.setAttribute(QScriptDebuggerCommand::IteratorID, id);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to set the \a value of the last property that
  was jumped over in the iterator identified by the given \a id, and
  returns a unique identifier associated with this command.

  \sa QScriptValueIterator::setValue()
*/
int QScriptDebuggerFrontend::scheduleIteratorSetValue(int id, const QScriptDebuggerValue &value)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::IteratorSetValue);
    cmd.setAttribute(QScriptDebuggerCommand::IteratorID, id);
    cmd.setAttribute(QScriptDebuggerCommand::Value, qVariantFromValue(value));
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to move the iterator identified by the given
  \a id to the back, and returns a unique identifier associated with
  this command.

  \sa QScriptValueIterator::toBack()
*/
int QScriptDebuggerFrontend::scheduleIteratorToBack(int id)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::IteratorToBack);
    cmd.setAttribute(QScriptDebuggerCommand::IteratorID, id);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to move the iterator identified by the given
  \a id to the front, and returns a unique identifier associated with
  this command.

  \sa QScriptValueIterator::toFront()
*/
int QScriptDebuggerFrontend::scheduleIteratorToFront(int id)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::IteratorToFront);
    cmd.setAttribute(QScriptDebuggerCommand::IteratorID, id);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to obtain the value of the last property that
  was jumped over in the iterator identified by the given \a id, and
  returns a unique identifier associated with this command.

  \sa QScriptValueIterator::value()
*/
int QScriptDebuggerFrontend::scheduleIteratorValue(int id)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::IteratorValue);
    cmd.setAttribute(QScriptDebuggerCommand::IteratorID, id);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to make the iterator identified by the given
  \a id operate on the given \a object, and returns a unique
  identifier associated with this command.

  \sa QScriptValueIterator::operator=()
*/
int QScriptDebuggerFrontend::scheduleIteratorAssign(int id, const QScriptDebuggerValue &object)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::IteratorAssign);
    cmd.setAttribute(QScriptDebuggerCommand::IteratorID, id);
    cmd.setAttribute(QScriptDebuggerCommand::Object, qVariantFromValue(object));
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to obtain a QScriptDebuggerProperty that
  describes the last property that was jumped over in the iterator
  identified by the given \a id, and returns a unique identifier
  associated with this command.
*/
int QScriptDebuggerFrontend::scheduleIteratorProperty(int id)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::IteratorProperty);
    cmd.setAttribute(QScriptDebuggerCommand::IteratorID, id);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to advance the iterator identified by the
  given \a id and obtain a QScriptDebuggerProperty that describes the
  property that was jumped over, and returns a unique identifier
  associated with this command.
*/
int QScriptDebuggerFrontend::scheduleIteratorNextProperty(int id)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::IteratorNextProperty);
    cmd.setAttribute(QScriptDebuggerCommand::IteratorID, id);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to obtain at most \a maxCount properties of
  the iterator identified by the given \a id, and returns a unique
  identifier associated with this command.
*/
int QScriptDebuggerFrontend::scheduleIteratorNextProperties(int id, int maxCount)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::IteratorNextProperties);
    cmd.setAttribute(QScriptDebuggerCommand::IteratorID, id);
    cmd.setAttribute(QScriptDebuggerCommand::Count, maxCount);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to destroy the iterator identified by the
  given \a id, and returns a unique identifier associated with this
  command.

  \sa QScriptValueIterator::operator=()
*/
int QScriptDebuggerFrontend::scheduleDeleteIterator(int id)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::DeleteIterator);
    cmd.setAttribute(QScriptDebuggerCommand::IteratorID, id);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to continue evaluation, and returns a unique
  identifier associated with this command.

  \sa scheduleBreak()
*/
int QScriptDebuggerFrontend::scheduleContinue()
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::Continue);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to step into the next script statement, and
  returns a unique identifier associated with this command.

  Evaluation will automatically be continued, and the client()'s event()
  function will be called when the statement has been stepped into.
*/
int QScriptDebuggerFrontend::scheduleStepInto()
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::StepInto);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to step over the next script statement, and
  returns a unique identifier associated with this command.

  Evaluation will automatically be continued, and the client()'s event()
  function will be called when the statement has been stepped over.
*/
int QScriptDebuggerFrontend::scheduleStepOver()
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::StepOver);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to step out of the current script function, and
  returns a unique identifier associated with this command.

  Evaluation will automatically be continued, and the client()'s
  event() function will be called when the script function has been
  stepped out of.
*/
int QScriptDebuggerFrontend::scheduleStepOut()
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::StepOut);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to continue evaluation until the location
  specified by the given \a fileName and \a lineNumber is reached.
*/
int QScriptDebuggerFrontend::scheduleRunToLocation(const QString &fileName, int lineNumber)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::RunToLocation);
    cmd.setAttribute(QScriptDebuggerCommand::FileName, fileName);
    cmd.setAttribute(QScriptDebuggerCommand::LineNumber, lineNumber);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to continue evaluation until the location
  specified by the given \a scriptId and \a lineNumber is reached.
*/
int QScriptDebuggerFrontend::scheduleRunToLocation(qint64 scriptId, int lineNumber)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::RunToLocationByID);
    cmd.setAttribute(QScriptDebuggerCommand::ScriptID, scriptId);
    cmd.setAttribute(QScriptDebuggerCommand::LineNumber, lineNumber);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to resume execution in whatever state the
  back-end is currently in.
*/
int QScriptDebuggerFrontend::scheduleResume()
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::Resume);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to set a breakpoint at the location specified
  by the given \a fileName and \a lineNumber, and returns a unique
  identifier associated with this command.
*/
int QScriptDebuggerFrontend::scheduleSetBreakpoint(const QString &fileName, int lineNumber)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::SetBreakpoint);
    cmd.setAttribute(QScriptDebuggerCommand::FileName, fileName);
    cmd.setAttribute(QScriptDebuggerCommand::LineNumber, lineNumber);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to set a breakpoint at the location specified
  by the given \a scriptId and \a lineNumber, and returns a unique
  identifier associated with this command.
*/
int QScriptDebuggerFrontend::scheduleSetBreakpoint(qint64 scriptId, int lineNumber)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::SetBreakpointByScriptID);
    cmd.setAttribute(QScriptDebuggerCommand::ScriptID, scriptId);
    cmd.setAttribute(QScriptDebuggerCommand::LineNumber, lineNumber);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to delete the breakpoint identified by the
  given \a id, and returns a unique identifier associated with this
  command.
*/
int QScriptDebuggerFrontend::scheduleDeleteBreakpoint(int id)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::DeleteBreakpoint);
    cmd.setAttribute(QScriptDebuggerCommand::BreakpointID, id);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to delete all breakpoints, and returns a
  unique identifier associated with this command.
*/
int QScriptDebuggerFrontend::scheduleDeleteAllBreakpoints()
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::DeleteAllBreakpoints);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to obtain the list of breakpoint identifiers,
  and returns a unique identifier associated with this command.
*/
int QScriptDebuggerFrontend::scheduleGetBreakpointIdentifiers()
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::GetBreakpointIdentifiers);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to obtain the information associated with the
  breakpoint identified by the given \a id, and returns a unique
  identifier associated with this command.
*/
int QScriptDebuggerFrontend::scheduleGetBreakpointInfo(int id)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::GetBreakpointInfo);
    cmd.setAttribute(QScriptDebuggerCommand::BreakpointID, id);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to obtain the information associated with the
  breakpoint identified by the given \a id, and returns a unique
  identifier associated with this command.
*/
int QScriptDebuggerFrontend::scheduleModifyBreakpoint(int id, const QScriptBreakpointInfo &info)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::ModifyBreakpoint);
    cmd.setAttribute(QScriptDebuggerCommand::BreakpointID, id);
    cmd.setAttribute(QScriptDebuggerCommand::BreakpointInfo, qVariantFromValue(info));
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to set the enabled state of the breakpoint
  identified by the given \a id to \a enabled, and returns a unique
  identifier associated with this command.
*/
int QScriptDebuggerFrontend::scheduleSetBreakpointEnabled(int id, bool enabled)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::SetBreakpointEnabled);
    cmd.setAttribute(QScriptDebuggerCommand::BreakpointID, id);
    cmd.setAttribute(QScriptDebuggerCommand::Enabled, enabled);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to list the scripts that are currently loaded,
  and returns a unique identifier associated with this command.
*/
int QScriptDebuggerFrontend::scheduleListScripts(bool includeScriptContents)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::ListScripts);
    cmd.setAttribute(QScriptDebuggerCommand::IncludeScriptContents, includeScriptContents);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to do a scripts checkpoint, and returns a unique
  identifier associated with this command.

  \sa scheduleGetScriptsDelta()
*/
int QScriptDebuggerFrontend::scheduleScriptsCheckpoint()
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::ScriptsCheckpoint);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to obtain the difference between the scripts
  of the last checkpoint and the previous checkpoint, and returns a
  unique identifier associated with this command.

  \sa scheduleScriptsCheckpoint()
*/
int QScriptDebuggerFrontend::scheduleGetScriptsDelta(bool includeScriptContents)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::GetScriptsDelta);
    cmd.setAttribute(QScriptDebuggerCommand::IncludeScriptContents, includeScriptContents);
    return scheduleCommand(cmd);
}

/*!
  Instructs the front-end to do a scripts checkpoint and obtain the
  difference between the new checkpoint checkpoint and the previous
  one, and returns a unique identifier associated with this command.

  This command effectively combines scheduleScriptsCheckpoint() and
  scheduleGetScriptsDelta().
*/
int QScriptDebuggerFrontend::scheduleScriptsCheckpointAndDelta(bool includeScriptContents)
{
    QScriptDebuggerCommand cmd(QScriptDebuggerCommand::ScriptsCheckpointAndDelta);
    cmd.setAttribute(QScriptDebuggerCommand::IncludeScriptContents, includeScriptContents);
    return scheduleCommand(cmd);
}

/*!
  \fn void QScriptDebuggerFrontend::processCommand(int id, const QScriptDebuggerCommand &command)

  Processes the given debugger \a command.

  Subclasses must reimplement this function to carry out debugger
  commands. This function typically forwards the command to a
  QScriptDebuggerBackend. Call the notifyCommandFinished() function
  when execution of the command has finished.

  \sa QScriptDebuggerBackend::applyCommand()
*/
