static bool ParseModifyRequest(DicomModification& target,
                                 const RestApiPostCall& call)
  {
    // curl http://localhost:8042/series/95a6e2bf-9296e2cc-bf614e2f-22b391ee-16e010e0/modify -X POST -d '{"Replace":{"InstitutionName":"My own clinic"}}'

    Json::Value request;
    if (call.ParseJsonRequest(request))
    {
      return OrthancRestApi::ParseModifyRequest(target, request);
    }
    else
    {
      return false;
    }
  }
  static bool ParseAnonymizationRequest(DicomModification& target,
                                        RestApiPostCall& call)
  {
    // curl http://localhost:8042/instances/6e67da51-d119d6ae-c5667437-87b9a8a5-0f07c49f/anonymize -X POST -d '{"Replace":{"PatientName":"hello","0010-0020":"world"},"Keep":["StudyDescription", "SeriesDescription"],"KeepPrivateTags": null,"Remove":["Modality"]}' > Anonymized.dcm

    target.SetupAnonymization();
    std::string patientName = target.GetReplacement(DICOM_TAG_PATIENT_NAME);

    Json::Value request;
    if (call.ParseJsonRequest(request) && request.isObject())
    {
      if (request.isMember("KeepPrivateTags"))
      {
        target.SetRemovePrivateTags(false);
      }

      if (request.isMember("Remove"))
      {
        ParseListOfTags(target, request["Remove"], TagOperation_Remove);
      }

      if (request.isMember("Replace"))
      {
        ParseReplacements(target, request["Replace"]);
      }

      if (request.isMember("Keep"))
      {
        ParseListOfTags(target, request["Keep"], TagOperation_Keep);
      }

      if (target.IsReplaced(DICOM_TAG_PATIENT_NAME) &&
          target.GetReplacement(DICOM_TAG_PATIENT_NAME) == patientName)
      {
        // Overwrite the random Patient's Name by one that is more
        // user-friendly (provided none was specified by the user)
        target.Replace(DICOM_TAG_PATIENT_NAME, GeneratePatientName(OrthancRestApi::GetContext(call)), true);
      }

      return true;
    }
    else
    {
      return false;
    }
  }
  static void CreateDicom(RestApiPostCall& call)
  {
    // curl http://localhost:8042/tools/create-dicom -X POST -d '{"PatientName":"Hello^World"}'
    // curl http://localhost:8042/tools/create-dicom -X POST -d '{"PatientName":"Hello^World","PixelData":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAAAAAA6mKC9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gUGDDcB53FulQAAAElJREFUGNNtj0sSAEEEQ1+U+185s1CtmRkblQ9CZldsKHJDk6DLGLJa6chjh0ooQmpjXMM86zPwydGEj6Ed/UGykkEM8X+p3u8/8LcOJIWLGeMAAAAASUVORK5CYII="}'

    Json::Value replacements;
    if (call.ParseJsonRequest(replacements) && replacements.isObject())
    {
      ParsedDicomFile dicom;

      Json::Value::Members members = replacements.getMemberNames();
      for (size_t i = 0; i < members.size(); i++)
      {
        const std::string& name = members[i];
        std::string value = replacements[name].asString();

        DicomTag tag = FromDcmtkBridge::ParseTag(name);
        if (tag == DICOM_TAG_PIXEL_DATA)
        {
          dicom.EmbedImage(value);
        }
        else
        {
          dicom.Replace(tag, value);
        }
      }

      DicomInstanceToStore toStore;
      toStore.SetParsedDicomFile(dicom);

      std::string id;
      StoreStatus status = OrthancRestApi::GetContext(call).Store(id, toStore);

      if (status == StoreStatus_Failure)
      {
        LOG(ERROR) << "Error while storing a manually-created instance";
        return;
      }

      OrthancRestApi::GetApi(call).AnswerStoredInstance(call, id, status);
    }
  }