private void simulate() {
        // Prepare the model for the iteration
        earthModel.begin();
        // Submit the sim iteration to the thread pool.
        // Wait on the Future objects returned to block the current
        // thread until the iteration is complete across the whole surface.
        // Inspired by http://stackoverflow.com/questions/3929361/how-to-wait-for-all-tasks-in-an-threadpoolexecutor-to-finish-without-shutting-do
        Collection<Future<?>> futures = new LinkedList<Future<?>>();
        for (ISimThread sim : this.parallelSims) {
            futures.add(threadPool.submit(sim));
        }
        for (Future<?> future : futures) {
            try {
                future.get();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }

        // This will block if the buffer is full. If the Presenter has the
        // initiative, it must not call this method if the buffer is full.
        earthModel.commit();
    }