@RequestMapping(value = SETTINGS_PATH, method = RequestMethod.POST)
  public void updateSettings(
      @ModelAttribute(SETTINGS_FORM) SettingsForm settingsForm,
      Errors errors,
      HttpServletRequest request,
      HttpSession session) {

    List<GlobalProperty> toSave = new ArrayList<GlobalProperty>();
    try {
      for (int i = 0; i < settingsForm.getSettings().size(); ++i) {
        SettingsProperty property = settingsForm.getSettings().get(i);
        if (StringUtils.isNotEmpty(property.getGlobalProperty().getDatatypeClassname())) {
          // we need to handle the submitted value with the appropriate widget
          CustomDatatype dt = CustomDatatypeUtil.getDatatypeOrDefault(property.getGlobalProperty());
          CustomDatatypeHandler handler =
              CustomDatatypeUtil.getHandler(property.getGlobalProperty());
          if (handler != null) {
            try {
              Object value =
                  WebAttributeUtil.getValue(
                      request, dt, handler, "settings[" + i + "].globalProperty.propertyValue");
              property.getGlobalProperty().setValue(value);
            } catch (Exception ex) {
              String originalValue = request.getParameter("originalValue[" + i + "]");
              property.getGlobalProperty().setPropertyValue(originalValue);
              errors.rejectValue(
                  "settings[" + i + "].globalProperty.propertyValue", "general.invalid");
            }
          }
        }
        toSave.add(property.getGlobalProperty());
      }
    } catch (Exception e) {
      log.error("Error saving global property", e);
      errors.reject("GlobalProperty.not.saved");
      session.setAttribute(WebConstants.OPENMRS_ERROR_ATTR, e.getMessage());
    }

    if (errors.hasErrors()) {
      session.setAttribute(WebConstants.OPENMRS_ERROR_ATTR, "GlobalProperty.not.saved");

    } else {
      for (GlobalProperty gp : toSave) {
        getService().saveGlobalProperty(gp);
      }
      session.setAttribute(WebConstants.OPENMRS_MSG_ATTR, "GlobalProperty.saved");

      // TODO: move this to a GlobalPropertyListener
      // refresh log level from global property(ies)
      OpenmrsUtil.applyLogLevels();

      OpenmrsUtil.setupLogAppenders();
    }
  }
  /**
   * The onSubmit function receives the form/command object that was modified by the input form and
   * saves it to the db
   *
   * @see
   *     org.springframework.web.servlet.mvc.SimpleFormController#onSubmit(javax.servlet.http.HttpServletRequest,
   *     javax.servlet.http.HttpServletResponse, java.lang.Object,
   *     org.springframework.validation.BindException)
   * @should retire location
   * @should not retire location if reason is empty
   */
  protected ModelAndView onSubmit(
      HttpServletRequest request, HttpServletResponse response, Object obj, BindException errors)
      throws Exception {

    HttpSession httpSession = request.getSession();

    String view = getFormView();
    if (Context.isAuthenticated()) {
      try {
        Location location = (Location) obj;
        WebAttributeUtil.handleSubmittedAttributesForType(
            location,
            errors,
            LocationAttribute.class,
            request,
            Context.getLocationService().getAllLocationAttributeTypes());

        if (errors.hasErrors()) {
          return showForm(request, response, errors);
        }

        LocationService locationService = Context.getLocationService();

        // if the user was editing the location
        if (request.getParameter("saveLocation") != null) {
          locationService.saveLocation(location);
          httpSession.setAttribute(WebConstants.OPENMRS_MSG_ATTR, "Location.saved");
        }
        // the 'retire this location' button was clicked
        else if (request.getParameter("retireLocation") != null) {
          locationService.retireLocation(location, location.getRetireReason());
          httpSession.setAttribute(WebConstants.OPENMRS_MSG_ATTR, "Location.retired");
        }
        // the 'unretire this location' button was clicked
        else if (request.getParameter("unretireLocation") != null) {
          locationService.unretireLocation(location);
          httpSession.setAttribute(WebConstants.OPENMRS_MSG_ATTR, "Location.unretired");
        }
      } catch (APIException e) {
        log.error("Error while saving location: " + obj, e);
        httpSession.setAttribute(WebConstants.OPENMRS_ERROR_ATTR, e.getMessage());
        return showForm(request, response, errors);
      }

      view = getSuccessView();
    }

    return new ModelAndView(new RedirectView(view));
  }