private static void saveBean(Object bean, int beanKey, HttpServletRequest req)
      throws IllegalAccessException, InvocationTargetException, IntrospectionException {
    log.info("Saving bean: " + bean.getClass().getName());
    ExtendedBeanInfo beanInfo = getExtendedBeanInfo(bean);
    Map<String, ExtendedPropertyDescriptor> epds = beanInfo.getExtendedPropertyDescriptorsByName();
    Enumeration<?> parameterNames = req.getParameterNames();
    String valueParameterPrefix = "beanedit." + beanKey + ".value.";
    while (parameterNames.hasMoreElements()) {
      String name = (String) parameterNames.nextElement();
      if (name.startsWith(valueParameterPrefix)) {
        String propertyName = name.substring(valueParameterPrefix.length());
        int bracketOpenIndex = propertyName.indexOf('[');
        String mapEntryKey = null;
        if (bracketOpenIndex >= 0) {
          // we're dealing with a map => extract the key
          if (!propertyName.endsWith("]"))
            throw new IllegalStateException(
                "propertyName contains '[' but does not end on ']': " + propertyName);

          mapEntryKey = propertyName.substring(bracketOpenIndex + 1, propertyName.length() - 1);
          propertyName = propertyName.substring(0, bracketOpenIndex);
        }

        ExtendedPropertyDescriptor epd = epds.get(propertyName);

        if (mapEntryKey != null && !epd.isMap())
          throw new IllegalStateException(
              "propertyName encodes a map key, but ExtendedPropertyDescriptor says it's not a map! "
                  + name);

        if (mapEntryKey == null) {
          Object realValue = getRealValue(bean, epd, req.getParameter(name));
          epd.setValue(bean, realValue);
        } else {
          if (epd.getMapKeyType() == String.class && epd.getMapValueType() == String.class) {
            String realValue = req.getParameter(name);

            @SuppressWarnings("unchecked")
            Map<String, String> map = (Map<String, String>) epd.getValue(bean);
            map.put(mapEntryKey, realValue);
          }
        }
      }
    }
  }