/// <summary>
 /// Process a instrumentation run failure
 /// </summary>
 internal virtual void handleTestRunFailed(string errorMsg)
 {
     errorMsg = (errorMsg == null ? "Unknown error" : errorMsg);
     Log.i(LOG_TAG, string.Format("test run failed: '{0}'", errorMsg));
     if (mLastTestResult != null && mLastTestResult.complete && StatusCodes.START == mLastTestResult.mCode)
     {
         // received test start msg, but not test complete
         // assume test caused this, report as test failure
         TestIdentifier testId = new TestIdentifier(mLastTestResult.mTestClass, mLastTestResult.mTestName);
         foreach (ITestRunListener listener in mTestListeners)
         {
             listener.testFailed(TestFailure.ERROR, testId, string.Format("{0}. Reason: '{1}'. {2}", INCOMPLETE_TEST_ERR_MSG_PREFIX, errorMsg, INCOMPLETE_TEST_ERR_MSG_POSTFIX));
             listener.testEnded(testId, andResetTestMetrics);
         }
     }
     foreach (ITestRunListener listener in mTestListeners)
     {
         if (!mTestStartReported)
         {
             // test run wasn't started - must have crashed before it started
             listener.testRunStarted(mTestRunName, 0);
         }
         listener.testRunFailed(errorMsg);
         listener.testRunEnded(mTestTime, mInstrumentationResultBundle);
     }
     mTestStartReported   = true;
     mTestRunFailReported = true;
 }
        /// <summary>
        /// Reports a test result to the test run listener. Must be called when a individual test
        /// result has been fully parsed.
        /// </summary>
        /// <param name="statusMap"> key-value status pairs of test result </param>
        private void reportResult(TestResult testInfo)
        {
            if (!testInfo.complete)
            {
                Log.w(LOG_TAG, "invalid instrumentation status bundle " + testInfo.ToString());
                return;
            }
            reportTestRunStarted(testInfo);
            TestIdentifier testId = new TestIdentifier(testInfo.mTestClass, testInfo.mTestName);
            IDictionary<string, string> metrics;

            switch (testInfo.mCode)
            {
                case StatusCodes.START:
                    foreach (ITestRunListener listener in mTestListeners)
                    {
                        listener.testStarted(testId);
                    }
                    break;
                case StatusCodes.FAILURE:
                    metrics = andResetTestMetrics;
                    foreach (ITestRunListener listener in mTestListeners)
                    {
                        listener.testFailed(TestFailure.FAILURE, testId, getTrace(testInfo));

                        listener.testEnded(testId, metrics);
                    }
                    mNumTestsRun++;
                    break;
                case StatusCodes.ERROR:
                    metrics = andResetTestMetrics;
                    foreach (ITestRunListener listener in mTestListeners)
                    {
                        listener.testFailed(TestFailure.ERROR, testId, getTrace(testInfo));
                        listener.testEnded(testId, metrics);
                    }
                    mNumTestsRun++;
                    break;
                case StatusCodes.OK:
                    metrics = andResetTestMetrics;
                    foreach (ITestRunListener listener in mTestListeners)
                    {
                        listener.testEnded(testId, metrics);
                    }
                    mNumTestsRun++;
                    break;
                default:
                    metrics = andResetTestMetrics;
                    Log.e(LOG_TAG, "Unknown status code received: " + testInfo.mCode);
                    foreach (ITestRunListener listener in mTestListeners)
                    {
                        listener.testEnded(testId, metrics);
                    }
                    mNumTestsRun++;
                    break;
            }
        }
        /// <summary>
        /// Reports a test result to the test run listener. Must be called when a individual test
        /// result has been fully parsed.
        /// </summary>
        /// <param name="statusMap"> key-value status pairs of test result </param>
        private void reportResult(TestResult testInfo)
        {
            if (!testInfo.complete)
            {
                Log.w(LOG_TAG, "invalid instrumentation status bundle " + testInfo.ToString());
                return;
            }
            reportTestRunStarted(testInfo);
            TestIdentifier testId = new TestIdentifier(testInfo.mTestClass, testInfo.mTestName);
            IDictionary <string, string> metrics;

            switch (testInfo.mCode)
            {
            case StatusCodes.START:
                foreach (ITestRunListener listener in mTestListeners)
                {
                    listener.testStarted(testId);
                }
                break;

            case StatusCodes.FAILURE:
                metrics = andResetTestMetrics;
                foreach (ITestRunListener listener in mTestListeners)
                {
                    listener.testFailed(TestFailure.FAILURE, testId, getTrace(testInfo));

                    listener.testEnded(testId, metrics);
                }
                mNumTestsRun++;
                break;

            case StatusCodes.ERROR:
                metrics = andResetTestMetrics;
                foreach (ITestRunListener listener in mTestListeners)
                {
                    listener.testFailed(TestFailure.ERROR, testId, getTrace(testInfo));
                    listener.testEnded(testId, metrics);
                }
                mNumTestsRun++;
                break;

            case StatusCodes.OK:
                metrics = andResetTestMetrics;
                foreach (ITestRunListener listener in mTestListeners)
                {
                    listener.testEnded(testId, metrics);
                }
                mNumTestsRun++;
                break;

            default:
                metrics = andResetTestMetrics;
                Log.e(LOG_TAG, "Unknown status code received: " + testInfo.mCode);
                foreach (ITestRunListener listener in mTestListeners)
                {
                    listener.testEnded(testId, metrics);
                }
                mNumTestsRun++;
                break;
            }
        }
        /// <summary>
        /// Process a instrumentation run failure
        /// </summary>
        internal virtual void handleTestRunFailed(string errorMsg)
        {
            errorMsg = (errorMsg == null ? "Unknown error" : errorMsg);
            Log.i(LOG_TAG, string.Format("test run failed: '{0}'", errorMsg));
            if (mLastTestResult != null && mLastTestResult.complete && StatusCodes.START == mLastTestResult.mCode)
            {

                // received test start msg, but not test complete
                // assume test caused this, report as test failure
                TestIdentifier testId = new TestIdentifier(mLastTestResult.mTestClass, mLastTestResult.mTestName);
                foreach (ITestRunListener listener in mTestListeners)
                {
                    listener.testFailed(TestFailure.ERROR, testId, string.Format("{0}. Reason: '{1}'. {2}", INCOMPLETE_TEST_ERR_MSG_PREFIX, errorMsg, INCOMPLETE_TEST_ERR_MSG_POSTFIX));
                    listener.testEnded(testId, andResetTestMetrics);
                }
            }
            foreach (ITestRunListener listener in mTestListeners)
            {
                if (!mTestStartReported)
                {
                    // test run wasn't started - must have crashed before it started
                    listener.testRunStarted(mTestRunName, 0);
                }
                listener.testRunFailed(errorMsg);
                listener.testRunEnded(mTestTime, mInstrumentationResultBundle);
            }
            mTestStartReported = true;
            mTestRunFailReported = true;
        }