@Override
    public Object provide() {
      ContainerRequest request = getContainerRequest();

      Form form = getCachedForm(request, decode);

      if (form == null) {
        Form otherForm = getCachedForm(request, !decode);
        if (otherForm != null) {
          form = switchUrlEncoding(request, otherForm);
          cacheForm(request, form);
        } else {
          form = getForm(request);
          cacheForm(request, form);
        }
      }

      try {
        return extractor.extract(form.asMap());
      } catch (ExtractorException e) {
        throw new ParamException.FormParamException(
            e.getCause(), extractor.getName(), extractor.getDefaultValueString());
      }
    }
    private Form switchUrlEncoding(final ContainerRequest request, final Form otherForm) {
      final Set<Map.Entry<String, List<String>>> entries = otherForm.asMap().entrySet();

      MultivaluedMap<String, String> formMap = new NullableMultivaluedHashMap<>();
      for (Map.Entry<String, List<String>> entry : entries) {
        final String charsetName =
            ReaderWriter.getCharset(
                    MediaType.valueOf(request.getHeaderString(HttpHeaders.CONTENT_TYPE)))
                .name();

        String key;
        try {
          key =
              decode
                  ? URLDecoder.decode(entry.getKey(), charsetName)
                  : URLEncoder.encode(entry.getKey(), charsetName);

          for (String value : entry.getValue()) {
            if (value != null) {
              formMap.add(
                  key,
                  decode
                      ? URLDecoder.decode(value, charsetName)
                      : URLEncoder.encode(value, charsetName));
            } else {
              formMap.add(key, null);
            }
          }

        } catch (UnsupportedEncodingException uee) {
          throw new ProcessingException(
              LocalizationMessages.ERROR_UNSUPPORTED_ENCODING(charsetName, extractor.getName()),
              uee);
        }
      }
      return new Form(formMap);
    }