changeset 563:dfc88a1018d9

Add UnitTest++ source code into ITW, without integration.
author Adam Domurad <adomurad@redhat.com>
date Wed, 21 Nov 2012 12:37:38 -0500
parents b28386115aae
children c7b7bd6fffb3
files ChangeLog tests/UnitTest++/COPYING tests/UnitTest++/Makefile tests/UnitTest++/README tests/UnitTest++/src/AssertException.cpp tests/UnitTest++/src/AssertException.h tests/UnitTest++/src/CheckMacros.h tests/UnitTest++/src/Checks.cpp tests/UnitTest++/src/Checks.h tests/UnitTest++/src/Config.h tests/UnitTest++/src/CurrentTest.cpp tests/UnitTest++/src/CurrentTest.h tests/UnitTest++/src/DeferredTestReporter.cpp tests/UnitTest++/src/DeferredTestReporter.h tests/UnitTest++/src/DeferredTestResult.cpp tests/UnitTest++/src/DeferredTestResult.h tests/UnitTest++/src/ExecuteTest.h tests/UnitTest++/src/MemoryOutStream.cpp tests/UnitTest++/src/MemoryOutStream.h tests/UnitTest++/src/Posix/SignalTranslator.cpp tests/UnitTest++/src/Posix/SignalTranslator.h tests/UnitTest++/src/Posix/TimeHelpers.cpp tests/UnitTest++/src/Posix/TimeHelpers.h tests/UnitTest++/src/ReportAssert.cpp tests/UnitTest++/src/ReportAssert.h tests/UnitTest++/src/Test.cpp tests/UnitTest++/src/Test.h tests/UnitTest++/src/TestDetails.cpp tests/UnitTest++/src/TestDetails.h tests/UnitTest++/src/TestList.cpp tests/UnitTest++/src/TestList.h tests/UnitTest++/src/TestMacros.h tests/UnitTest++/src/TestReporter.cpp tests/UnitTest++/src/TestReporter.h tests/UnitTest++/src/TestReporterStdout.cpp tests/UnitTest++/src/TestReporterStdout.h tests/UnitTest++/src/TestResults.cpp tests/UnitTest++/src/TestResults.h tests/UnitTest++/src/TestRunner.cpp tests/UnitTest++/src/TestRunner.h tests/UnitTest++/src/TestSuite.h tests/UnitTest++/src/TimeConstraint.cpp tests/UnitTest++/src/TimeConstraint.h tests/UnitTest++/src/TimeHelpers.h tests/UnitTest++/src/UnitTest++.h tests/UnitTest++/src/XmlTestReporter.cpp tests/UnitTest++/src/XmlTestReporter.h
diffstat 47 files changed, 2124 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Wed Nov 21 10:54:55 2012 -0500
+++ b/ChangeLog	Wed Nov 21 12:37:38 2012 -0500
@@ -1,3 +1,53 @@
+2012-11-21  Adam Domurad  <adomurad@redhat.com>
+
+	Add the source code to UnitTest++ into the project.
+	* tests/UnitTest++/COPYING: Part of UnitTest++
+	* tests/UnitTest++/Makefile: Part of UnitTest++
+	* tests/UnitTest++/README: Part of UnitTest++
+	* tests/UnitTest++/src/AssertException.cpp: Part of UnitTest++
+	* tests/UnitTest++/src/AssertException.h: Part of UnitTest++
+	* tests/UnitTest++/src/CheckMacros.h: Part of UnitTest++
+	* tests/UnitTest++/src/Checks.cpp: Part of UnitTest++
+	* tests/UnitTest++/src/Checks.h: Part of UnitTest++
+	* tests/UnitTest++/src/Config.h: Part of UnitTest++
+	* tests/UnitTest++/src/CurrentTest.cpp: Part of UnitTest++
+	* tests/UnitTest++/src/CurrentTest.h: Part of UnitTest++
+	* tests/UnitTest++/src/DeferredTestReporter.cpp: Part of UnitTest++
+	* tests/UnitTest++/src/DeferredTestReporter.h: Part of UnitTest++
+	* tests/UnitTest++/src/DeferredTestResult.cpp: Part of UnitTest++
+	* tests/UnitTest++/src/DeferredTestResult.h: Part of UnitTest++
+	* tests/UnitTest++/src/ExecuteTest.h: Part of UnitTest++
+	* tests/UnitTest++/src/MemoryOutStream.cpp: Part of UnitTest++
+	* tests/UnitTest++/src/MemoryOutStream.h: Part of UnitTest++
+	* tests/UnitTest++/src/Posix/SignalTranslator.cpp: Part of UnitTest++
+	* tests/UnitTest++/src/Posix/SignalTranslator.h: Part of UnitTest++
+	* tests/UnitTest++/src/Posix/TimeHelpers.cpp: Part of UnitTest++
+	* tests/UnitTest++/src/Posix/TimeHelpers.h: Part of UnitTest++
+	* tests/UnitTest++/src/ReportAssert.cpp: Part of UnitTest++
+	* tests/UnitTest++/src/ReportAssert.h: Part of UnitTest++
+	* tests/UnitTest++/src/Test.cpp: Part of UnitTest++
+	* tests/UnitTest++/src/Test.h: Part of UnitTest++
+	* tests/UnitTest++/src/TestDetails.cpp: Part of UnitTest++
+	* tests/UnitTest++/src/TestDetails.h: Part of UnitTest++
+	* tests/UnitTest++/src/TestList.cpp: Part of UnitTest++
+	* tests/UnitTest++/src/TestList.h: Part of UnitTest++
+	* tests/UnitTest++/src/TestMacros.h: Part of UnitTest++
+	* tests/UnitTest++/src/TestReporter.cpp: Part of UnitTest++
+	* tests/UnitTest++/src/TestReporter.h: Part of UnitTest++
+	* tests/UnitTest++/src/TestReporterStdout.cpp: Part of UnitTest++
+	* tests/UnitTest++/src/TestReporterStdout.h: Part of UnitTest++
+	* tests/UnitTest++/src/TestResults.cpp: Part of UnitTest++
+	* tests/UnitTest++/src/TestResults.h: Part of UnitTest++
+	* tests/UnitTest++/src/TestRunner.cpp: Part of UnitTest++
+	* tests/UnitTest++/src/TestRunner.h: Part of UnitTest++
+	* tests/UnitTest++/src/TestSuite.h: Part of UnitTest++
+	* tests/UnitTest++/src/TimeConstraint.cpp: Part of UnitTest++
+	* tests/UnitTest++/src/TimeConstraint.h: Part of UnitTest++
+	* tests/UnitTest++/src/TimeHelpers.h: Part of UnitTest++
+	* tests/UnitTest++/src/UnitTest++.h: Part of UnitTest++
+	* tests/UnitTest++/src/XmlTestReporter.cpp: Part of UnitTest++
+	* tests/UnitTest++/src/XmlTestReporter.h: Part of UnitTest++
+
 2012-11-21  Adam Domurad  <adomurad@redhat.com>
 
 	* plugin/icedteanp/IcedTeaNPPlugin.cc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/UnitTest++/COPYING	Wed Nov 21 12:37:38 2012 -0500
@@ -0,0 +1,20 @@
+Copyright (c) 2006 Noel Llopis and Charles Nicholson
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/UnitTest++/Makefile	Wed Nov 21 12:37:38 2012 -0500
@@ -0,0 +1,96 @@
+CXX = g++
+CXXFLAGS ?= -g -Wall -W -ansi # -pedantic
+LDFLAGS ?= 
+SED = sed
+MV = mv
+RM = rm
+
+.SUFFIXES: .o .cpp
+
+lib = libUnitTest++.a
+test = TestUnitTest++
+
+src = src/AssertException.cpp \
+	src/Test.cpp \
+	src/Checks.cpp \
+	src/TestRunner.cpp \
+	src/TestResults.cpp \
+	src/TestReporter.cpp \
+	src/TestReporterStdout.cpp \
+	src/ReportAssert.cpp \
+	src/TestList.cpp \
+	src/TimeConstraint.cpp \
+	src/TestDetails.cpp \
+	src/MemoryOutStream.cpp \
+	src/DeferredTestReporter.cpp \
+	src/DeferredTestResult.cpp \
+	src/XmlTestReporter.cpp \
+	src/CurrentTest.cpp
+	
+ifeq ($(MSYSTEM), MINGW32)
+  src += src/Win32/TimeHelpers.cpp
+else
+  src += src/Posix/SignalTranslator.cpp \
+	src/Posix/TimeHelpers.cpp
+endif
+
+test_src = src/tests/Main.cpp \
+	src/tests/TestAssertHandler.cpp \
+	src/tests/TestChecks.cpp \
+	src/tests/TestUnitTest++.cpp \
+	src/tests/TestTest.cpp \
+	src/tests/TestTestResults.cpp \
+	src/tests/TestTestRunner.cpp \
+	src/tests/TestCheckMacros.cpp \
+	src/tests/TestTestList.cpp \
+	src/tests/TestTestMacros.cpp \
+	src/tests/TestTimeConstraint.cpp \
+	src/tests/TestTimeConstraintMacro.cpp \
+	src/tests/TestMemoryOutStream.cpp \
+	src/tests/TestDeferredTestReporter.cpp \
+	src/tests/TestXmlTestReporter.cpp \
+	src/tests/TestCurrentTest.cpp
+
+objects = $(patsubst %.cpp, %.o, $(src))
+test_objects = $(patsubst %.cpp, %.o, $(test_src))
+dependencies = $(subst .o,.d,$(objects))
+test_dependencies = $(subst .o,.d,$(test_objects))
+
+define make-depend
+  $(CXX) $(CXXFLAGS) -M $1 | \
+  $(SED) -e 's,\($(notdir $2)\) *:,$(dir $2)\1: ,' > $3.tmp
+  $(SED) -e 's/#.*//' \
+      -e 's/^[^:]*: *//' \
+      -e 's/ *\\$$//' \
+      -e '/^$$/ d' \
+      -e 's/$$/ :/' $3.tmp >> $3.tmp
+  $(MV) $3.tmp $3
+endef
+
+
+all: $(lib)
+
+
+$(lib): $(objects) 
+	@echo Creating $(lib) library...
+	@ar cr $(lib) $(objects)
+    
+$(test): $(lib) $(test_objects)
+	@echo Linking $(test)...
+	@$(CXX) $(LDFLAGS) -o $(test) $(test_objects) $(lib)
+	@echo Running unit tests...
+	@./$(test)
+
+clean:
+	-@$(RM) $(objects) $(test_objects) $(dependencies) $(test_dependencies) $(test) $(lib) 2> /dev/null
+
+%.o : %.cpp
+	@echo $<
+	@$(call make-depend,$<,$@,$(subst .o,.d,$@))
+	@$(CXX) $(CXXFLAGS) -c $< -o $(patsubst %.cpp, %.o, $<)
+
+
+ifneq "$(MAKECMDGOALS)" "clean"
+-include $(dependencies)
+-include $(test_dependencies)
+endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/UnitTest++/README	Wed Nov 21 12:37:38 2012 -0500
@@ -0,0 +1,68 @@
+UnitTest++ README
+Version: v1.4
+Last update: 2008-10-30
+
+UnitTest++ is free software. You may copy, distribute, and modify it under
+the terms of the License contained in the file COPYING distributed
+with this package. This license is the same as the MIT/X Consortium
+license.
+
+See src/tests/TestUnitTest++.cpp for usage.
+
+Authors:
+Noel Llopis (llopis@convexhull.com) 
+Charles Nicholson (charles.nicholson@gmail.com)
+
+Contributors:
+Jim Tilander
+Kim Grasman
+Jonathan Jansson
+Dirck Blaskey
+Rory Driscoll
+Dan Lind
+Matt Kimmel -- Submitted with permission from Blue Fang Games
+Anthony Moralez
+Jeff Dixon
+Randy Coulman
+Lieven van der Heide
+
+Release notes:
+--------------
+Version 1.4 (2008-10-30)
+- CHECK macros work at arbitrary stack depth from inside TESTs.
+- Remove obsolete TEST_UTILITY macros
+- Predicated test execution (via TestRunner::RunTestsIf)
+- Better exception handling for fixture ctors/dtors.
+- VC6/7/8/9 support
+
+Version 1.3 (2007-4-22)
+- Removed dynamic memory allocations (other than streams)
+- MinGW support
+- Consistent (native) line endings
+- Minor bug fixing
+
+Version 1.2 (2006-10-29)
+- First pass at documentation.
+- More detailed error crash catching in fixtures.
+- Standard streams used for printing objects under check. This should allow the
+  use of standard class types such as std::string or other custom classes with
+  stream operators to ostream.
+- Standard streams can be optionally compiled off by defining UNITTEST_USE_CUSTOM_STREAMS
+  in Config.h
+- Added named test suites
+- Added CHECK_ARRAY2D_CLOSE 
+- Posix library name is libUnitTest++.a now
+- Floating point numbers are postfixed with f in the failure reports
+
+Version 1.1 (2006-04-18)
+- CHECK macros do not have side effects even if one of the parameters changes state
+- Removed CHECK_ARRAY_EQUAL (too similar to CHECK_ARRAY_CLOSE)
+- Added local and global time constraints
+- Removed dependencies on strstream
+- Improved Posix signal to exception translator
+- Failing tests are added to Visual Studio's error list
+- Fixed Visual Studio projects to work with spaces in directories
+
+Version 1.0 (2006-03-15)
+- Initial release
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/UnitTest++/src/AssertException.cpp	Wed Nov 21 12:37:38 2012 -0500
@@ -0,0 +1,34 @@
+#include "AssertException.h"
+#include <cstring>
+
+namespace UnitTest {
+
+AssertException::AssertException(char const* description, char const* filename, int lineNumber)
+    : m_lineNumber(lineNumber)
+{
+	using namespace std;
+
+    strcpy(m_description, description);
+    strcpy(m_filename, filename);
+}
+
+AssertException::~AssertException() throw()
+{
+}
+
+char const* AssertException::what() const throw()
+{
+    return m_description;
+}
+
+char const* AssertException::Filename() const
+{
+    return m_filename;
+}
+
+int AssertException::LineNumber() const
+{
+    return m_lineNumber;
+}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/UnitTest++/src/AssertException.h	Wed Nov 21 12:37:38 2012 -0500
@@ -0,0 +1,28 @@
+#ifndef UNITTEST_ASSERTEXCEPTION_H
+#define UNITTEST_ASSERTEXCEPTION_H
+
+#include <exception>
+
+
+namespace UnitTest {
+
+class AssertException : public std::exception
+{
+public:
+    AssertException(char const* description, char const* filename, int lineNumber);
+    virtual ~AssertException() throw();
+
+    virtual char const* what() const throw();
+
+    char const* Filename() const;
+    int LineNumber() const;
+
+private:
+    char m_description[512];
+    char m_filename[256];
+    int m_lineNumber;
+};
+
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/UnitTest++/src/CheckMacros.h	Wed Nov 21 12:37:38 2012 -0500
@@ -0,0 +1,122 @@
+#ifndef UNITTEST_CHECKMACROS_H 
+#define UNITTEST_CHECKMACROS_H
+
+#include "Checks.h"
+#include "AssertException.h"
+#include "MemoryOutStream.h"
+#include "TestDetails.h"
+#include "CurrentTest.h"
+
+#ifdef CHECK
+    #error UnitTest++ redefines CHECK
+#endif
+
+#ifdef CHECK_EQUAL
+	#error UnitTest++ redefines CHECK_EQUAL
+#endif
+
+#ifdef CHECK_CLOSE
+	#error UnitTest++ redefines CHECK_CLOSE
+#endif
+
+#ifdef CHECK_ARRAY_EQUAL
+	#error UnitTest++ redefines CHECK_ARRAY_EQUAL
+#endif
+
+#ifdef CHECK_ARRAY_CLOSE
+	#error UnitTest++ redefines CHECK_ARRAY_CLOSE
+#endif
+
+#ifdef CHECK_ARRAY2D_CLOSE
+	#error UnitTest++ redefines CHECK_ARRAY2D_CLOSE
+#endif
+
+#define CHECK(value) \
+    do \
+    { \
+        try { \
+            if (!UnitTest::Check(value)) \
+                UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), #value); \
+        } \
+        catch (...) { \
+            UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \
+                    "Unhandled exception in CHECK(" #value ")"); \
+        } \
+    } while (0)
+
+#define CHECK_EQUAL(expected, actual) \
+    do \
+    { \
+        try { \
+            UnitTest::CheckEqual(*UnitTest::CurrentTest::Results(), expected, actual, UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__)); \
+        } \
+        catch (...) { \
+            UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \
+                    "Unhandled exception in CHECK_EQUAL(" #expected ", " #actual ")"); \
+        } \
+    } while (0)
+
+#define CHECK_CLOSE(expected, actual, tolerance) \
+    do \
+    { \
+        try { \
+            UnitTest::CheckClose(*UnitTest::CurrentTest::Results(), expected, actual, tolerance, UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__)); \
+        } \
+        catch (...) { \
+            UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \
+                    "Unhandled exception in CHECK_CLOSE(" #expected ", " #actual ")"); \
+        } \
+    } while (0)
+
+#define CHECK_ARRAY_EQUAL(expected, actual, count) \
+    do \
+    { \
+        try { \
+            UnitTest::CheckArrayEqual(*UnitTest::CurrentTest::Results(), expected, actual, count, UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__)); \
+        } \
+        catch (...) { \
+            UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \
+                    "Unhandled exception in CHECK_ARRAY_EQUAL(" #expected ", " #actual ")"); \
+        } \
+    } while (0)
+
+#define CHECK_ARRAY_CLOSE(expected, actual, count, tolerance) \
+    do \
+    { \
+        try { \
+            UnitTest::CheckArrayClose(*UnitTest::CurrentTest::Results(), expected, actual, count, tolerance, UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__)); \
+        } \
+        catch (...) { \
+            UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \
+                    "Unhandled exception in CHECK_ARRAY_CLOSE(" #expected ", " #actual ")"); \
+        } \
+    } while (0)
+
+#define CHECK_ARRAY2D_CLOSE(expected, actual, rows, columns, tolerance) \
+    do \
+    { \
+        try { \
+            UnitTest::CheckArray2DClose(*UnitTest::CurrentTest::Results(), expected, actual, rows, columns, tolerance, UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__)); \
+        } \
+        catch (...) { \
+            UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \
+                    "Unhandled exception in CHECK_ARRAY_CLOSE(" #expected ", " #actual ")"); \
+        } \
+    } while (0)
+
+
+#define CHECK_THROW(expression, ExpectedExceptionType) \
+    do \
+    { \
+        bool caught_ = false; \
+        try { expression; } \
+        catch (ExpectedExceptionType const&) { caught_ = true; } \
+        catch (...) {} \
+        if (!caught_) \
+            UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), "Expected exception: \"" #ExpectedExceptionType "\" not thrown"); \
+    } while(0)
+
+#define CHECK_ASSERT(expression) \
+    CHECK_THROW(expression, UnitTest::AssertException);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/UnitTest++/src/Checks.cpp	Wed Nov 21 12:37:38 2012 -0500
@@ -0,0 +1,50 @@
+#include "Checks.h"
+#include <cstring>
+
+namespace UnitTest {
+
+namespace {
+
+void CheckStringsEqual(TestResults& results, char const* expected, char const* actual, 
+                       TestDetails const& details)
+{
+	using namespace std;
+
+    if (strcmp(expected, actual))
+    {
+        UnitTest::MemoryOutStream stream;
+        stream << "Expected " << expected << " but was " << actual;
+
+        results.OnTestFailure(details, stream.GetText());
+    }
+}
+
+}
+
+
+void CheckEqual(TestResults& results, char const* expected, char const* actual,
+                TestDetails const& details)
+{
+    CheckStringsEqual(results, expected, actual, details);
+}
+
+void CheckEqual(TestResults& results, char* expected, char* actual,
+                TestDetails const& details)
+{
+    CheckStringsEqual(results, expected, actual, details);
+}
+
+void CheckEqual(TestResults& results, char* expected, char const* actual,
+                TestDetails const& details)
+{
+    CheckStringsEqual(results, expected, actual, details);
+}
+
+void CheckEqual(TestResults& results, char const* expected, char* actual,
+                TestDetails const& details)
+{
+    CheckStringsEqual(results, expected, actual, details);
+}
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/UnitTest++/src/Checks.h	Wed Nov 21 12:37:38 2012 -0500
@@ -0,0 +1,158 @@
+#ifndef UNITTEST_CHECKS_H
+#define UNITTEST_CHECKS_H
+
+#include "Config.h"
+#include "TestResults.h"
+#include "MemoryOutStream.h"
+
+namespace UnitTest {
+
+
+template< typename Value >
+bool Check(Value const value)
+{
+    return !!value; // doing double negative to avoid silly VS warnings
+}
+
+
+template< typename Expected, typename Actual >
+void CheckEqual(TestResults& results, Expected const& expected, Actual const& actual, TestDetails const& details)
+{
+    if (!(expected == actual))
+    {
+        UnitTest::MemoryOutStream stream;
+        stream << "Expected " << expected << " but was " << actual;
+
+        results.OnTestFailure(details, stream.GetText());
+    }
+}
+
+void CheckEqual(TestResults& results, char const* expected, char const* actual, TestDetails const& details);
+
+void CheckEqual(TestResults& results, char* expected, char* actual, TestDetails const& details);
+
+void CheckEqual(TestResults& results, char* expected, char const* actual, TestDetails const& details);
+
+void CheckEqual(TestResults& results, char const* expected, char* actual, TestDetails const& details);
+
+template< typename Expected, typename Actual, typename Tolerance >
+bool AreClose(Expected const& expected, Actual const& actual, Tolerance const& tolerance)
+{
+    return (actual >= (expected - tolerance)) && (actual <= (expected + tolerance));
+}
+
+template< typename Expected, typename Actual, typename Tolerance >
+void CheckClose(TestResults& results, Expected const& expected, Actual const& actual, Tolerance const& tolerance,
+                TestDetails const& details)
+{
+    if (!AreClose(expected, actual, tolerance))
+    { 
+        UnitTest::MemoryOutStream stream;
+        stream << "Expected " << expected << " +/- " << tolerance << " but was " << actual;
+
+        results.OnTestFailure(details, stream.GetText());
+    }
+}
+
+
+template< typename Expected, typename Actual >
+void CheckArrayEqual(TestResults& results, Expected const& expected, Actual const& actual,
+                int const count, TestDetails const& details)
+{
+    bool equal = true;
+    for (int i = 0; i < count; ++i)
+        equal &= (expected[i] == actual[i]);
+
+    if (!equal)
+    {
+        UnitTest::MemoryOutStream stream;
+
+		stream << "Expected [ ";
+
+		for (int expectedIndex = 0; expectedIndex < count; ++expectedIndex)
+            stream << expected[expectedIndex] << " ";
+
+		stream << "] but was [ ";
+
+		for (int actualIndex = 0; actualIndex < count; ++actualIndex)
+            stream << actual[actualIndex] << " ";
+
+		stream << "]";
+
+        results.OnTestFailure(details, stream.GetText());
+    }
+}
+
+template< typename Expected, typename Actual, typename Tolerance >
+bool ArrayAreClose(Expected const& expected, Actual const& actual, int const count, Tolerance const& tolerance)
+{
+    bool equal = true;
+    for (int i = 0; i < count; ++i)
+        equal &= AreClose(expected[i], actual[i], tolerance);
+    return equal;
+}
+
+template< typename Expected, typename Actual, typename Tolerance >
+void CheckArrayClose(TestResults& results, Expected const& expected, Actual const& actual,
+                   int const count, Tolerance const& tolerance, TestDetails const& details)
+{
+    bool equal = ArrayAreClose(expected, actual, count, tolerance);
+
+    if (!equal)
+    {
+        UnitTest::MemoryOutStream stream;
+
+        stream << "Expected [ ";
+        for (int expectedIndex = 0; expectedIndex < count; ++expectedIndex)
+            stream << expected[expectedIndex] << " ";
+        stream << "] +/- " << tolerance << " but was [ ";
+
+		for (int actualIndex = 0; actualIndex < count; ++actualIndex)
+            stream << actual[actualIndex] << " ";
+        stream << "]";
+
+        results.OnTestFailure(details, stream.GetText());
+    }
+}
+
+template< typename Expected, typename Actual, typename Tolerance >
+void CheckArray2DClose(TestResults& results, Expected const& expected, Actual const& actual,
+                   int const rows, int const columns, Tolerance const& tolerance, TestDetails const& details)
+{
+    bool equal = true;
+    for (int i = 0; i < rows; ++i)
+        equal &= ArrayAreClose(expected[i], actual[i], columns, tolerance);
+
+    if (!equal)
+    {
+        UnitTest::MemoryOutStream stream;
+
+        stream << "Expected [ ";    
+
+		for (int expectedRow = 0; expectedRow < rows; ++expectedRow)
+        {
+            stream << "[ ";
+            for (int expectedColumn = 0; expectedColumn < columns; ++expectedColumn)
+                stream << expected[expectedRow][expectedColumn] << " ";
+            stream << "] ";
+        }
+
+		stream << "] +/- " << tolerance << " but was [ ";
+
+		for (int actualRow = 0; actualRow < rows; ++actualRow)
+        {
+            stream << "[ ";
+            for (int actualColumn = 0; actualColumn < columns; ++actualColumn)
+                stream << actual[actualRow][actualColumn] << " ";
+            stream << "] ";
+        }
+
+		stream << "]";
+
+        results.OnTestFailure(details, stream.GetText());
+    }
+}
+
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/UnitTest++/src/Config.h	Wed Nov 21 12:37:38 2012 -0500
@@ -0,0 +1,31 @@
+#ifndef UNITTEST_CONFIG_H
+#define UNITTEST_CONFIG_H
+
+// Standard defines documented here: http://predef.sourceforge.net
+
+#if defined(_MSC_VER)
+    #pragma warning(disable:4127) // conditional expression is constant
+	#pragma warning(disable:4702) // unreachable code
+	#pragma warning(disable:4722) // destructor never returns, potential memory leak
+
+	#if (_MSC_VER == 1200)  // VC6
+		#pragma warning(disable:4786)
+		#pragma warning(disable:4290)
+	#endif
+#endif
+
+#if defined(unix) || defined(__unix__) || defined(__unix) || defined(linux) || \
+    defined(__APPLE__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__)        
+    #define UNITTEST_POSIX
+#endif
+
+#if defined(__MINGW32__)
+    #define UNITTEST_MINGW
+#endif
+
+// by default, MemoryOutStream is implemented in terms of std::ostringstream, which can be expensive.
+// uncomment this line to use the custom MemoryOutStream (no deps on std::ostringstream).
+
+//#define UNITTEST_USE_CUSTOM_STREAMS
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/UnitTest++/src/CurrentTest.cpp	Wed Nov 21 12:37:38 2012 -0500
@@ -0,0 +1,18 @@
+#include "CurrentTest.h"
+#include <cstddef>
+
+namespace UnitTest {
+
+TestResults*& CurrentTest::Results()
+{
+	static TestResults* testResults = NULL;
+	return testResults;
+}
+
+const TestDetails*& CurrentTest::Details()
+{
+	static const TestDetails* testDetails = NULL;
+	return testDetails;
+}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/UnitTest++/src/CurrentTest.h	Wed Nov 21 12:37:38 2012 -0500
@@ -0,0 +1,17 @@
+#ifndef UNITTEST_CURRENTTESTRESULTS_H
+#define UNITTEST_CURRENTTESTRESULTS_H
+
+namespace UnitTest {
+
+class TestResults;
+class TestDetails;
+
+namespace CurrentTest
+{
+	TestResults*& Results();
+	const TestDetails*& Details();
+}
+
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/UnitTest++/src/DeferredTestReporter.cpp	Wed Nov 21 12:37:38 2012 -0500
@@ -0,0 +1,29 @@
+#include "DeferredTestReporter.h"
+#include "TestDetails.h"
+#include "Config.h"
+
+using namespace UnitTest;
+
+void DeferredTestReporter::ReportTestStart(TestDetails const& details)
+{
+    m_results.push_back(DeferredTestResult(details.suiteName, details.testName));
+}
+
+void DeferredTestReporter::ReportFailure(TestDetails const& details, char const* failure)
+{
+    DeferredTestResult& r = m_results.back();
+    r.failed = true;
+    r.failures.push_back(DeferredTestResult::Failure(details.lineNumber, failure));
+    r.failureFile = details.filename;
+}
+
+void DeferredTestReporter::ReportTestFinish(TestDetails const&, float secondsElapsed)
+{
+    DeferredTestResult& r = m_results.back();
+    r.timeElapsed = secondsElapsed;
+}
+
+DeferredTestReporter::DeferredTestResultList& DeferredTestReporter::GetResults()
+{
+    return m_results;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/UnitTest++/src/DeferredTestReporter.h	Wed Nov 21 12:37:38 2012 -0500
@@ -0,0 +1,28 @@
+#ifndef UNITTEST_DEFERREDTESTREPORTER_H
+#define UNITTEST_DEFERREDTESTREPORTER_H
+
+#include "TestReporter.h"
+#include "DeferredTestResult.h"
+
+#include <vector>
+
+namespace UnitTest
+{
+
+class DeferredTestReporter : public TestReporter
+{
+public:
+    virtual void ReportTestStart(TestDetails const& details);
+    virtual void ReportFailure(TestDetails const& details, char const* failure);
+    virtual void ReportTestFinish(TestDetails const& details, float secondsElapsed);
+
+    typedef std::vector< DeferredTestResult > DeferredTestResultList;
+    DeferredTestResultList& GetResults();
+
+private:
+    DeferredTestResultList m_results;
+};
+
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/UnitTest++/src/DeferredTestResult.cpp	Wed Nov 21 12:37:38 2012 -0500
@@ -0,0 +1,25 @@
+#include "DeferredTestResult.h"
+#include "Config.h"
+
+namespace UnitTest
+{
+
+DeferredTestResult::DeferredTestResult()
+	: suiteName("")
+	, testName("")
+	, failureFile("")
+	, timeElapsed(0.0f)
+	, failed(false)
+{
+}
+
+DeferredTestResult::DeferredTestResult(char const* suite, char const* test)
+	: suiteName(suite)
+	, testName(test)
+	, failureFile("")
+	, timeElapsed(0.0f)
+	, failed(false)
+{
+}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/UnitTest++/src/DeferredTestResult.h	Wed Nov 21 12:37:38 2012 -0500
@@ -0,0 +1,29 @@
+#ifndef UNITTEST_DEFERREDTESTRESULT_H
+#define UNITTEST_DEFERREDTESTRESULT_H
+
+#include <string>
+#include <vector>
+
+namespace UnitTest
+{
+
+struct DeferredTestResult
+{
+	DeferredTestResult();
+    DeferredTestResult(char const* suite, char const* test);
+
+    std::string suiteName;
+    std::string testName;
+    std::string failureFile;
+    
+    typedef std::pair< int, std::string > Failure;
+    typedef std::vector< Failure > FailureVec;
+    FailureVec failures;
+    
+    float timeElapsed;
+	bool failed;
+};
+
+}
+
+#endif //UNITTEST_DEFERREDTESTRESULT_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/UnitTest++/src/ExecuteTest.h	Wed Nov 21 12:37:38 2012 -0500
@@ -0,0 +1,46 @@
+#ifndef UNITTEST_EXECUTE_TEST_H
+#define UNITTEST_EXECUTE_TEST_H
+
+#include "TestDetails.h"
+#include "MemoryOutStream.h"
+#include "AssertException.h"
+#include "CurrentTest.h"
+
+#ifdef UNITTEST_POSIX
+	#include "Posix/SignalTranslator.h"
+#endif
+
+namespace UnitTest {
+
+template< typename T >
+void ExecuteTest(T& testObject, TestDetails const& details)
+{
+	CurrentTest::Details() = &details;
+
+	try
+	{
+#ifdef UNITTEST_POSIX
+		UNITTEST_THROW_SIGNALS
+#endif
+		testObject.RunImpl();
+	}
+	catch (AssertException const& e)
+	{
+		CurrentTest::Results()->OnTestFailure(
+			TestDetails(details.testName, details.suiteName, e.Filename(), e.LineNumber()), e.what());
+	}
+	catch (std::exception const& e)
+	{
+		MemoryOutStream stream;
+		stream << "Unhandled exception: " << e.what();
+		CurrentTest::Results()->OnTestFailure(details, stream.GetText());
+	}
+	catch (...)
+	{
+		CurrentTest::Results()->OnTestFailure(details, "Unhandled exception: Crash!");
+	}
+}
+
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/UnitTest++/src/MemoryOutStream.cpp	Wed Nov 21 12:37:38 2012 -0500
@@ -0,0 +1,149 @@
+#include "MemoryOutStream.h"
+
+#ifndef UNITTEST_USE_CUSTOM_STREAMS
+
+
+namespace UnitTest {
+
+char const* MemoryOutStream::GetText() const
+{
+    m_text = this->str();
+    return m_text.c_str();
+}
+
+
+}
+
+
+#else
+
+
+#include <cstring>
+#include <cstdio>
+
+namespace UnitTest {
+
+namespace {
+
+template<typename ValueType>
+void FormatToStream(MemoryOutStream& stream, char const* format, ValueType const& value)
+{
+	using namespace std;
+
+    char txt[32];
+    sprintf(txt, format, value);
+    stream << txt;
+}
+
+int RoundUpToMultipleOfPow2Number (int n, int pow2Number)
+{
+    return (n + (pow2Number - 1)) & ~(pow2Number - 1);
+}
+
+}
+
+
+MemoryOutStream::MemoryOutStream(int const size)
+    : m_capacity (0)
+    , m_buffer (0)
+
+{
+    GrowBuffer(size);
+}
+
+MemoryOutStream::~MemoryOutStream()
+{
+    delete [] m_buffer;
+}
+
+char const* MemoryOutStream::GetText() const
+{
+    return m_buffer;
+}
+
+MemoryOutStream& MemoryOutStream::operator << (char const* txt)
+{
+	using namespace std;
+
+    int const bytesLeft = m_capacity - (int)strlen(m_buffer);
+    int const bytesRequired = (int)strlen(txt) + 1;
+
+    if (bytesRequired > bytesLeft)
+    {
+        int const requiredCapacity = bytesRequired + m_capacity - bytesLeft;
+        GrowBuffer(requiredCapacity);
+    }
+
+    strcat(m_buffer, txt);
+    return *this;
+}
+
+MemoryOutStream& MemoryOutStream::operator << (int const n)
+{
+    FormatToStream(*this, "%i", n);
+    return *this;
+}
+
+MemoryOutStream& MemoryOutStream::operator << (long const n)
+{
+    FormatToStream(*this, "%li", n);
+    return *this;
+}
+
+MemoryOutStream& MemoryOutStream::operator << (unsigned long const n)
+{
+    FormatToStream(*this, "%lu", n);
+    return *this;
+}
+
+MemoryOutStream& MemoryOutStream::operator << (float const f)
+{
+    FormatToStream(*this, "%ff", f);
+    return *this;    
+}
+
+MemoryOutStream& MemoryOutStream::operator << (void const* p)
+{
+    FormatToStream(*this, "%p", p);
+    return *this;    
+}
+
+MemoryOutStream& MemoryOutStream::operator << (unsigned int const s)
+{
+    FormatToStream(*this, "%u", s);
+    return *this;    
+}
+
+MemoryOutStream& MemoryOutStream::operator <<(double const d)
+{
+	FormatToStream(*this, "%f", d);
+	return *this;
+}
+
+int MemoryOutStream::GetCapacity() const
+{
+    return m_capacity;
+}
+
+
+void MemoryOutStream::GrowBuffer(int const desiredCapacity)
+{
+    int const newCapacity = RoundUpToMultipleOfPow2Number(desiredCapacity, GROW_CHUNK_SIZE);
+
+	using namespace std;
+
+    char* buffer = new char[newCapacity];
+    if (m_buffer)
+        strcpy(buffer, m_buffer);
+    else
+        strcpy(buffer, "");
+
+    delete [] m_buffer;
+    m_buffer = buffer;
+    m_capacity = newCapacity;
+}
+
+}
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/UnitTest++/src/MemoryOutStream.h	Wed Nov 21 12:37:38 2012 -0500
@@ -0,0 +1,67 @@
+#ifndef UNITTEST_MEMORYOUTSTREAM_H
+#define UNITTEST_MEMORYOUTSTREAM_H
+
+#include "Config.h"
+
+#ifndef UNITTEST_USE_CUSTOM_STREAMS
+
+#include <sstream>
+
+namespace UnitTest
+{
+
+class MemoryOutStream : public std::ostringstream
+{
+public:
+    MemoryOutStream() {}
+    char const* GetText() const;
+
+private:
+    MemoryOutStream(MemoryOutStream const&);
+    void operator =(MemoryOutStream const&);
+
+    mutable std::string m_text;
+};
+
+}
+
+#else
+
+#include <cstddef>
+
+namespace UnitTest
+{
+
+class MemoryOutStream
+{
+public:
+    explicit MemoryOutStream(int const size = 256);
+    ~MemoryOutStream();
+
+    char const* GetText() const;
+
+    MemoryOutStream& operator << (char const* txt);
+    MemoryOutStream& operator << (int n);
+    MemoryOutStream& operator << (long n);
+    MemoryOutStream& operator << (unsigned long n);
+    MemoryOutStream& operator << (float f);
+    MemoryOutStream& operator << (double d);
+    MemoryOutStream& operator << (void const* p);
+    MemoryOutStream& operator << (unsigned int s);
+
+    enum { GROW_CHUNK_SIZE = 32 };
+    int GetCapacity() const;
+
+private:
+    void operator= (MemoryOutStream const&);
+    void GrowBuffer(int capacity);
+
+    int m_capacity;
+    char* m_buffer;
+};
+
+}
+
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/UnitTest++/src/Posix/SignalTranslator.cpp	Wed Nov 21 12:37:38 2012 -0500
@@ -0,0 +1,46 @@
+#include "SignalTranslator.h"
+
+namespace UnitTest {
+
+sigjmp_buf* SignalTranslator::s_jumpTarget = 0;
+
+namespace {
+
+void SignalHandler(int sig)
+{
+    siglongjmp(*SignalTranslator::s_jumpTarget, sig );
+}
+
+}
+
+
+SignalTranslator::SignalTranslator()
+{
+    m_oldJumpTarget = s_jumpTarget;
+    s_jumpTarget = &m_currentJumpTarget;
+
+    struct sigaction action;
+    action.sa_flags = 0;
+    action.sa_handler = SignalHandler;
+    sigemptyset( &action.sa_mask );
+
+    sigaction( SIGSEGV, &action, &m_old_SIGSEGV_action );
+    sigaction( SIGFPE , &action, &m_old_SIGFPE_action  );
+    sigaction( SIGTRAP, &action, &m_old_SIGTRAP_action );
+    sigaction( SIGBUS , &action, &m_old_SIGBUS_action  );
+    sigaction( SIGILL , &action, &m_old_SIGBUS_action  );
+}
+
+SignalTranslator::~SignalTranslator()
+{
+    sigaction( SIGILL , &m_old_SIGBUS_action , 0 );
+    sigaction( SIGBUS , &m_old_SIGBUS_action , 0 );
+    sigaction( SIGTRAP, &m_old_SIGTRAP_action, 0 );
+    sigaction( SIGFPE , &m_old_SIGFPE_action , 0 );
+    sigaction( SIGSEGV, &m_old_SIGSEGV_action, 0 );
+
+    s_jumpTarget = m_oldJumpTarget;
+}
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/UnitTest++/src/Posix/SignalTranslator.h	Wed Nov 21 12:37:38 2012 -0500
@@ -0,0 +1,42 @@
+#ifndef UNITTEST_SIGNALTRANSLATOR_H
+#define UNITTEST_SIGNALTRANSLATOR_H
+
+#include <setjmp.h>
+#include <signal.h>
+
+namespace UnitTest {
+
+class SignalTranslator
+{
+public:
+    SignalTranslator();
+    ~SignalTranslator();
+
+    static sigjmp_buf* s_jumpTarget;
+
+private:
+    sigjmp_buf m_currentJumpTarget;
+    sigjmp_buf* m_oldJumpTarget;
+
+    struct sigaction m_old_SIGFPE_action;
+    struct sigaction m_old_SIGTRAP_action;
+    struct sigaction m_old_SIGSEGV_action;
+    struct sigaction m_old_SIGBUS_action;
+    struct sigaction m_old_SIGABRT_action;
+    struct sigaction m_old_SIGALRM_action;
+};
+
+#if !defined (__GNUC__)
+    #define UNITTEST_EXTENSION
+#else
+    #define UNITTEST_EXTENSION __extension__
+#endif
+
+#define UNITTEST_THROW_SIGNALS \
+	UnitTest::SignalTranslator sig; \
+	if (UNITTEST_EXTENSION sigsetjmp(*UnitTest::SignalTranslator::s_jumpTarget, 1) != 0) \
+        throw ("Unhandled system exception"); 
+
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/UnitTest++/src/Posix/TimeHelpers.cpp	Wed Nov 21 12:37:38 2012 -0500
@@ -0,0 +1,33 @@
+#include "TimeHelpers.h"
+#include <unistd.h>
+
+namespace UnitTest {
+
+Timer::Timer()
+{
+    m_startTime.tv_sec = 0;
+    m_startTime.tv_usec = 0;
+}
+
+void Timer::Start()
+{
+    gettimeofday(&m_startTime, 0);
+}
+
+
+int Timer::GetTimeInMs() const
+{
+    struct timeval currentTime;
+    gettimeofday(&currentTime, 0);
+    int const dsecs = currentTime.tv_sec - m_startTime.tv_sec;
+    int const dus = currentTime.tv_usec - m_startTime.tv_usec;
+    return dsecs*1000 + dus/1000;
+}
+
+
+void TimeHelpers::SleepMs (int ms)
+{
+    usleep(ms * 1000);
+}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/UnitTest++/src/Posix/TimeHelpers.h	Wed Nov 21 12:37:38 2012 -0500
@@ -0,0 +1,28 @@
+#ifndef UNITTEST_TIMEHELPERS_H
+#define UNITTEST_TIMEHELPERS_H
+
+#include <sys/time.h>
+
+namespace UnitTest {
+
+class Timer
+{
+public:
+    Timer();
+    void Start();
+    int GetTimeInMs() const;    
+
+private:
+    struct timeval m_startTime;    
+};
+
+
+namespace TimeHelpers
+{
+void SleepMs (int ms);
+}
+
+
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/UnitTest++/src/ReportAssert.cpp	Wed Nov 21 12:37:38 2012 -0500
@@ -0,0 +1,10 @@
+#include "AssertException.h"
+
+namespace UnitTest {
+
+void ReportAssert(char const* description, char const* filename, int lineNumber)
+{
+    throw AssertException(description, filename, lineNumber);
+}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/UnitTest++/src/ReportAssert.h	Wed Nov 21 12:37:38 2012 -0500
@@ -0,0 +1,10 @@
+#ifndef UNITTEST_ASSERT_H
+#define UNITTEST_ASSERT_H
+
+namespace UnitTest {
+
+void ReportAssert(char const* description, char const* filename, int lineNumber);
+    
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/UnitTest++/src/Test.cpp	Wed Nov 21 12:37:38 2012 -0500
@@ -0,0 +1,41 @@
+#include "Config.h"
+#include "Test.h"
+#include "TestList.h"
+#include "TestResults.h"
+#include "AssertException.h"
+#include "MemoryOutStream.h"
+#include "ExecuteTest.h"
+
+#ifdef UNITTEST_POSIX
+    #include "Posix/SignalTranslator.h"
+#endif
+
+namespace UnitTest {
+
+TestList& Test::GetTestList()
+{
+    static TestList s_list;
+    return s_list;
+}
+
+Test::Test(char const* testName, char const* suiteName, char const* filename, int lineNumber)
+    : m_details(testName, suiteName, filename, lineNumber)
+    , next(0)
+    , m_timeConstraintExempt(false)
+{
+}
+
+Test::~Test()
+{
+}
+
+void Test::Run()
+{
+	ExecuteTest(*this, m_details);
+}
+
+void Test::RunImpl() const
+{
+}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/UnitTest++/src/Test.h	Wed Nov 21 12:37:38 2012 -0500
@@ -0,0 +1,34 @@
+#ifndef UNITTEST_TEST_H
+#define UNITTEST_TEST_H
+
+#include "TestDetails.h"
+
+namespace UnitTest {
+
+class TestResults;
+class TestList;
+
+class Test
+{
+public:
+    explicit Test(char const* testName, char const* suiteName = "DefaultSuite", char const* filename = "", int lineNumber = 0);
+    virtual ~Test();
+    void Run();
+
+    TestDetails const m_details;
+    Test* next;
+    mutable bool m_timeConstraintExempt;
+
+    static TestList& GetTestList();
+
+    virtual void RunImpl() const;
+
+private:
+	Test(Test const&);
+    Test& operator =(Test const&);
+};
+
+
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/UnitTest++/src/TestDetails.cpp	Wed Nov 21 12:37:38 2012 -0500
@@ -0,0 +1,22 @@
+#include "TestDetails.h"
+
+namespace UnitTest {
+
+TestDetails::TestDetails(char const* testName_, char const* suiteName_, char const* filename_, int lineNumber_)
+    : suiteName(suiteName_)
+    , testName(testName_)
+    , filename(filename_)
+    , lineNumber(lineNumber_)
+{
+}
+
+TestDetails::TestDetails(const TestDetails& details, int lineNumber_)
+    : suiteName(details.suiteName)
+    , testName(details.testName)
+    , filename(details.filename)
+    , lineNumber(lineNumber_)
+{
+}
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/UnitTest++/src/TestDetails.h	Wed Nov 21 12:37:38 2012 -0500
@@ -0,0 +1,24 @@
+#ifndef UNITTEST_TESTDETAILS_H
+#define UNITTEST_TESTDETAILS_H
+
+namespace UnitTest {
+
+class TestDetails
+{
+public:
+    TestDetails(char const* testName, char const* suiteName, char const* filename, int lineNumber);
+    TestDetails(const TestDetails& details, int lineNumber);
+
+    char const* const suiteName;
+    char const* const testName;
+    char const* const filename;
+    int const lineNumber;
+
+    TestDetails(TestDetails const&); // Why is it public? --> http://gcc.gnu.org/bugs.html#cxx_rvalbind
+private:
+    TestDetails& operator=(TestDetails const&);
+};
+
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/UnitTest++/src/TestList.cpp	Wed Nov 21 12:37:38 2012 -0500
@@ -0,0 +1,39 @@
+#include "TestList.h"
+#include "Test.h"
+
+#include <cassert>
+
+namespace UnitTest {
+
+TestList::TestList() 
+    : m_head(0)
+    , m_tail(0)
+{
+}
+
+void TestList::Add(Test* test)
+{
+    if (m_tail == 0)
+    {
+        assert(m_head == 0);
+        m_head = test;
+        m_tail = test;
+    }
+    else
+    {
+        m_tail->next = test;
+        m_tail = test;
+    }
+}
+
+Test* TestList::GetHead() const
+{
+    return m_head;
+}
+
+ListAdder::ListAdder(TestList& list, Test* test)
+{
+    list.Add(test);
+}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/UnitTest++/src/TestList.h	Wed Nov 21 12:37:38 2012 -0500
@@ -0,0 +1,32 @@
+#ifndef UNITTEST_TESTLIST_H
+#define UNITTEST_TESTLIST_H
+
+
+namespace UnitTest {
+
+class Test;
+
+class TestList
+{
+public:
+    TestList();
+    void Add (Test* test);
+
+    Test* GetHead() const;
+
+private:
+    Test* m_head;
+    Test* m_tail;
+};
+
+
+class ListAdder
+{
+public:
+    ListAdder(TestList& list, Test* test);
+};
+
+}
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/UnitTest++/src/TestMacros.h	Wed Nov 21 12:37:38 2012 -0500
@@ -0,0 +1,113 @@
+#ifndef UNITTEST_TESTMACROS_H
+#define UNITTEST_TESTMACROS_H
+
+#include "Config.h"
+#include "ExecuteTest.h"
+#include "AssertException.h"
+#include "TestDetails.h"
+#include "MemoryOutStream.h"
+
+#ifndef UNITTEST_POSIX
+	#define UNITTEST_THROW_SIGNALS
+#else
+	#include "Posix/SignalTranslator.h"
+#endif
+
+#ifdef TEST
+    #error UnitTest++ redefines TEST
+#endif
+
+#ifdef TEST_EX
+	#error UnitTest++ redefines TEST_EX
+#endif
+
+#ifdef TEST_FIXTURE_EX
+	#error UnitTest++ redefines TEST_FIXTURE_EX
+#endif
+
+#define SUITE(Name)                                                         \
+	namespace Suite##Name {                                                        \
+        namespace UnitTestSuite {                                           \
+            inline char const* GetSuiteName () {                            \
+                return #Name ;                                              \
+            }                                                               \
+        }                                                                   \
+    }                                                                       \
+	namespace Suite##Name
+
+#define TEST_EX(Name, List)                                                \
+    class Test##Name : public UnitTest::Test                               \
+    {                                                                      \
+    public:                                                                \
+		Test##Name() : Test(#Name, UnitTestSuite::GetSuiteName(), __FILE__, __LINE__) {}  \
+    private:                                                               \
+        virtual void RunImpl() const;   \
+    } test##Name##Instance;                                                \
+																		   \
+    UnitTest::ListAdder adder##Name (List, &test##Name##Instance);         \
+																		   \
+    void Test##Name::RunImpl() const
+
+
+#define TEST(Name) TEST_EX(Name, UnitTest::Test::GetTestList())
+
+
+#define TEST_FIXTURE_EX(Fixture, Name, List)                                         \
+    class Fixture##Name##Helper : public Fixture									 \
+	{																				 \
+	public:																			 \
+        explicit Fixture##Name##Helper(UnitTest::TestDetails const& details) : m_details(details) {} \
+        void RunImpl();                           \
+        UnitTest::TestDetails const& m_details;                                      \
+    private:                                                                         \
+        Fixture##Name##Helper(Fixture##Name##Helper const&);                         \
+        Fixture##Name##Helper& operator =(Fixture##Name##Helper const&);             \
+    };                                                                               \
+																					 \
+    class Test##Fixture##Name : public UnitTest::Test                                \
+    {                                                                                \
+    public:                                                                          \
+	    Test##Fixture##Name() : Test(#Name, UnitTestSuite::GetSuiteName(), __FILE__, __LINE__) {} \
+    private:                                                                         \
+        virtual void RunImpl() const;             \
+    } test##Fixture##Name##Instance;                                                 \
+																					 \
+    UnitTest::ListAdder adder##Fixture##Name (List, &test##Fixture##Name##Instance); \
+																					 \
+    void Test##Fixture##Name::RunImpl() const	 \
+	{																				 \
+		bool ctorOk = false;														 \
+		try {																		 \
+			Fixture##Name##Helper fixtureHelper(m_details);							 \
+			ctorOk = true;															 \
+			UnitTest::ExecuteTest(fixtureHelper, m_details);					 \
+		}																			 \
+		catch (UnitTest::AssertException const& e)											 \
+		{																			 \
+			UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(m_details.testName, m_details.suiteName, e.Filename(), e.LineNumber()), e.what()); \
+		}																			 \
+		catch (std::exception const& e)												 \
+		{																			 \
+			UnitTest::MemoryOutStream stream;													 \
+			stream << "Unhandled exception: " << e.what();							 \
+			UnitTest::CurrentTest::Results()->OnTestFailure(m_details, stream.GetText());				 \
+		}																			 \
+		catch (...) {																 \
+			if (ctorOk)																 \
+			{																		 \
+	            UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(m_details, __LINE__),	 \
+					"Unhandled exception while destroying fixture " #Fixture);		 \
+			}																		 \
+			else																	 \
+			{																		 \
+				UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(m_details, __LINE__),   \
+					"Unhandled exception while constructing fixture " #Fixture);         \
+			}																		 \
+		}																			 \
+    }                                                                                \
+    void Fixture##Name##Helper::RunImpl()
+
+#define TEST_FIXTURE(Fixture,Name) TEST_FIXTURE_EX(Fixture, Name, UnitTest::Test::GetTestList())
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/UnitTest++/src/TestReporter.cpp	Wed Nov 21 12:37:38 2012 -0500
@@ -0,0 +1,10 @@
+#include "TestReporter.h"
+
+namespace UnitTest {
+
+
+TestReporter::~TestReporter()
+{
+}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/UnitTest++/src/TestReporter.h	Wed Nov 21 12:37:38 2012 -0500
@@ -0,0 +1,20 @@
+#ifndef UNITTEST_TESTREPORTER_H
+#define UNITTEST_TESTREPORTER_H
+
+namespace UnitTest {
+
+class TestDetails;
+
+class TestReporter
+{
+public:
+    virtual ~TestReporter();
+
+    virtual void ReportTestStart(TestDetails const& test) = 0;
+    virtual void ReportFailure(TestDetails const& test, char const* failure) = 0;
+    virtual void ReportTestFinish(TestDetails const& test, float secondsElapsed) = 0;
+    virtual void ReportSummary(int totalTestCount, int failedTestCount, int failureCount, float secondsElapsed) = 0;
+};
+
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/UnitTest++/src/TestReporterStdout.cpp	Wed Nov 21 12:37:38 2012 -0500
@@ -0,0 +1,41 @@
+#include "TestReporterStdout.h"
+#include <cstdio>
+
+#include "TestDetails.h"
+
+namespace UnitTest {
+
+void TestReporterStdout::ReportFailure(TestDetails const& details, char const* failure)
+{
+#if defined(__APPLE__) || defined(__GNUG__)
+    char const* const errorFormat = "%s:%d: error: Failure in %s: %s\n";
+#else
+    char const* const errorFormat = "%s(%d): error: Failure in %s: %s\n";
+#endif
+
+	using namespace std;
+    printf(errorFormat, details.filename, details.lineNumber, details.testName, failure);
+}
+
+void TestReporterStdout::ReportTestStart(TestDetails const& /*test*/)
+{
+}
+
+void TestReporterStdout::ReportTestFinish(TestDetails const& /*test*/, float)
+{
+}
+
+void TestReporterStdout::ReportSummary(int const totalTestCount, int const failedTestCount,
+                                       int const failureCount, float secondsElapsed)
+{
+	using namespace std;
+
+    if (failureCount > 0)
+        printf("FAILURE: %d out of %d tests failed (%d failures).\n", failedTestCount, totalTestCount, failureCount);
+    else
+        printf("Success: %d tests passed.\n", totalTestCount);
+
+    printf("Test time: %.2f seconds.\n", secondsElapsed);
+}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/UnitTest++/src/TestReporterStdout.h	Wed Nov 21 12:37:38 2012 -0500
@@ -0,0 +1,19 @@
+#ifndef UNITTEST_TESTREPORTERSTDOUT_H
+#define UNITTEST_TESTREPORTERSTDOUT_H
+
+#include "TestReporter.h"
+
+namespace UnitTest {
+
+class TestReporterStdout : public TestReporter
+{
+private:
+    virtual void ReportTestStart(TestDetails const& test);
+    virtual void ReportFailure(TestDetails const& test, char const* failure);
+    virtual void ReportTestFinish(TestDetails const& test, float secondsElapsed);
+    virtual void ReportSummary(int totalTestCount, int failedTestCount, int failureCount, float secondsElapsed);
+};
+
+}
+
+#endif 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/UnitTest++/src/TestResults.cpp	Wed Nov 21 12:37:38 2012 -0500
@@ -0,0 +1,60 @@
+#include "TestResults.h"
+#include "TestReporter.h"
+
+#include "TestDetails.h"
+
+namespace UnitTest {
+
+TestResults::TestResults(TestReporter* testReporter)
+    : m_testReporter(testReporter)
+    , m_totalTestCount(0)
+    , m_failedTestCount(0)
+    , m_failureCount(0)
+    , m_currentTestFailed(false)
+{
+}
+
+void TestResults::OnTestStart(TestDetails const& test)
+{
+    ++m_totalTestCount;
+    m_currentTestFailed = false;
+    if (m_testReporter)
+        m_testReporter->ReportTestStart(test);
+}
+
+void TestResults::OnTestFailure(TestDetails const& test, char const* failure)
+{
+    ++m_failureCount;
+    if (!m_currentTestFailed)
+    {
+        ++m_failedTestCount;
+        m_currentTestFailed = true;
+    }
+
+    if (m_testReporter)
+        m_testReporter->ReportFailure(test, failure);
+}
+
+void TestResults::OnTestFinish(TestDetails const& test, float secondsElapsed)
+{
+    if (m_testReporter)
+        m_testReporter->ReportTestFinish(test, secondsElapsed);
+}
+
+int TestResults::GetTotalTestCount() const
+{
+    return m_totalTestCount;
+}
+
+int TestResults::GetFailedTestCount() const
+{
+    return m_failedTestCount;
+}
+
+int TestResults::GetFailureCount() const
+{
+    return m_failureCount;
+}
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/UnitTest++/src/TestResults.h	Wed Nov 21 12:37:38 2012 -0500
@@ -0,0 +1,36 @@
+#ifndef UNITTEST_TESTRESULTS_H
+#define UNITTEST_TESTRESULTS_H
+
+namespace UnitTest {
+
+class TestReporter;
+class TestDetails;
+
+class TestResults
+{
+public:
+    explicit TestResults(TestReporter* reporter = 0);
+
+    void OnTestStart(TestDetails const& test);
+    void OnTestFailure(TestDetails const& test, char const* failure);
+    void OnTestFinish(TestDetails const& test, float secondsElapsed);
+
+    int GetTotalTestCount() const;
+    int GetFailedTestCount() const;
+    int GetFailureCount() const;
+
+private:
+    TestReporter* m_testReporter;
+    int m_totalTestCount;
+    int m_failedTestCount;
+    int m_failureCount;
+
+    bool m_currentTestFailed;
+
+    TestResults(TestResults const&);
+    TestResults& operator =(TestResults const&);
+};
+
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/UnitTest++/src/TestRunner.cpp	Wed Nov 21 12:37:38 2012 -0500
@@ -0,0 +1,76 @@
+#include "TestRunner.h"
+#include "TestResults.h"
+#include "TestReporter.h"
+#include "TestReporterStdout.h"
+#include "TimeHelpers.h"
+#include "MemoryOutStream.h"
+
+#include <cstring>
+
+
+namespace UnitTest {
+
+int RunAllTests()
+{
+	TestReporterStdout reporter;
+	TestRunner runner(reporter);
+	return runner.RunTestsIf(Test::GetTestList(), NULL, True(), 0);
+}
+
+
+TestRunner::TestRunner(TestReporter& reporter)
+	: m_reporter(&reporter)
+	, m_result(new TestResults(&reporter))
+	, m_timer(new Timer)
+{
+	m_timer->Start();
+}
+
+TestRunner::~TestRunner()
+{
+	delete m_result;
+	delete m_timer;
+}
+
+int TestRunner::Finish() const
+{
+    float const secondsElapsed = m_timer->GetTimeInMs() / 1000.0f;
+    m_reporter->ReportSummary(m_result->GetTotalTestCount(), 
+							  m_result->GetFailedTestCount(), 
+							  m_result->GetFailureCount(), 
+							  secondsElapsed);
+    
+	return m_result->GetFailureCount();
+}
+
+bool TestRunner::IsTestInSuite(const Test* const curTest, char const* suiteName) const
+{
+	using namespace std;
+	return (suiteName == NULL) || !strcmp(curTest->m_details.suiteName, suiteName);
+}
+
+void TestRunner::RunTest(TestResults* const result, Test* const curTest, int const maxTestTimeInMs) const
+{
+	CurrentTest::Results() = result;
+
+	Timer testTimer;
+	testTimer.Start();
+
+	result->OnTestStart(curTest->m_details);
+
+	curTest->Run();
+
+	int const testTimeInMs = testTimer.GetTimeInMs();
+	if (maxTestTimeInMs > 0 && testTimeInMs > maxTestTimeInMs && !curTest->m_timeConstraintExempt)
+	{
+	    MemoryOutStream stream;
+	    stream << "Global time constraint failed. Expected under " << maxTestTimeInMs <<
+	            "ms but took " << testTimeInMs << "ms.";
+
+	    result->OnTestFailure(curTest->m_details, stream.GetText());
+	}
+
+	result->OnTestFinish(curTest->m_details, testTimeInMs/1000.0f);
+}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/UnitTest++/src/TestRunner.h	Wed Nov 21 12:37:38 2012 -0500
@@ -0,0 +1,61 @@
+#ifndef UNITTEST_TESTRUNNER_H
+#define UNITTEST_TESTRUNNER_H
+
+#include "Test.h"
+#include "TestList.h"
+#include "CurrentTest.h"
+
+namespace UnitTest {
+
+class TestReporter;
+class TestResults;
+class Timer;
+
+int RunAllTests();
+
+struct True
+{
+	bool operator()(const Test* const) const
+	{
+		return true;	
+	}
+};
+
+class TestRunner
+{
+public:
+	explicit TestRunner(TestReporter& reporter);
+	~TestRunner();
+
+	template <class Predicate>
+	int RunTestsIf(TestList const& list, char const* suiteName, 
+				   const Predicate& predicate, int maxTestTimeInMs) const
+	{
+	    Test* curTest = list.GetHead();
+
+	    while (curTest != 0)
+	    {
+		    if (IsTestInSuite(curTest,suiteName) && predicate(curTest))
+			{
+				RunTest(m_result, curTest, maxTestTimeInMs);
+			}
+
+			curTest = curTest->next;
+	    }
+
+	    return Finish();
+	}	
+
+private:
+	TestReporter* m_reporter;
+	TestResults* m_result;
+	Timer* m_timer;
+
+	int Finish() const;
+	bool IsTestInSuite(const Test* const curTest, char const* suiteName) const;
+	void RunTest(TestResults* const result, Test* const curTest, int const maxTestTimeInMs) const;
+};
+
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/UnitTest++/src/TestSuite.h	Wed Nov 21 12:37:38 2012 -0500
@@ -0,0 +1,14 @@
+#ifndef UNITTEST_TESTSUITE_H
+#define UNITTEST_TESTSUITE_H
+
+namespace UnitTestSuite {
+
+    inline char const* GetSuiteName ()
+    {
+        return "DefaultSuite";
+    }
+
+}
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/UnitTest++/src/TimeConstraint.cpp	Wed Nov 21 12:37:38 2012 -0500
@@ -0,0 +1,29 @@
+#include "TimeConstraint.h"
+#include "TestResults.h"
+#include "MemoryOutStream.h"
+#include "CurrentTest.h"
+
+namespace UnitTest {
+
+
+TimeConstraint::TimeConstraint(int ms, TestDetails const& details)
+	: m_details(details)
+    , m_maxMs(ms)
+{
+    m_timer.Start();
+}
+
+TimeConstraint::~TimeConstraint()
+{
+    int const totalTimeInMs = m_timer.GetTimeInMs();
+    if (totalTimeInMs > m_maxMs)
+    {
+        MemoryOutStream stream;
+        stream << "Time constraint failed. Expected to run test under " << m_maxMs <<
+                  "ms but took " << totalTimeInMs << "ms.";
+
+		UnitTest::CurrentTest::Results()->OnTestFailure(m_details, stream.GetText());
+    }
+}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/UnitTest++/src/TimeConstraint.h	Wed Nov 21 12:37:38 2012 -0500
@@ -0,0 +1,33 @@
+#ifndef UNITTEST_TIMECONSTRAINT_H
+#define UNITTEST_TIMECONSTRAINT_H
+
+#include "TimeHelpers.h"
+
+namespace UnitTest {
+
+class TestResults;
+class TestDetails;
+
+class TimeConstraint
+{
+public:
+    TimeConstraint(int ms, TestDetails const& details);
+    ~TimeConstraint();
+
+private:
+    void operator=(TimeConstraint const&); 
+	TimeConstraint(TimeConstraint const&);
+
+	Timer m_timer;
+    TestDetails const& m_details;
+	int const m_maxMs;
+};
+
+#define UNITTEST_TIME_CONSTRAINT(ms) \
+	UnitTest::TimeConstraint unitTest__timeConstraint__(ms, UnitTest::TestDetails(m_details, __LINE__))
+
+#define UNITTEST_TIME_CONSTRAINT_EXEMPT() do { m_timeConstraintExempt = true; } while (0)
+
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/UnitTest++/src/TimeHelpers.h	Wed Nov 21 12:37:38 2012 -0500
@@ -0,0 +1,7 @@
+#include "Config.h"
+
+#if defined UNITTEST_POSIX
+    #include "Posix/TimeHelpers.h"
+#else
+    #include "Win32/TimeHelpers.h"
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/UnitTest++/src/UnitTest++.h	Wed Nov 21 12:37:38 2012 -0500
@@ -0,0 +1,18 @@
+#ifndef UNITTESTCPP_H
+#define UNITTESTCPP_H
+
+//lint -esym(1509,*Fixture)
+
+#include "Config.h"
+#include "Test.h"
+#include "TestList.h"
+#include "TestSuite.h"
+#include "TestResults.h"
+
+#include "TestMacros.h"
+
+#include "CheckMacros.h"
+#include "TestRunner.h"
+#include "TimeConstraint.h"
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/UnitTest++/src/XmlTestReporter.cpp	Wed Nov 21 12:37:38 2012 -0500
@@ -0,0 +1,127 @@
+#include "XmlTestReporter.h"
+#include "Config.h"
+
+#include <iostream>
+#include <sstream>
+#include <string>
+
+using std::string;
+using std::ostringstream;
+using std::ostream;
+
+namespace {
+
+void ReplaceChar(string& str, char c, string const& replacement)
+{
+    for (size_t pos = str.find(c); pos != string::npos; pos = str.find(c, pos + 1))
+        str.replace(pos, 1, replacement);
+}
+
+string XmlEscape(string const& value)
+{
+    string escaped = value;
+
+    ReplaceChar(escaped, '&', "&amp;");
+    ReplaceChar(escaped, '<', "&lt;");
+    ReplaceChar(escaped, '>', "&gt;");
+    ReplaceChar(escaped, '\'', "&apos;");
+    ReplaceChar(escaped, '\"', "&quot;");
+ 
+    return escaped;
+}
+
+string BuildFailureMessage(string const& file, int line, string const& message)
+{
+    ostringstream failureMessage;
+    failureMessage << file << "(" << line << ") : " << message;
+    return failureMessage.str();
+}
+
+}
+
+namespace UnitTest {
+
+XmlTestReporter::XmlTestReporter(ostream& ostream)
+    : m_ostream(ostream)
+{
+}
+
+void XmlTestReporter::ReportSummary(int totalTestCount, int failedTestCount,
+                                    int failureCount, float secondsElapsed)
+{
+    AddXmlElement(m_ostream, NULL);
+
+    BeginResults(m_ostream, totalTestCount, failedTestCount, failureCount, secondsElapsed);
+
+    DeferredTestResultList const& results = GetResults();
+    for (DeferredTestResultList::const_iterator i = results.begin(); i != results.end(); ++i)
+    {
+        BeginTest(m_ostream, *i);
+
+        if (i->failed)
+            AddFailure(m_ostream, *i);
+
+        EndTest(m_ostream, *i);
+    }
+
+    EndResults(m_ostream);
+}
+
+void XmlTestReporter::AddXmlElement(ostream& os, char const* encoding)
+{
+    os << "<?xml version=\"1.0\"";
+
+    if (encoding != NULL)
+        os << " encoding=\"" << encoding << "\"";
+
+    os << "?>";
+}
+
+void XmlTestReporter::BeginResults(std::ostream& os, int totalTestCount, int failedTestCount, 
+                                   int failureCount, float secondsElapsed)
+{
+   os << "<unittest-results"
+       << " tests=\"" << totalTestCount << "\"" 
+       << " failedtests=\"" << failedTestCount << "\"" 
+       << " failures=\"" << failureCount << "\"" 
+       << " time=\"" << secondsElapsed << "\""
+       << ">";
+}
+
+void XmlTestReporter::EndResults(std::ostream& os)
+{
+    os << "</unittest-results>";
+}
+
+void XmlTestReporter::BeginTest(std::ostream& os, DeferredTestResult const& result)
+{
+    os << "<test"
+        << " suite=\"" << result.suiteName << "\"" 
+        << " name=\"" << result.testName << "\""
+        << " time=\"" << result.timeElapsed << "\"";
+}
+
+void XmlTestReporter::EndTest(std::ostream& os, DeferredTestResult const& result)
+{
+    if (result.failed)
+        os << "</test>";
+    else
+        os << "/>";
+}
+
+void XmlTestReporter::AddFailure(std::ostream& os, DeferredTestResult const& result)
+{
+    os << ">"; // close <test> element
+
+    for (DeferredTestResult::FailureVec::const_iterator it = result.failures.begin(); 
+         it != result.failures.end(); 
+         ++it)
+    {
+        string const escapedMessage = XmlEscape(it->second);
+        string const message = BuildFailureMessage(result.failureFile, it->first, escapedMessage);
+
+        os << "<failure" << " message=\"" << message << "\"" << "/>";
+    }
+}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/UnitTest++/src/XmlTestReporter.h	Wed Nov 21 12:37:38 2012 -0500
@@ -0,0 +1,34 @@
+#ifndef UNITTEST_XMLTESTREPORTER_H
+#define UNITTEST_XMLTESTREPORTER_H
+
+#include "DeferredTestReporter.h"
+
+#include <iosfwd>
+
+namespace UnitTest
+{
+
+class XmlTestReporter : public DeferredTestReporter
+{
+public:
+    explicit XmlTestReporter(std::ostream& ostream);
+
+    virtual void ReportSummary(int totalTestCount, int failedTestCount, int failureCount, float secondsElapsed);
+
+private:
+    XmlTestReporter(XmlTestReporter const&);
+    XmlTestReporter& operator=(XmlTestReporter const&);
+
+    void AddXmlElement(std::ostream& os, char const* encoding);
+    void BeginResults(std::ostream& os, int totalTestCount, int failedTestCount, int failureCount, float secondsElapsed);
+    void EndResults(std::ostream& os);
+    void BeginTest(std::ostream& os, DeferredTestResult const& result);
+    void AddFailure(std::ostream& os, DeferredTestResult const& result);
+    void EndTest(std::ostream& os, DeferredTestResult const& result);
+
+    std::ostream& m_ostream;
+};
+
+}
+
+#endif