@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();
    }
  }