public int Run()
    {
        int state;
        int tc_index;

        Console.WriteLine("Discovering tests...");

        int n = 0;

        while (n < 20)
        {
            bool res = discoverer.Step();
            if (!res)
            {
                break;
            }
        }

        Console.WriteLine("Running " + testCases.Count + " tests...");
        state    = 3;
        tc_index = 0;

        Console.WriteLine(".");
        int    ncases    = 0;
        string last_name = "";

        while (true)
        {
            if (tc_index == testCases.Count)
            {
                break;
            }
            var tc = testCases [tc_index] as XunitTestCase;

            tc_index++;

            if (!project.Filters.Filter(tc))
            {
                nfiltered++;
                continue;
            }

            // var itrait_attrs = tc.TestMethod.Method.GetCustomAttributes(typeof(ITraitAttribute));
            // // FIXME:
            // if (itrait_attrs.Count () > 0) {
            //  Console.WriteLine ("SKIP (ITraitAttribute): " + tc.DisplayName);
            //  nfiltered ++;
            //  continue;
            // }

            /*
             * foreach (var attr in itrait_attrs) {
             *      Console.WriteLine (attr);
             *      foreach (var disc_attr in attr.GetCustomAttributes (typeof (TraitDiscovererAttribute))) {
             *              Console.WriteLine (disc_attr);
             *
             *      }
             * }
             */

            var method = (tc.Method as ReflectionMethodInfo).MethodInfo;

            if (method.ReflectedType.IsGenericTypeDefinition)
            {
                Console.WriteLine("FAIL (generic): " + tc.DisplayName);
                nfail++;
                continue;
            }

            if (tc is Xunit.Sdk.XunitTheoryTestCase)
            {
                if (method.IsGenericMethod)
                {
                    Console.WriteLine("SKIP (generic): " + tc.DisplayName);
                    nfiltered++;
                    continue;
                }

                // From XunitTheoryTestCaseRunner
                var  attrs  = tc.TestMethod.Method.GetCustomAttributes(typeof(DataAttribute));
                bool failed = false;
                foreach (var dataAttribute in attrs)
                {
                    var discovererAttribute = dataAttribute.GetCustomAttributes(typeof(DataDiscovererAttribute)).First();
                    var args = discovererAttribute.GetConstructorArguments().Cast <string>().ToList();

                    Type discovererType = null;
                    if (args [1] == "xunit.core")
                    {
                        discovererType = typeof(IXunitTestCollectionFactory).Assembly.GetType(args [0]);
                    }
                    if (discovererType == null)
                    {
                        Console.WriteLine("FAIL (discoverer): " + args [0] + " " + args [1]);
                        failed = true;
                    }

                    IDataDiscoverer discoverer;
                    discoverer = ExtensibilityPointFactory.GetDataDiscoverer(this, discovererType);

                    try {
                        var data     = discoverer.GetData(dataAttribute, tc.TestMethod.Method);
                        var data_arr = data.ToArray();
                        Console.WriteLine(tc.DisplayName + " [" + data_arr.Length + "]");
                        foreach (var dataRow in data_arr)
                        {
                            nrun++;
                            object obj = null;
                            if (!method.IsStatic)
                            {
                                var constructor = method.ReflectedType.GetConstructor(Type.EmptyTypes);
                                if (constructor != null)
                                {
                                    obj = constructor.Invoke(null);
                                }
                                else
                                {
                                    obj = System.Runtime.Serialization.FormatterServices.GetUninitializedObject(method.ReflectedType);
                                }
                            }

                            var pars = method.GetParameters();
                            for (int i = 0; i < dataRow.Length; ++i)
                            {
                                dataRow [i] = ConvertArg(dataRow [i], pars [i].ParameterType);
                            }
                            method.Invoke(obj, BindingFlags.Default, null, dataRow, null);
                        }
                    } catch (Exception ex) {
                        Console.WriteLine("FAIL: " + tc.DisplayName + " " + ex);
                        failed = true;
                    }
                }
                if (failed)
                {
                    nfail++;
                    continue;
                }
            }
            else
            {
                if (!String.IsNullOrEmpty(tc.SkipReason))
                {
                    nskipped++;
                    continue;
                }
                nrun++;
                var name = tc.DisplayName;
                if (name.Contains("("))
                {
                    name = name.Substring(0, name.IndexOf("("));
                }
                if (name != last_name)
                {
                    Console.WriteLine(name);
                }
                last_name = name;
                //Console.WriteLine (tc.DisplayName);
                try {
                    object obj = null;
                    if (!method.IsStatic)
                    {
                        var constructor = method.ReflectedType.GetConstructor(Type.EmptyTypes);
                        if (constructor != null)
                        {
                            obj = constructor.Invoke(null);
                        }
                        else
                        {
                            obj = System.Runtime.Serialization.FormatterServices.GetUninitializedObject(method.ReflectedType);
                        }
                    }
                    var args = tc.TestMethodArguments;
                    if (args != null)
                    {
                        var pars = method.GetParameters();
                        for (int i = 0; i < args.Length; ++i)
                        {
                            args [i] = ConvertArg(args [i], pars [i].ParameterType);
                        }
                    }
                    method.Invoke(obj, args);
                } catch (Exception ex) {
                    Console.WriteLine("FAIL: " + tc.DisplayName);
                    Console.WriteLine(ex);
                    nfail++;
                }
            }
        }

        //foreach (var tc in testCases)
        //	Console.WriteLine (tc.DisplayName);
        //executor.RunTests (testCases, this, executionOptions);
        Console.WriteLine("TESTS = " + testCases.Count + ", RUN = " + nrun + ", SKIP = " + nfiltered + ", FAIL = " + nfail);
        return(nfail == 0 ? 0 : 1);
    }