public ResponseDTO createEvent(ExpoEventDTO expoEventDTO) {
    ExpoEvent expoEvent = saveEvent(mapper.map(expoEventDTO, ExpoEvent.class));

    //        setFreeStands(expoEvent);
    //        addEventToHall(expoEvent);

    expoEventDTO = mapper.map(expoEvent, ExpoEventDTO.class);
    expoEventDTO.setExpoHall(getExpoHall(expoEventDTO.getHallId()));

    return ResponseDTO.getBuilder().data(expoEventDTO).build();
  }
  public ResponseDTO updateEvent(BigInteger id, ExpoEventDTO expoEventDTO)
      throws MethodArgumentNotValidException, NoSuchMethodException {
    ExpoEvent expoEvent = findOne(id);

    ValidationUtil.process(validator.validate(expoEvent));

    //        boolean isHallChanged = expoEvent.isHallChanged(expoEventDTO.getExpoHall());
    //        if(isHallChanged) {
    //            removeEventFromHall(expoEvent);  // hall can be changed
    //        }

    mapper.map(expoEventDTO, expoEvent);

    //        if(isHallChanged){
    //            setFreeStands(expoEvent);
    //            addEventToHall(expoEvent);
    //        }

    expoEventDTO = mapper.map(saveEvent(expoEvent), ExpoEventDTO.class);
    expoEventDTO.setExpoHall(getExpoHall(expoEventDTO.getHallId()));

    return ResponseDTO.getBuilder().data(expoEventDTO).build();
  }
  // (Event is in progress && Event has reserved stands)
  public ResponseDTO findAllUserEvents(Integer page, Integer limit) {
    List<BigInteger> eventIds =
        StreamSupport.stream(
                expoEventRepository
                    .findAll(ExpoEventPredicates.eventsIsInProgressAndRemovedIsFalse())
                    .spliterator(),
                false)
            .filter(
                expoEvent -> {
                  ExpoHall expoHall = expoHallService.findOne(expoEvent.getHallId());
                  return StreamSupport.stream(
                          expoStandRepository
                              .findAll(
                                  ExpoStandPredicates.eqHallIdAndRemovedIsFalse(expoHall.getId()))
                              .spliterator(),
                          false)
                      .anyMatch(expoStand -> expoStandService.isStandReserved(expoStand.getId()));
                })
            .map(AbstractDocument::getId)
            .collect(Collectors.toList());

    /*Page<ExpoEvent> expoEventPage = expoEventRepository.findAll(
            ExpoEventPredicates.eventIsInProgress(),
            new PageRequest(--page, limit, Sort.Direction.DESC, "lastModifiedDate")
    );*/
    Page<ExpoEvent> expoEventPage =
        expoEventRepository.findAll(
            eventIds, new PageRequest(--page, limit, Sort.Direction.DESC, "lastModifiedDate"));

    List<ExpoEventDTO> eventDTOs = mapper.mapAsList(expoEventPage.getContent(), ExpoEventDTO.class);
    eventDTOs.forEach(
        eventDTO -> {
          if (eventDTO.getLogo() != null) {
            eventDTO
                .getLogo()
                .setBytes(
                    ImageResizeUtil.resize(
                        eventDTO.getLogo().getBytes(),
                        thumbnailSize,
                        eventDTO.getLogo().getContentType()));
          }
          eventDTO.setExpoHall(getExpoHall(eventDTO.getHallId()));
        });

    return ResponseDTO.getBuilder().data(eventDTOs).total(expoEventPage.getTotalElements()).build();
  }
  public ResponseDTO findAllEvents(Integer page, Integer limit) {
    Page<ExpoEvent> expoEventPage =
        expoEventRepository.findAll(
            ExpoEventPredicates.removedIsFalse(),
            new PageRequest(--page, limit, Sort.Direction.DESC, "lastModifiedDate"));

    List<ExpoEventBaseDTO> expoEventDTOs =
        mapper.mapAsList(expoEventPage.getContent(), ExpoEventBaseDTO.class);

    expoEventDTOs.forEach(
        expoEventDTO -> expoEventDTO.setExpoHall(getExpoHall(expoEventDTO.getHallId())));

    return ResponseDTO.getBuilder()
        .data(expoEventDTOs)
        .total(expoEventPage.getTotalElements())
        .build();

    /*return ResponseDTO.getBuilder().
    data(mapper.mapAsList(expoEventPage.getContent(), ExpoEventBaseDTO.class)).
    total(expoEventPage.getTotalElements()).
    build();*/
  }
  // (Event is not finished && Event has free stands) || (Company reserved stand of the event
  // before)
  public ResponseDTO findAllCompanyEvents(Integer page, Integer limit) {
    // (Event is not finished && Event has free stands)
    List<BigInteger> notFinishedWithFreeStandsEventIds =
        StreamSupport.stream(
                expoEventRepository
                    .findAll(ExpoEventPredicates.eventsIsNotFinishedAndRemovedIsFalse())
                    .spliterator(),
                false)
            .filter(
                expoEvent -> {
                  ExpoHall expoHall = expoHallService.findOne(expoEvent.getHallId());
                  return StreamSupport.stream(
                          expoStandRepository
                              .findAll(
                                  ExpoStandPredicates.eqHallIdAndRemovedIsFalse(expoHall.getId()))
                              .spliterator(),
                          false)
                      .anyMatch(expoStand -> !expoStandService.isStandReserved(expoStand.getId()));
                })
            .map(AbstractDocument::getId)
            .collect(Collectors.toList());

    // (Company reserved stand of the event before)
    BigInteger userCompanyId = userService.findUserCompanyId();
    List<BigInteger> companyStandEventIds =
        StreamSupport.stream(
                companyStandRepository
                    .findAll(CompanyStandPredicates.companyIdEqAndRemovedIsFalse(userCompanyId))
                    .spliterator(),
                false)
            .map(companyStand -> findOne(companyStand.getEventId()).getId())
            .collect(Collectors.toList());

    // Merge eventIds
    List<BigInteger> eventIds =
        Stream.concat(notFinishedWithFreeStandsEventIds.stream(), companyStandEventIds.stream())
            .distinct()
            .collect(Collectors.toList());

    Page<ExpoEvent> expoEventPage =
        expoEventRepository.findAll(
            eventIds, new PageRequest(--page, limit, Sort.Direction.DESC, "lastModifiedDate"));

    List<CompanyEventDTO> eventDTOs =
        mapper.mapAsList(expoEventPage.getContent(), CompanyEventDTO.class);
    eventDTOs.forEach(
        eventDTO -> {
          if (eventDTO.getLogo() != null) {
            eventDTO
                .getLogo()
                .setBytes(
                    ImageResizeUtil.resize(
                        eventDTO.getLogo().getBytes(),
                        thumbnailSize,
                        eventDTO.getLogo().getContentType()));
          }

          eventDTO.setExpoHall(getExpoHall(eventDTO.getHallId()));

          eventDTO.setCompanyStands(
              mapper.mapAsList(
                  companyStandRepository.findAll(
                      CompanyStandPredicates.companyIdEqAndEventIdEq(
                          userCompanyId, eventDTO.getId())),
                  CompanyStandBaseDTO.class));
        });

    return ResponseDTO.getBuilder().data(eventDTOs).total(expoEventPage.getTotalElements()).build();
  }
 private ExpoHallAbstractDTO getExpoHall(BigInteger hallId) {
   return mapper.map(expoHallService.findOne(hallId), ExpoHallAbstractDTO.class);
 }
  public ResponseDTO findOneEvent(BigInteger id) {
    ExpoEventDTO expoEventDTO = mapper.map(findOne(id), ExpoEventDTO.class);
    expoEventDTO.setExpoHall(getExpoHall(expoEventDTO.getHallId()));

    return ResponseDTO.getBuilder().data(expoEventDTO).build();
  }