class WaitForSeInsertion extends AbstractObservableState {

  @Override
  public void onEvent(AbstractObservableLocalReader.InternalEvent event) {
    if (logger.isTraceEnabled()) {
      logger.trace(
          "[{}] onEvent => Event {} received in currentState {}", reader.getName(), event, state);
    }
    /*
     * Process InternalEvent
     */
    switch (event) {
      case SE_INSERTED:
        // process default selection if any, return an event, can be null
        ReaderEvent seEvent = this.reader.processSeInserted();
        if (seEvent != null) {
          // switch internal state
          switchState(MonitoringState.WAIT_FOR_SE_PROCESSING);
          // notify the external observer of the event
          reader.notifyObservers(seEvent);
        } else {
          // if none event was sent to the application, back to SE detection
          // stay in the same state, however switch to WAIT_FOR_SE_INSERTION to relaunch
          // the monitoring job
          if (logger.isTraceEnabled()) {
            logger.trace("[{}] onEvent => Inserted SE hasn't matched", reader.getName());
          }
          switchState(MonitoringState.WAIT_FOR_SE_REMOVAL);
        }
        break;

      case STOP_DETECT:
        switchState(MonitoringState.WAIT_FOR_START_DETECTION);
        break;

      case SE_REMOVED:
        // TODO Check if this case really happens (NFC?)
        // SE has been removed during default selection
        if (reader.getPollingMode() == ObservableReader.PollingMode.REPEATING) {
          switchState(MonitoringState.WAIT_FOR_SE_INSERTION);
        } else {
          switchState(MonitoringState.WAIT_FOR_START_DETECTION);
        }
        break;

      default:
        logger.warn(
            "[{}] Ignore =>  Event {} received in currentState {}", reader.getName(), event, state);
        break;
    }
  }

  public  WaitForSeInsertion(AbstractObservableLocalReader reader);
  public  WaitForSeInsertion(
      AbstractObservableLocalReader reader,
      AbstractMonitoringJob monitoringJob,
      ExecutorService executorService);

}