public bool RunStandardTestsAndGetResults(OriginalMethodCaller ofCaller, String category, String functionName,
                                                  Object[] param, Type returnType, ref Object returnValue, ref Exception exception)
        {
            IncrementCallLevel();

            bool shouldPauseApp      = false;
            bool runOriginalFunction = true;

            IntPtr newEvents      = ReplacementLibraryWrapper.CreateNewEventsArray();
            IntPtr previousEvents = ReplacementLibraryWrapper.InitNewEventsArrayAndSavePrevious(newEvents);

            bool   testMatches  = false;
            int    matchingTest = -1;
            IntPtr testList;

            IntPtr paramArrays = IntPtr.Zero;

            int typedArrayParams = ConvertParamsToTypedArrays(param, ref paramArrays);

            testList = ReplacementLibraryWrapper.GetFunctionTests(category.ToCharArray(), functionName.ToCharArray());
            if (testList != IntPtr.Zero)
            {
                testMatches = DoesTestMatch(typedArrayParams, paramArrays, testList,
                                            ref exception, returnType, ref returnValue, ref matchingTest);
            }

            //If matching test was found then Check Firing Specification
            if (testMatches)
            {
                int result = this.CheckFiringSpecification(testList, matchingTest);
                switch (result)
                {
                case -1:
                    runOriginalFunction = true;
                    shouldPauseApp      = false;
                    break;

                case 0:
                    runOriginalFunction = false;
                    shouldPauseApp      = false;
                    break;

                case 1:
                    runOriginalFunction = false;
                    shouldPauseApp      = true;
                    break;
                }
            }

            bool loggingEnabled = ReplacementLibraryWrapper.IsFunctionLoggingEnabled(category.ToCharArray(), functionName.ToCharArray());
            bool parentLogged   = ReplacementLibraryWrapper.IsParentLogged();

            if (!parentLogged)
            {
                // If parent is not logged, do not log this function either
                loggingEnabled = false;
            }

            ReplacementLibraryWrapper.SetParentLogged(loggingEnabled);

            if (runOriginalFunction)
            {
                ofCaller(param, ref returnValue, ref exception);
            }
            else
            {
                if (matchingTest != -1)
                {
                    ReplacementLibraryWrapper.IncrementTestExecutionCount(testList, matchingTest);
                }
            }

            //If AUT should be paused after this test then set the pause event in the current LogEntry
            if (!runOriginalFunction && shouldPauseApp)
            {
                ReplacementLibraryWrapper.SetPauseEventInLogEntry();
            }

            if (matchingTest != -1)
            {
                ModifyChangeParameters(typedArrayParams, paramArrays, testList, matchingTest);
            }

            if (loggingEnabled)
            {
                SendLog(category, functionName, typedArrayParams, paramArrays, exception, returnValue, newEvents);
            }

            //If the app is going to be paused the flush the log now
            if (!runOriginalFunction && shouldPauseApp)
            {
                //Flush the log
                ReplacementLibraryWrapper.FlushLog();
            }

            // Restore original parent logging value
            ReplacementLibraryWrapper.SetParentLogged(parentLogged);

            ReplacementLibraryWrapper.RestorePreviousEventsArray(previousEvents);
            ReplacementLibraryWrapper.DeleteEventArray(newEvents);

            if (testList != IntPtr.Zero)
            {
                ReplacementLibraryWrapper.FreeFunctionTests(testList);
            }
            FreeParamTypedArrays(typedArrayParams, paramArrays);

            DecrementCallLevel();

            //Performing app pause here
            if (!runOriginalFunction && shouldPauseApp)
            {
                ReplacementLibraryWrapper.SuspendProcess();
            }

            return(!runOriginalFunction);
        }
        public bool RunStandardTestsAndGetResults(OriginalMethodCaller ofCaller, String category, String functionName,
            Object[] param, Type returnType, ref Object returnValue, ref Exception exception)
        {
            IncrementCallLevel();

            bool shouldPauseApp = false;
            bool runOriginalFunction = true;

            IntPtr newEvents = ReplacementLibraryWrapper.CreateNewEventsArray ();
            IntPtr previousEvents = ReplacementLibraryWrapper.InitNewEventsArrayAndSavePrevious (newEvents);

            bool testMatches = false;
            int matchingTest = -1;
            IntPtr testList;

            IntPtr paramArrays = IntPtr.Zero;

            int typedArrayParams = ConvertParamsToTypedArrays(param, ref paramArrays);

            testList = ReplacementLibraryWrapper.GetFunctionTests(category.ToCharArray(), functionName.ToCharArray());
            if (testList != IntPtr.Zero)
            {
                testMatches = DoesTestMatch(typedArrayParams, paramArrays, testList,
                    ref exception, returnType, ref returnValue, ref matchingTest);
            }

            //If matching test was found then Check Firing Specification
            if (testMatches)
            {
                int result = this.CheckFiringSpecification (testList, matchingTest);
                switch (result)
                {
                    case -1:
                        runOriginalFunction = true;
                        shouldPauseApp  = false;
                        break;
                    case 0:
                        runOriginalFunction = false;
                        shouldPauseApp = false;
                        break;
                    case 1:
                        runOriginalFunction = false;
                        shouldPauseApp = true;
                        break;
                }
            }

            bool loggingEnabled = ReplacementLibraryWrapper.IsFunctionLoggingEnabled(category.ToCharArray(), functionName.ToCharArray());
            bool parentLogged = ReplacementLibraryWrapper.IsParentLogged();

            if (!parentLogged)
            {
                // If parent is not logged, do not log this function either
                loggingEnabled = false;
            }

            ReplacementLibraryWrapper.SetParentLogged(loggingEnabled);

            if (runOriginalFunction)
                ofCaller(param, ref returnValue, ref exception);
            else
            {
                if (matchingTest != -1)
                {
                    ReplacementLibraryWrapper.IncrementTestExecutionCount(testList, matchingTest);
                }
            }

            //If AUT should be paused after this test then set the pause event in the current LogEntry
            if (!runOriginalFunction && shouldPauseApp)
            {
                ReplacementLibraryWrapper.SetPauseEventInLogEntry();
            }

            if (matchingTest != -1)
                ModifyChangeParameters(typedArrayParams, paramArrays, testList, matchingTest);

            if (loggingEnabled)
                SendLog(category, functionName, typedArrayParams, paramArrays, exception, returnValue, newEvents);

            //If the app is going to be paused the flush the log now
            if (!runOriginalFunction && shouldPauseApp)
            {
                //Flush the log
                ReplacementLibraryWrapper.FlushLog();
            }

            // Restore original parent logging value
            ReplacementLibraryWrapper.SetParentLogged(parentLogged);

            ReplacementLibraryWrapper.RestorePreviousEventsArray (previousEvents);
            ReplacementLibraryWrapper.DeleteEventArray(newEvents);

            if (testList != IntPtr.Zero)
                ReplacementLibraryWrapper.FreeFunctionTests(testList);
            FreeParamTypedArrays(typedArrayParams, paramArrays);

            DecrementCallLevel();

            //Performing app pause here
            if (!runOriginalFunction && shouldPauseApp)
            {
                ReplacementLibraryWrapper.SuspendProcess();
            }

            return (!runOriginalFunction);
        }