class WashingMachine {

  private final DelayProvider delayProvider;

  @Getter
  private WashingMachineState washingMachineState;

  /**
   * Creates a new instance of WashingMachine.
   */
  public WashingMachine() {
    this((interval, timeUnit, task) -> {
      try {
        Thread.sleep(timeUnit.toMillis(interval));
      } catch (InterruptedException ie) {
        LOGGER.error("", ie);
        Thread.currentThread().interrupt();
      }
      task.run();
    });
  }

  /**
   * Creates a new instance of WashingMachine using provided delayProvider. This constructor is used
   * only for unit testing purposes.
   */
  public WashingMachine(DelayProvider delayProvider) {
    this.delayProvider = delayProvider;
    this.washingMachineState = WashingMachineState.ENABLED;
  }

  /**
   * Method responsible for washing if the object is in appropriate state.
   */
  public void wash() {<FILL_FUNCTION_BODY>}

  /**
   * Method is responsible for ending the washing by changing machine state.
   */
  public synchronized void endOfWashing() {
    washingMachineState = WashingMachineState.ENABLED;
    LOGGER.info("{}: Washing completed.", Thread.currentThread().getId());
  }

}

    synchronized (this) {
      var machineState = getWashingMachineState();
      LOGGER.info("{}: Actual machine state: {}", Thread.currentThread().getName(), machineState);
      if (this.washingMachineState == WashingMachineState.WASHING) {
        LOGGER.error("Cannot wash if the machine has been already washing!");
        return;
      }
      this.washingMachineState = WashingMachineState.WASHING;
    }
    LOGGER.info("{}: Doing the washing", Thread.currentThread().getName());

    this.delayProvider.executeAfterDelay(50, TimeUnit.MILLISECONDS, this::endOfWashing);
  
<no_super_class>