 
 // -----------------------------------------------------------------------------
 
+BEGIN_MIDI_NAMESPACE
+
+class TestFixture
+{
+public:
+    typedef const char* String;
+    typedef bool (*Functor) (void);
+    
+public:
+    TestFixture(String inTestName, 
+                Functor inFunctor)
+        : mTestName(inTestName)
+        , mFunctor(inFunctor)
+    {
+    }
+    
+public:
+    inline bool operator() (void)
+    {
+        return mFunctor();
+    }
+    
+    inline String getName() const
+    {
+        return mTestName;
+    }
+    
+private:
+    String mTestName;
+    Functor mFunctor;
+};
+
+// -----------------------------------------------------------------------------
+
+template<class SerialPort>
+class MidiTester
+{
+public:
+    explicit MidiTester(MidiInterface<SerialPort>& inInstance)
+        : mInstance(inInstance)
+    {
+    }
+    
+    virtual ~MidiTester()
+    {
+    }
+    
+public:
+    inline bool performTestFixture(TestFixture* inFixture)
+    {
+        if (inFixture != 0)
+        {
+            return (*inFixture)();
+        }
+        return false;
+    }
+    
+    inline bool expect(bool inCondition) const
+    {
+        if (inCondition == false)
+            blinkFail();
+        else
+            blinkPass();
+        return inCondition;
+    }
+    
+public:
+    inline void registerTest(TestFixture* inFixture)
+    {
+        mTests[mNumActiveTests++] = inFixture;
+    }
+    
+    bool runTests()
+    {
+        for (unsigned i = 0; i < mNumActiveTests; ++i)
+        {
+            if (mTests[i] != 0)
+            {
+                if (expect(performTestFixture(mTests[i]) == false))
+                {
+                    // \todo Display message
+                    // \todo Store error number and continue.
+                    return false;
+                }
+            }
+            setProgressBar(i, mNumActiveTests);
+        }
+        return true;
+    }
+    
+private:
+    MidiInterface<SerialPort>& mInstance;
+    TestFixture* mTests[NUM_TESTS];
+    unsigned mNumActiveTests;
+};
+
+// -----------------------------------------------------------------------------
+
+bool testNoteOn()
+{
+    return true;
+}
+
+// -----------------------------------------------------------------------------
+
+END_MIDI_NAMESPACE
+
+midi::MidiTester<HardwareSerial> testerHW(midiHW);
+midi::MidiTester<SoftwareSerial> testerSW(midiSW);
+
+// -----------------------------------------------------------------------------
+
 template<class SerialClass>
 void setupMidiInstance(midi::MidiInterface<SerialClass>& inInstance)
 {

#define LED_PASS        4
#define LED_FAIL        5

// -----------------------------------------------------------------------------

SoftwareSerial softSerial(2, 3);

    setupMidiInstance<SoftwareSerial>(midiSW);
    setupLCD();
    setupLEDs();
    setupTesters();
}

// -----------------------------------------------------------------------------

void loop()
{
    testerHW.runTests();
    testerSW.runTests();
}
