public void setScoringDefinition(Scoring scoring) {
    for (ScoringElement element : scoring.getElements()) {
      ParserHelper.resolveConditionType(definitionsService, element.getCondition());
    }
    for (ScoringElement element : scoring.getElements()) {
      if (scoring.getMetadata().isEnabled() && !scoring.getMetadata().isMissingPlugins()) {
        updateAutoGeneratedRules(scoring.getMetadata(), element.getCondition());
      }
    }
    // make sure we update the name and description metadata that might not match, so first we
    // remove the entry from the map
    persistenceService.save(scoring);

    persistenceService.createMapping(
        Profile.ITEM_TYPE,
        String.format(
            "{\n"
                + "    \"profile\": {\n"
                + "        \"properties\" : {\n"
                + "            \"scores\": {\n"
                + "                \"properties\": {\n"
                + "                    \"%s\": {\n"
                + "                        \"type\": \"long\"\n"
                + "                    }\n"
                + "                }\n"
                + "            }\n"
                + "        }\n"
                + "    }\n"
                + "}\n",
            scoring.getItemId()));

    updateExistingProfilesForScoring(scoring);
  }
  private void updateExistingProfilesForScoring(Scoring scoring) {
    long t = System.currentTimeMillis();
    Condition scoringCondition = new Condition();
    scoringCondition.setConditionType(
        definitionsService.getConditionType("profilePropertyCondition"));
    scoringCondition.setParameter("propertyName", "scores." + scoring.getItemId());
    scoringCondition.setParameter("comparisonOperator", "exists");
    List<Profile> previousProfiles =
        persistenceService.query(scoringCondition, null, Profile.class);

    HashMap<String, Object> scriptParams = new HashMap<>();
    scriptParams.put("scoringId", scoring.getItemId());

    for (Profile profileToRemove : previousProfiles) {
      persistenceService.updateWithScript(
          profileToRemove.getItemId(),
          null,
          Profile.class,
          "if (ctx._source.systemProperties.scoreModifiers == null) { ctx._source.systemProperties.scoreModifiers=[:] } ; if (ctx._source.systemProperties.scoreModifiers.containsKey(scoringId)) { ctx._source.scores[scoringId] = ctx._source.systemProperties.scoreModifiers[scoringId] } else { ctx._source.scores.remove(scoringId) }",
          scriptParams);
    }
    if (scoring.getMetadata().isEnabled()) {
      String script =
          "if (ctx._source.scores == null) { ctx._source.scores=[:] } ; if (ctx._source.scores.containsKey(scoringId)) { ctx._source.scores[scoringId] += scoringValue } else { ctx._source.scores[scoringId] = scoringValue }";
      Map<String, Event> updatedProfiles = new HashMap<>();
      for (ScoringElement element : scoring.getElements()) {
        scriptParams.put("scoringValue", element.getValue());
        for (Profile p : persistenceService.query(element.getCondition(), null, Profile.class)) {
          persistenceService.updateWithScript(
              p.getItemId(), null, Profile.class, script, scriptParams);
          Event profileUpdated = new Event("profileUpdated", null, p, null, null, p, new Date());
          profileUpdated.setPersistent(false);
          updatedProfiles.put(p.getItemId(), profileUpdated);
        }
      }
      Iterator<Map.Entry<String, Event>> entries = updatedProfiles.entrySet().iterator();
      while (entries.hasNext()) {
        eventService.send(entries.next().getValue());
      }
    }
    logger.info("Profiles updated in {}", System.currentTimeMillis() - t);
  }