private void startSimulation() {
        // Once both simulator and presenter start, control flow depends on the
        // Initiative setting, which both classes have, so they must each be implemented
        // consistently with that. When the presenter or simulator are not launched in a
        // separate thread, it is important that they don't block if they don't have
        // the initiative. If an instance is not in a separate thread and doesn't have
        // the initiative, start() should simply return.
        MetricCollector.startProgramTimer();
        _isRunning = true;
        if (_args.simulationThread > 0) {
            (new Thread(_simulator)).start();
        } else {
            // If we're not in our own thread, we'll block and will
            // never reach the "start presenter" condition below
            // if we don't start the presenter before we do.
            if (_args.presentationThread > 0) {
                (new Thread(_presenter)).start();
            }
            _simulator.start();
        }
        if (_args.presentationThread > 0) {
            (new Thread(_presenter)).start();
        } else {
            _presenter.start();
        }

        // The simulation has stopped; print metrics to stdout.
        // Do this here rather than in stopSimulation() since that
        // method is potentially called by multiple threads. This method
        // is only run by the main thread, however.
        while (_isRunning) {
            try {
                // Sleep briefly to minimize error to the program timer.
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
                System.exit(1);
            }
        }
        MetricCollector.stopProgramTimer();
        MetricCollector.setIterations(_simulator.getIterationCount());
        MetricCollector.printCSV();
        // If we're running in batch mode, exit the program entirely
        // to allow new commands to be run.
        if (_args.stopWhenStable || _args.maxIterations != -1) {
            System.exit(0);
        }

        // Get ready to simulate again upon a signal from the GUI.
        MetricCollector.reset();
        waitToSimulate();
        startSimulation();
    }