/// <summary>
        /// The method that gets called when a test is executed
        /// </summary>
        /// <param name="args">arguments that are passed from the test signature</param>
        /// <returns></returns>
        public TestMethodInvokerResult Invoke(params object[] args)
        {
            // Our helper results class to aggregate our test results
            // Make sure we dispose it when done to get rid of our XmlTextWriter
            using (HelperTestGridResults results = new HelperTestGridResults(this.invokerContext.TestMethodInfo))
            {
                Assembly testMethodAssembly = this.invokerContext.TestMethodInfo.DeclaringType.Assembly;

                // Gets the custom attribute off the method
                RowAttribute[] rows = (RowAttribute[])this.invokerContext.TestMethodInfo.GetCustomAttributes(typeof(RowAttribute), false);

                IList<RowFilterAttribute> rowFilters = AttributeHelper.GetCustomAttributes<RowFilterAttribute>(this.invokerContext.TestMethodInfo, true);

                IList<TestExecutionAttribute> testExecutionAttributes = AttributeHelper.GetCustomAttributes<TestExecutionAttribute>(this.invokerContext.TestMethodInfo, true);
                TestExecutionAttribute testExecutionAggregateAttr = TestExecutionAttribute.Aggregate(testExecutionAttributes);

                Log.LogWriter logWriter = CreateLogWriter(testExecutionAggregateAttr);

                SetExpandedPaths(rows, this.invokerContext);
                IEnumerable<DataRowValues> dataRowValuesCollection = GetAllDataRowValues(rows, this.invokerContext, results);

                IEnumerable<RowTestContext> inputRowContexts = dataRowValuesCollection.Select(dataRowValues =>
                    {
                        object[] valuesArray = results.PrepareRowValues(dataRowValues);

                        RowTestContext rowTestContext = new RowTestContext(dataRowValues)
                        {
                            LogType = testExecutionAggregateAttr.LogType,
                            LogContentType = testExecutionAggregateAttr.LogContentType,
                            LogWriter = logWriter,
                            WriteHeaders = testExecutionAggregateAttr.WriteHeaders,
                            ValuesArray = valuesArray,
                            TestExecutionAttributes = testExecutionAttributes
                        };

                        PopulateRowSkippedInfo(invokerContext, rowTestContext, rowFilters);

                        return rowTestContext;
                    });

                IEnumerable<RowTestContext> outputRowContexts;

                if (testExecutionAggregateAttr.ExecuteInParallel)
                {
                    ParallelQuery<RowTestContext> query = inputRowContexts.AsParallel().AsOrdered();
                    if (testExecutionAggregateAttr.MaxDegreeOfParallelism > 0)
                    {
                        query = query.WithDegreeOfParallelism(testExecutionAggregateAttr.MaxDegreeOfParallelism);
                    }

                    outputRowContexts = query.Select(this.InvokeSingleRow);
                }
                else
                {
                    outputRowContexts = inputRowContexts.Select(this.InvokeSingleRow);
                }

                // enumerate row data and invoke the test case with each yield they give us
                foreach (RowTestContext rowTestContext in outputRowContexts)
                {
                    // Add results to our aggregator if it is either executed, or skipped but we are showing skipped rows in results
                    if (!rowTestContext.Ignored || rowTestContext.ShowSkipped)
                    {
                        results.AddTestResult(rowTestContext);
                    }
                }

                // Return the aggregated results for the row variatons in the TestMethod
                return results.GetAllResults();
            }
        }