/**
   * Assign the given list of units to the emergency.
   *
   * @param units The given list of units.
   * @post All the units in the given list are assigned | forall (u in units) | u.isAssigned()
   * @post All the units in the given list are handling the emergency of this UnitNeeded | forall (u
   *     in units) | u.getEmergency().equals(this.getEmergency())
   * @throws InvalidEmergencyException If the units can't be assigned to the emergency (when
   *     canAssignUnitsToEmergency fails)
   * @see #canAssignUnitsToEmergency(Set)
   */
  @Override
  public synchronized void assignUnitsToEmergency(Set<Unit> units)
      throws InvalidEmergencyException {
    ArrayList<Unit> options = new ArrayList<Unit>(units.size());
    Iterator<Unit> it = units.iterator();
    while (it.hasNext()) {
      options.add(it.next());
    }

    if (!canAssignUnitsToEmergency(units)) {
      throw new InvalidEmergencyException(
          "Units can't be assigned to the emergency, harm to assignment constraints.");
    }
    for (Emergency e : getDisaster().getEmergencies()) {
      ConcreteUnitsNeeded CUN = e.getUnitsNeeded();
      Set<Unit> unitsForEmergency = CUN.generateProposal(options);
      try {
        e.assignUnits(unitsForEmergency);
      } catch (InvalidEmergencyStatusException ex) {
        // We assume this can't happen.
        Logger.getLogger(DerivedUnitsNeeded.class.getName()).log(Level.SEVERE, null, ex);
      }
      for (Unit u : unitsForEmergency) {
        addWorkingUnits(u);
      }
      options.removeAll(unitsForEmergency);
    }
  }
  /**
   * Checks if the given units can be assigned to the emergency.
   *
   * @param units The units to be assigned.
   * @return True if all the given units are effective, unique and can be assigned and the
   *     constraint for allocation is passed; otherwise false.
   */
  public boolean canAssignUnitsToEmergency(Set<Unit> units) {
    ArrayList<Unit> options = new ArrayList<Unit>(units.size());
    Iterator<Unit> it = units.iterator();
    while (it.hasNext()) {
      options.add(it.next());
    }
    for (Emergency e : getDisaster().getEmergencies()) {
      ConcreteUnitsNeeded CUN = e.getUnitsNeeded();
      Set<Unit> unitsForEmergency = CUN.generateProposal(options);

      if (unitsForEmergency.isEmpty() || !e.canAssignUnits(unitsForEmergency)) {
        return false;
      }
    }

    return true;
  }