private CreateExtractorRequest generateCreateExtractorRequest(
      Map<String, String[]> form, Extractor originalExtractor) {
    final Extractor.Type extractorType =
        Extractor.Type.valueOf(form.get("extractor_type")[0].toUpperCase());

    final Extractor extractor =
        extractorFactory.forCreate(
            Extractor.CursorStrategy.valueOf(form.get("cut_or_copy")[0].toUpperCase()),
            form.get("title")[0],
            form.get("source_field")[0],
            // grok extractor, for example, has no target field, so set it to source to satisf
            (form.get("target_field") == null
                ? form.get("source_field")[0]
                : form.get("target_field")[0]),
            extractorType,
            currentUser(),
            Extractor.ConditionType.valueOf(form.get("condition_type")[0].toUpperCase()),
            form.get("condition_value")[0]);
    if (originalExtractor != null) {
      extractor.setOrder(originalExtractor.getOrder());
    }
    extractor.loadConfigFromForm(extractorType, form);
    extractor.loadConvertersFromForm(form);

    return extractor.toCreateExtractorRequest();
  }
  public Result importExtractors(String nodeId, String inputId) {
    if (!Permissions.isPermitted(RestPermissions.INPUTS_EDIT, inputId)) {
      return redirect(routes.StartpageController.redirect());
    }
    Map<String, String> form = flattenFormUrlEncoded(request().body().asFormUrlEncoded());

    if (!form.containsKey("extractors") || form.get("extractors").isEmpty()) {
      flash("error", "No JSON provided. Please fill out the import definition field.");
      return redirect(
          controllers.routes.ExtractorsController.importExtractorsPage(nodeId, inputId));
    }

    ExtractorListImportRequest elir;
    try {
      elir = Json.fromJson(Json.parse(form.get("extractors")), ExtractorListImportRequest.class);
    } catch (Exception e) {
      Logger.error("Could not read JSON.", e);
      flash("error", "Could not read JSON.");
      return redirect(
          controllers.routes.ExtractorsController.importExtractorsPage(nodeId, inputId));
    }

    /*
     * For future versions with breaking changes: check the "version" field in the ExtractorListImportRequest.
     *
     * Thank me later.
     */

    int successes = 0;
    List<String> failedExtractors = new ArrayList<>();
    for (ExtractorImportRequest importRequest : elir.extractors) {
      try {
        Node node = nodeService.loadNode(nodeId);

        Extractor.Type type = Extractor.Type.valueOf(importRequest.extractorType.toUpperCase());

        Extractor extractor =
            extractorFactory.forCreate(
                Extractor.CursorStrategy.valueOf(importRequest.cursorStrategy.toUpperCase()),
                importRequest.title,
                importRequest.sourceField,
                importRequest.targetField,
                type,
                currentUser(),
                Extractor.ConditionType.valueOf(importRequest.conditionType.toUpperCase()),
                importRequest.conditionValue);

        extractor.loadConfigFromImport(type, importRequest.extractorConfig);
        extractor.loadConvertersFromImport(importRequest.converters);
        extractor.setOrder(importRequest.order);
        extractorService.create(node, node.getInput(inputId), extractor.toCreateExtractorRequest());
        successes++;
      } catch (Exception e) {
        failedExtractors.add(importRequest.title);
        Logger.error(
            "Could not import extractor \"" + importRequest.title + "\": " + e.getMessage());
        Logger.debug("Details for failing to import extractor \"" + importRequest.title + "\":", e);
      }
    }

    if (!failedExtractors.isEmpty()) {
      flash(
          "error",
          "Failed to import "
              + failedExtractors.size()
              + " extractors: "
              + Joiner.on(',').useForNull("[null title]").join(failedExtractors));
    }

    flash(
        "success",
        "Successfully imported " + successes + " of " + elir.extractors.size() + " extractors.");
    return redirect(controllers.routes.ExtractorsController.manage(nodeId, inputId));
  }