@Override
 public void stopAsync() {
   if (lifecycle.tryToMoveTo(Lifecycle.State.STOPPING)) {
     stopperThread =
         new StopperThread(
             monitored,
             commands,
             Long.parseLong(props.nonNullValue(PROPERTY_TERMINATION_TIMEOUT)));
     stopperThread.start();
     stopWatcher.stopWatching();
   }
 }
 /** Blocks until stopped in a timely fashion (see {@link org.sonar.process.StopperThread}) */
 void stop() {
   stopAsync();
   try {
     // stopperThread is not null for sure
     // join() does nothing if thread already finished
     stopperThread.join();
     lifecycle.tryToMoveTo(Lifecycle.State.STOPPED);
   } catch (InterruptedException e) {
     // nothing to do, the process is going to be exited
   }
   exit.exit(0);
 }