void NSFTraceLog::addTrace(const NSFString& type, const NSFString& tag1, const NSFString& data1, const NSFString& tag2, const NSFString& data2, const NSFString& tag3, const NSFString& data3)
    {
        // If logging is not enabled, then return without action
        if (!enabled)
        {
            return;
        }

        NSFXMLElement* trace = NULL;

        try
        {
            // Lock to prevent events from being added to the queue with timestamps out of order
            LOCK(traceLogMutex)
            {
                // Create the new trace element
                trace = new NSFXMLElement(TraceTag());

                // Add the time
                trace->addChildElementBack(new NSFXMLElement(TimeTag(), toString(NSFTimerThread::getPrimaryTimerThread().getCurrentTime())));

                // Add a trace for the type
                NSFXMLElement* typeTrace = new NSFXMLElement(type);
                trace->addChildElementBack(typeTrace);

                // Add the new data under the type element;
                typeTrace->addChildElementBack(new NSFXMLElement(tag1, data1));

                if (!tag2.empty()) typeTrace->addChildElementBack(new NSFXMLElement(tag2, data2));
                if (!tag3.empty()) typeTrace->addChildElementBack(new NSFXMLElement(tag3, data3));

                eventHandler.queueEvent(traceAddEvent.copy(true, trace));
            }
            ENDLOCK;
        }
        catch(...)
        {
            // If unable to add a trace, just do nothing, because calling the exception handler may result in an infinite loop
            delete trace;
        }
    }
 TimerResolutionTest::TimerResolutionTest(const NSFString& name)
     : name(name.c_str())
 {
 }
 DocumentLoadTest::DocumentLoadTest(const NSFString& name, const NSFString& fileName)
     :name(name.c_str()), fileName(fileName.c_str())
 {
 }
 StateMachineDeleteTest::StateMachineDeleteTest(const NSFString& name)
     : name(name.c_str())
 {
 }
 TimerAccuracyTest::TimerAccuracyTest(const NSFString& name)
     : name(name.c_str()), eventHandler(name, new NSFEventThread(name)), testEvent(name, &eventHandler),
     lastTime(0), maxDeltaTime(0), minDeltaTime(LONG_MAX)
 {
     eventHandler.startEventHandler();
 }