private static void TestThreadStateProperty()
    {
        var t_event = new AutoResetEvent(false);
        var t       = new Thread(() => t_event.WaitOne());

        Expect(t.ThreadState == ThreadState.Unstarted, "Expected t.ThreadState == ThreadState.Unstarted");
        t.Start();
        s_startedThreads.Add(t);

        Expect(t.ThreadState == ThreadState.Running || t.ThreadState == ThreadState.WaitSleepJoin,
               "Expected t.ThreadState is either ThreadState.Running or ThreadState.WaitSleepJoin");
        t_event.Set();
        t.Join();
        Expect(t.ThreadState == ThreadState.Stopped, "Expected t.ThreadState == ThreadState.Stopped");

        // Resurrected threads
        Thread unstartedResurrected = Resurrector.CreateUnstartedResurrected();

        Expect(unstartedResurrected.ThreadState == ThreadState.Unstarted,
               "Expected unstartedResurrected.ThreadState == ThreadState.Unstarted");

        Thread stoppedResurrected = Resurrector.CreateStoppedResurrected();

        Expect(stoppedResurrected.ThreadState == ThreadState.Stopped,
               "Expected stoppedResurrected.ThreadState == ThreadState.Stopped");

        ExpectPassed(nameof(TestThreadStateProperty), 5);
    }
    private static void TestManagedThreadIdProperty()
    {
        int t_id = 0;
        var t    = new Thread(() => {
            Expect(Thread.CurrentThread.ManagedThreadId == t_id, "Expected CurrentTread.ManagedThreadId == t_id on thread t");
            Expect(Environment.CurrentManagedThreadId == t_id, "Expected Environment.CurrentManagedThreadId == t_id on thread t");
        });

        t_id = t.ManagedThreadId;
        Expect(t_id != 0, "Expected t_id != 0");
        Expect(Thread.CurrentThread.ManagedThreadId != t_id, "Expected CurrentTread.ManagedThreadId != t_id on main thread");
        Expect(Environment.CurrentManagedThreadId != t_id, "Expected Environment.CurrentManagedThreadId != t_id on main thread");

        t.Start();
        s_startedThreads.Add(t);

        // Resurrected threads
        Thread unstartedResurrected = Resurrector.CreateUnstartedResurrected();

        Expect(unstartedResurrected.ManagedThreadId != 0, "Expected unstartedResurrected.ManagedThreadId != 0");

        Thread stoppedResurrected = Resurrector.CreateStoppedResurrected();

        Expect(stoppedResurrected.ManagedThreadId != 0, "Expected stoppedResurrected.ManagedThreadId != 0");

        ExpectPassed(nameof(TestManagedThreadIdProperty), 7);
    }
    private static void TestIsBackgroundProperty()
    {
        // Thread created using Thread.Start
        var t_event = new AutoResetEvent(false);
        var t       = new Thread(() => t_event.WaitOne());

        t.Start();
        s_startedThreads.Add(t);

        Expect(!t.IsBackground, "Expected t.IsBackground == false");
        t_event.Set();
        t.Join();
        ExpectException <ThreadStateException>(() => Console.WriteLine(t.IsBackground),
                                               "Expected ThreadStateException for t.IsBackground");

        // Thread pool thread
        Task.Factory.StartNew(() => Expect(Thread.CurrentThread.IsBackground, "Expected IsBackground == true")).Wait();

        // Resurrected threads
        Thread unstartedResurrected = Resurrector.CreateUnstartedResurrected();

        Expect(unstartedResurrected.IsBackground == false, "Expected unstartedResurrected.IsBackground == false");

        Thread stoppedResurrected = Resurrector.CreateStoppedResurrected();

        ExpectException <ThreadStateException>(() => Console.WriteLine(stoppedResurrected.IsBackground),
                                               "Expected ThreadStateException for stoppedResurrected.IsBackground");

        // Main thread
        Expect(!Thread.CurrentThread.IsBackground, "Expected CurrentThread.IsBackground == false");

        ExpectPassed(nameof(TestIsBackgroundProperty), 6);
    }
    private static void TestJoinMethod()
    {
        var t = new Thread(() => { });

        ExpectException <InvalidOperationException>(() => t.Start(null), "Expected InvalidOperationException for t.Start()");
        ExpectException <ThreadStateException>(() => t.Join(), "Expected ThreadStateException for t.Join()");

        Thread stoppedResurrected = Resurrector.CreateStoppedResurrected();

        Expect(stoppedResurrected.Join(1), "Expected stoppedResurrected.Join(1) to return true");

        Expect(!Thread.CurrentThread.Join(1), "Expected CurrentThread.Join(1) to return false");

        ExpectPassed(nameof(TestJoinMethod), 4);
    }
    private static void TestStartMethod()
    {
        // Case 1: new Thread(ThreadStart).Start()
        var t1 = new Thread(() => Expect(true, "Expected t1 to start"));

        t1.Start();
        s_startedThreads.Add(t1);

        // Case 2: new Thread(ThreadStart).Start(parameter)
        var t2 = new Thread(() => Expect(false, "This thread must not be started"));

        // InvalidOperationException: The thread was created with a ThreadStart delegate that does not accept a parameter.
        ExpectException <InvalidOperationException>(() => t2.Start(null), "Expected InvalidOperationException for t2.Start()");

        // Case 3: new Thread(ParameterizedThreadStart).Start()
        var t3 = new Thread(obj => Expect(obj == null, "Expected obj == null"));

        t3.Start();
        s_startedThreads.Add(t3);

        // Case 4: new Thread(ParameterizedThreadStart).Start(parameter)
        var t4 = new Thread(obj => Expect((int)obj == 42, "Expected (int)obj == 42"));

        t4.Start(42);
        s_startedThreads.Add(t4);

        // Start an unstarted resurrected thread.
        // CoreCLR: ThreadStateException, CoreRT: no exception.
        Thread unstartedResurrected = Resurrector.CreateUnstartedResurrected();

        unstartedResurrected.Start();
        s_startedThreads.Add(unstartedResurrected);

        // Threads cannot started more than once
        t1.Join();
        ExpectException <ThreadStateException>(() => t1.Start(), "Expected ThreadStateException for t1.Start()");

        ExpectException <ThreadStateException>(() => Thread.CurrentThread.Start(),
                                               "Expected ThreadStateException for CurrentThread.Start()");

        Thread stoppedResurrected = Resurrector.CreateStoppedResurrected();

        ExpectException <ThreadStateException>(() => stoppedResurrected.Start(),
                                               "Expected ThreadStateException for stoppedResurrected.Start()");

        ExpectPassed(nameof(TestStartMethod), 7);
    }