@Override
  public void terminate() {
    boolean wasTerminated;

    synchronized (this) {
      wasTerminated = terminated;
      terminated = true;
    }

    if (!wasTerminated) {
      partitionerFinished();
      documentListener.deregisterListener();

      commandExecutor.terminate();
      interpreter.interrupt();
      interpreter.terminate();
    }
  }