private void addProviders(
     Encounter encounter, Map<EncounterRole, ? extends Collection<Provider>> providers) {
   for (Map.Entry<EncounterRole, ? extends Collection<Provider>> entry : providers.entrySet()) {
     EncounterRole encounterRole = entry.getKey();
     for (Provider provider : entry.getValue()) {
       encounter.addProvider(encounterRole, provider);
     }
   }
 }
  /**
   * This method is synchronized to prevent multiple check-ins in a row at the same location and
   * during the same visit. See #579.
   *
   * @see org.openmrs.module.emrapi.adt.AdtService#checkInPatient(org.openmrs.Patient,
   *     org.openmrs.Location, org.openmrs.Provider, java.util.List, java.util.List, boolean)
   */
  @Override
  @Transactional
  public synchronized Encounter checkInPatient(
      Patient patient,
      Location where,
      Provider checkInClerk,
      List<Obs> obsForCheckInEncounter,
      List<Order> ordersForCheckInEncounter,
      boolean newVisit) {
    if (checkInClerk == null) {
      checkInClerk = getProvider(Context.getAuthenticatedUser());
    }

    Visit activeVisit = getActiveVisitHelper(patient, where);

    if (activeVisit != null && newVisit) {
      closeAndSaveVisit(activeVisit);
      activeVisit = null;
    }

    if (activeVisit == null) {
      activeVisit = ensureActiveVisit(patient, where);
    }

    Encounter lastEncounter = getLastEncounter(patient);
    if (lastEncounter != null
        && activeVisit.equals(lastEncounter.getVisit())
        && emrApiProperties.getCheckInEncounterType().equals(lastEncounter.getEncounterType())
        && where.equals(lastEncounter.getLocation())) {
      log.warn(
          "Patient id:{} tried to check-in twice in a row at id:{} during the same visit",
          patient.getId(),
          where.getId());
      return lastEncounter;
    }

    Encounter encounter =
        buildEncounter(
            emrApiProperties.getCheckInEncounterType(),
            patient,
            where,
            null,
            new Date(),
            obsForCheckInEncounter,
            ordersForCheckInEncounter);
    encounter.addProvider(emrApiProperties.getCheckInClerkEncounterRole(), checkInClerk);
    activeVisit.addEncounter(encounter);
    encounterService.saveEncounter(encounter);
    return encounter;
  }
  /**
   * @see
   *     org.springframework.web.servlet.mvc.SimpleFormController#processFormSubmission(javax.servlet.http.HttpServletRequest,
   *     javax.servlet.http.HttpServletResponse, java.lang.Object,
   *     org.springframework.validation.BindException)
   */
  @Override
  protected ModelAndView processFormSubmission(
      HttpServletRequest request, HttpServletResponse reponse, Object obj, BindException errors)
      throws Exception {

    Encounter encounter = (Encounter) obj;

    try {
      if (Context.isAuthenticated()) {
        Context.addProxyPrivilege(PrivilegeConstants.VIEW_USERS);
        Context.addProxyPrivilege(PrivilegeConstants.VIEW_PATIENTS);

        if (encounter.getEncounterId() == null
            && StringUtils.hasText(request.getParameter("patientId"))) {
          encounter.setPatient(
              Context.getPatientService()
                  .getPatient(Integer.valueOf(request.getParameter("patientId"))));
        }
        if (encounter.isVoided()) {
          ValidationUtils.rejectIfEmptyOrWhitespace(errors, "voidReason", "error.null");
        }

        String[] providerIdsArray = ServletRequestUtils.getStringParameters(request, "providerIds");
        if (ArrayUtils.isEmpty(providerIdsArray)) {
          errors.reject("Encounter.provider.atleastOneProviderRequired");
        }

        String[] roleIdsArray =
            ServletRequestUtils.getStringParameters(request, "encounterRoleIds");

        ProviderService ps = Context.getProviderService();
        EncounterService es = Context.getEncounterService();
        if (providerIdsArray != null && roleIdsArray != null) {
          // list to store role provider mappings to be used below to detect removed providers
          List<String> unremovedRoleAndProviders = new ArrayList<String>();
          for (int i = 0; i < providerIdsArray.length; i++) {
            if (StringUtils.hasText(providerIdsArray[i]) && StringUtils.hasText(roleIdsArray[i])) {
              unremovedRoleAndProviders.add(roleIdsArray[i] + "-" + providerIdsArray[i]);
              Provider provider = ps.getProvider(Integer.valueOf(providerIdsArray[i]));
              EncounterRole encounterRole = es.getEncounterRole(Integer.valueOf(roleIdsArray[i]));
              // if this is an existing provider, don't create a new one to avoid losing existing
              // details like dateCreated, creator, uuid etc in the encounter_provider table
              if (encounter.getProvidersByRole(encounterRole).contains(provider)) {
                continue;
              }

              // this is a new provider
              encounter.addProvider(encounterRole, provider);
            }
          }
          // Get rid of the removed ones
          for (Map.Entry<EncounterRole, Set<Provider>> entry :
              encounter.getProvidersByRoles().entrySet()) {
            for (Provider p : entry.getValue()) {
              if (!unremovedRoleAndProviders.contains(
                  entry.getKey().getEncounterRoleId() + "-" + p.getProviderId())) {
                encounter.removeProvider(entry.getKey(), p);
              }
            }
          }
        }

        ValidationUtils.invokeValidator(new EncounterValidator(), encounter, errors);
      }
    } finally {
      Context.removeProxyPrivilege(PrivilegeConstants.VIEW_USERS);
      Context.removeProxyPrivilege(PrivilegeConstants.VIEW_PATIENTS);
    }

    return super.processFormSubmission(request, reponse, encounter, errors);
  }