@Override
  public SeatHold findAndHoldSeats(
      int numSeats, Optional<Integer> minLevel, Optional<Integer> maxLevel, String customerEmail) {

    List<Seat> seatsList = new ArrayList<Seat>();

    int seatsHoldCount = 0;

    EXTLOOP:
    for (VenueLevel level : MockData.levels) {
      if ((!minLevel.isPresent() || level.getLevelId() >= minLevel.get())
          && (!maxLevel.isPresent() || level.getLevelId() <= maxLevel.get())) {
        synchronized (MockData.seatsMap.get(level)) {
          Iterator<Seat> itr = MockData.seatsMap.get(level).iterator();
          while (itr.hasNext()) {
            Seat seat = itr.next();
            // if
            // (SeatStatusType.AVAILABLE.equals(seat.getStatus())) {
            MockData.seatsMap.get(level).remove(seat);
            seatsList.add(seat);
            seatsHoldCount++;
            // }
            if (seatsHoldCount == numSeats) {
              break EXTLOOP;
            }
          }
        }
      }
    }

    SeatHold seatHold = new SeatHold();

    if (seatsHoldCount < numSeats) {
      this.releaseSeats(seatsList);
      throw new SeatsUnAvailableException("Seats not available.");
    } else {
      seatHold.setHoldId(RandomUtils.nextInt());
      seatHold.setStatus(ReservationStatusType.HOLD);
      seatHold.setHoldTimestamp(Calendar.getInstance().getTimeInMillis());
      // seatHold.setSeats(seatsList);
      seatHold.setCustomer(new Customer(RandomUtils.nextLong(), null, customerEmail));
      for (Seat seat : seatsList) {
        seat.setStatus(SeatStatusType.HOLD);
        seatHold.getSeats().add(seat);
      }
      MockData.holdsMap.put(seatHold.getHoldId(), seatHold);
    }
    return seatHold;
  }