             inBarrierStageCompleted = 0
             postBarrierStageCompleted = 0
         }
-
-//        print("testAsyncBarrierFunction() @ \(#line): ^ leave main test loop")
-//
-//        print("testAsyncBarrierFunction() @ \(#line) -- leaving function")
     }
 
     func testMainThreadFunction()

        {
            XCTAssertTrue(NSThread.isMainThread())  // we expect tests to run on the main thread

//            print("testBarrierWithSemaphore() @ \(#line) -- entering function")

            for _ in 0..<IterationsPerBarrierStage {
//                print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): v enter async {} -- preBarrierStage")

                async {
                    XCTAssertTrue(!NSThread.isMainThread())

//                    print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): v startingGun.lock() -- preBarrierStage")
                    startingGun.lock()
//                    print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): ^ startingGun.lock() -- preBarrierStage")
                    while !startAsyncWork {
//                        print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): v startingGun.wait() -- preBarrierStage")
                        startingGun.wait()
//                        print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): ^ startingGun.wait() -- preBarrierStage")
                    }
//                    print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): v startingGun.unlock() -- preBarrierStage")
                    startingGun.unlock()
//                    print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): ^ startingGun.unlock() -- preBarrierStage")

//                    print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): v semaphore.lock() -- preBarrierStage")
                    semaphore.lock()
//                    print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): ^ semaphore.lock() -- preBarrierStage")

                    XCTAssertTrue(inBarrierStageCompleted == 0)
                    XCTAssertTrue(postBarrierStageCompleted == 0)

                    preBarrierStageCompleted += 1

//                    print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): v semaphore.signal() -- preBarrierStage")
                    semaphore.signal()
//                    print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): ^ semaphore.signal() -- preBarrierStage")

//                    print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): v semaphore.unlock() -- preBarrierStage")
                    semaphore.unlock()
//                    print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): ^ semaphore.unlock() -- preBarrierStage")
                }

//                print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): ^ leave async {} -- preBarrierStage")
            }

//            print("testBarrierWithSemaphore() @ \(#line)")

            for _ in 0..<IterationsPerBarrierStage {
//                print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): v enter asyncBarrier {} -- inBarrierStage")

                asyncBarrier {
                    XCTAssertTrue(!NSThread.isMainThread())

//                    print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): v startingGun.lock() -- inBarrierStage")
                    startingGun.lock()
//                    print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): ^ startingGun.lock() -- inBarrierStage")
                    while !startAsyncWork {
//                        print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): v startingGun.wait() -- inBarrierStage")
                        startingGun.wait()
//                        print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): ^ startingGun.wait() -- inBarrierStage")
                    }
//                    print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): v startingGun.unlock() -- inBarrierStage")
                    startingGun.unlock()
//                    print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): ^ startingGun.unlock() -- inBarrierStage")

//                    print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): v semaphore.lock() -- inBarrierStage")
                    semaphore.lock()
//                    print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): ^ semaphore.lock() -- inBarrierStage")

                    XCTAssertTrue(preBarrierStageCompleted == self.IterationsPerBarrierStage)
                    XCTAssertTrue(postBarrierStageCompleted == 0)

                    inBarrierStageCompleted += 1

//                    print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): v semaphore.signal() -- inBarrierStage")
                    semaphore.signal()
//                    print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): ^ semaphore.signal() -- inBarrierStage")

//                    print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): v semaphore.unlock() -- inBarrierStage")
                    semaphore.unlock()
//                    print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): ^ semaphore.unlock() -- inBarrierStage")
                }

//                print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): ^ leave asyncBarrier {} -- inBarrierStage")
            }

//            print("testBarrierWithSemaphore() @ \(#line)")

            for _ in 0..<IterationsPerBarrierStage {
//                print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): v enter async {} -- postBarrierStage")

                async {
                    XCTAssertTrue(!NSThread.isMainThread())

//                    print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): v startingGun.lock() -- postBarrierStage")
                    startingGun.lock()
//                    print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): ^ startingGun.lock() -- postBarrierStage")
                    while !startAsyncWork {
//                        print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): v startingGun.wait() -- postBarrierStage")
                        startingGun.wait()
//                        print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): ^ startingGun.wait() -- postBarrierStage")
                    }
//                    print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): v startingGun.unlock() -- postBarrierStage")
                    startingGun.unlock()
//                    print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): ^ startingGun.unlock() -- postBarrierStage")

//                    print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): v semaphore.lock() -- postBarrierStage")
                    semaphore.lock()
//                    print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): ^ semaphore.lock() -- postBarrierStage")

                    XCTAssertTrue(preBarrierStageCompleted == self.IterationsPerBarrierStage)
                    XCTAssertTrue(inBarrierStageCompleted == self.IterationsPerBarrierStage)

                    postBarrierStageCompleted += 1

//                    print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): v semaphore.signal() -- postBarrierStage")
                    semaphore.signal()
//                    print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): ^ semaphore.signal() -- postBarrierStage")

//                    print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): v semaphore.unlock() -- postBarrierStage")
                    semaphore.unlock()
//                    print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): ^ semaphore.unlock() -- postBarrierStage")
                }

//                print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): ^ leave async {} -- postBarrierStage")
            }

//            print("testBarrierWithSemaphore() @ \(#line) -- leaving function")
        }

//        print("testAsyncBarrierFunction() @ \(#line): v enter main test loop (will execute \(IterationsOfBarrierTest) times)")

        for _ in 0..<IterationsOfBarrierTest {
//            print("testAsyncBarrierFunction() @ \(#line) (\(i+1)/\(IterationsOfBarrierTest)): creating semaphore")

            let semaphore = NSCondition()
            let startingGun = NSCondition()

//            print("testAsyncBarrierFunction() @ \(#line) (\(i+1)/\(IterationsOfBarrierTest)): v testBarrierWithSemaphore()")
            testBarrier(with: semaphore, startingGun: startingGun)
//            print("testAsyncBarrierFunction() @ \(#line) (\(i+1)/\(IterationsOfBarrierTest)): ^ testBarrierWithSemaphore()")

            let waitingFor = IterationsPerBarrierStage * 3  // because there are 3 test stages

            var completed = 0
            var lastCompleted: Int?
//            print("testAsyncBarrierFunction() @ \(#line) (\(i+1)/\(IterationsOfBarrierTest)): v semaphore.lock()")
            semaphore.lock()
//            print("testAsyncBarrierFunction() @ \(#line) (\(i+1)/\(IterationsOfBarrierTest)): ^ semaphore.lock()")

//            print("testAsyncBarrierFunction() @ \(#line): v startingGun.lock()")
            startingGun.lock()
//            print("testAsyncBarrierFunction() @ \(#line): ^ startingGun.lock()")
            startAsyncWork = true
//            print("testAsyncBarrierFunction() @ \(#line): v startingGun.broadcast()")
            startingGun.broadcast()
//            print("testAsyncBarrierFunction() @ \(#line): ^ startingGun.broadcast()")
//            print("testAsyncBarrierFunction() @ \(#line): v startingGun.unlock()")
            startingGun.unlock()
//            print("testBarrierWithSemaphore() @ \(#line): ^ startingGun.unlock()")

            while completed < waitingFor {
//                print("testAsyncBarrierFunction() @ \(#line) (\(i+1)/\(IterationsOfBarrierTest)): v semaphore.waitUntilDate()")
                let result = semaphore.waitUntilDate(NSDate().dateByAddingTimeInterval(1.1))
//                print("testAsyncBarrierFunction() @ \(#line) (\(i+1)/\(IterationsOfBarrierTest)): ^ semaphore.waitUntilDate()")
                if result {
                if !semaphore.waitUntilDate(NSDate().dateByAddingTimeInterval(1.0)) {
                    NSRunLoop.currentRunLoop().runMode(NSRunLoopCommonModes, beforeDate: NSDate().dateByAddingTimeInterval(1.0))
                }


    func testAsyncBarrierFunction()
    {
        var startAsyncWork = false
        var preBarrierStageCompleted = 0
        var inBarrierStageCompleted = 0
