public DependentMetadata removeScoringDefinition(String scoringId, boolean validate) {
    Set<Segment> impactedSegments = getScoringDependentSegments(scoringId);
    Set<Scoring> impactedScorings = getScoringDependentScorings(scoringId);
    if (!validate || (impactedSegments.isEmpty() && impactedScorings.isEmpty())) {
      // update profiles
      updateExistingProfilesForRemovedScoring(scoringId);

      // update impacted segments
      for (Segment segment : impactedSegments) {
        Condition updatedCondition =
            updateScoringDependentCondition(segment.getCondition(), scoringId);
        segment.setCondition(updatedCondition);
        if (updatedCondition == null) {
          clearAutoGeneratedRules(
              persistenceService.query(
                  "linkedItems", segment.getMetadata().getId(), null, Rule.class),
              segment.getMetadata().getId());
          segment.getMetadata().setEnabled(false);
        }
        setSegmentDefinition(segment);
      }

      // update impacted scorings
      for (Scoring scoring : impactedScorings) {
        List<ScoringElement> updatedScoringElements = new ArrayList<>();
        for (ScoringElement scoringElement : scoring.getElements()) {
          Condition updatedCondition =
              updateScoringDependentCondition(scoringElement.getCondition(), scoringId);
          if (updatedCondition != null) {
            scoringElement.setCondition(updatedCondition);
            updatedScoringElements.add(scoringElement);
          }
        }
        scoring.setElements(updatedScoringElements);
        if (updatedScoringElements.isEmpty()) {
          clearAutoGeneratedRules(
              persistenceService.query(
                  "linkedItems", scoring.getMetadata().getId(), null, Rule.class),
              scoring.getMetadata().getId());
          scoring.getMetadata().setEnabled(false);
        }
        setScoringDefinition(scoring);
      }

      persistenceService.remove(scoringId, Scoring.class);
      List<Rule> previousRules =
          persistenceService.query("linkedItems", scoringId, null, Rule.class);
      clearAutoGeneratedRules(previousRules, scoringId);
    }

    List<Metadata> segments = new LinkedList<>();
    List<Metadata> scorings = new LinkedList<>();
    for (Segment definition : impactedSegments) {
      segments.add(definition.getMetadata());
    }
    for (Scoring definition : impactedScorings) {
      scorings.add(definition.getMetadata());
    }
    return new DependentMetadata(segments, scorings);
  }
 private Set<Segment> getScoringDependentSegments(String scoringId) {
   Set<Segment> impactedSegments = new HashSet<>(this.allSegments.size());
   for (Segment segment : this.allSegments) {
     if (checkScoringDeletionImpact(segment.getCondition(), scoringId)) {
       impactedSegments.add(segment);
     }
   }
   return impactedSegments;
 }
  private void getAutoGeneratedRules(
      Metadata metadata, Condition condition, Condition parentCondition, List<Rule> rules) {
    Set<String> tags = condition.getConditionType().getMetadata().getTags();
    if (tags.contains("eventCondition") && !tags.contains("profileCondition")) {
      try {
        Map<String, Object> m = new HashMap<>(3);
        m.put("scope", metadata.getScope());
        m.put("condition", condition);
        m.put("numberOfDays", parentCondition.getParameter("numberOfDays"));
        String key = CustomObjectMapper.getObjectMapper().writeValueAsString(m);
        key = "eventTriggered" + getMD5(key);
        parentCondition.setParameter("generatedPropertyKey", key);
        Rule rule = rulesService.getRule(key);
        if (rule == null) {
          rule =
              new Rule(
                  new Metadata(
                      metadata.getScope(),
                      key,
                      "Auto generated rule for " + metadata.getName(),
                      ""));
          rule.setCondition(condition);
          rule.getMetadata().setHidden(true);
          final Action action = new Action();
          action.setActionType(definitionsService.getActionType("setEventOccurenceCountAction"));
          action.setParameter("pastEventCondition", parentCondition);

          rule.setActions(Arrays.asList(action));
          rule.setLinkedItems(Arrays.asList(metadata.getId()));
          rules.add(rule);

          updateExistingProfilesForPastEventCondition(condition, parentCondition);
        } else {
          rule.getLinkedItems().add(metadata.getId());
          rules.add(rule);
        }
      } catch (JsonProcessingException e) {
        logger.error(e.getMessage(), e);
      }
    } else {
      Collection<Object> values = new ArrayList<>(condition.getParameterValues().values());
      for (Object parameterValue : values) {
        if (parameterValue instanceof Condition) {
          getAutoGeneratedRules(metadata, (Condition) parameterValue, condition, rules);
        } else if (parameterValue instanceof Collection) {
          for (Object subCondition : (Collection<?>) parameterValue) {
            if (subCondition instanceof Condition) {
              getAutoGeneratedRules(metadata, (Condition) subCondition, condition, rules);
            }
          }
        }
      }
    }
  }
 private Set<Scoring> getScoringDependentScorings(String scoringId) {
   Set<Scoring> impactedScoring = new HashSet<>(this.allScoring.size());
   for (Scoring scoring : this.allScoring) {
     for (ScoringElement element : scoring.getElements()) {
       if (checkScoringDeletionImpact(element.getCondition(), scoringId)) {
         impactedScoring.add(scoring);
         break;
       }
     }
   }
   return impactedScoring;
 }
  public SegmentsAndScores getSegmentsAndScoresForProfile(Profile profile) {
    Set<String> segments = new HashSet<String>();
    Map<String, Integer> scores = new HashMap<String, Integer>();

    List<Segment> allSegments = this.allSegments;
    for (Segment segment : allSegments) {
      if (persistenceService.testMatch(segment.getCondition(), profile)) {
        segments.add(segment.getMetadata().getId());
      }
    }

    List<Scoring> allScoring = this.allScoring;
    Map<String, Integer> scoreModifiers =
        (Map<String, Integer>) profile.getSystemProperties().get("scoreModifiers");
    for (Scoring scoring : allScoring) {
      if (scoring.getMetadata().isEnabled()) {
        int score = 0;
        for (ScoringElement scoringElement : scoring.getElements()) {
          if (persistenceService.testMatch(scoringElement.getCondition(), profile)) {
            score += scoringElement.getValue();
          }
        }
        String scoringId = scoring.getMetadata().getId();
        if (scoreModifiers != null
            && scoreModifiers.containsKey(scoringId)
            && scoreModifiers.get(scoringId) != null) {
          score += scoreModifiers.get(scoringId);
        }
        if (score > 0) {
          scores.put(scoringId, score);
        }
      }
    }

    return new SegmentsAndScores(segments, scores);
  }
  public Boolean isProfileInSegment(Profile profile, String segmentId) {
    Set<String> matchingSegments = getSegmentsAndScoresForProfile(profile).getSegments();

    return matchingSegments.contains(segmentId);
  }
  public DependentMetadata removeSegmentDefinition(String segmentId, boolean validate) {
    Set<Segment> impactedSegments = getSegmentDependentSegments(segmentId);
    Set<Scoring> impactedScorings = getSegmentDependentScorings(segmentId);
    if (!validate || (impactedSegments.isEmpty() && impactedScorings.isEmpty())) {
      // update profiles
      Condition segmentCondition = new Condition();
      segmentCondition.setConditionType(
          definitionsService.getConditionType("profilePropertyCondition"));
      segmentCondition.setParameter("propertyName", "segments");
      segmentCondition.setParameter("comparisonOperator", "equals");
      segmentCondition.setParameter("propertyValue", segmentId);

      List<Profile> previousProfiles =
          persistenceService.query(segmentCondition, null, Profile.class);
      for (Profile profileToRemove : previousProfiles) {
        profileToRemove.getSegments().remove(segmentId);
        persistenceService.update(
            profileToRemove.getItemId(),
            null,
            Profile.class,
            "segments",
            profileToRemove.getSegments());
      }

      // update impacted segments
      for (Segment segment : impactedSegments) {
        Condition updatedCondition =
            updateSegmentDependentCondition(segment.getCondition(), segmentId);
        segment.setCondition(updatedCondition);
        if (updatedCondition == null) {
          clearAutoGeneratedRules(
              persistenceService.query(
                  "linkedItems", segment.getMetadata().getId(), null, Rule.class),
              segment.getMetadata().getId());
          segment.getMetadata().setEnabled(false);
        }
        setSegmentDefinition(segment);
      }

      // update impacted scorings
      for (Scoring scoring : impactedScorings) {
        List<ScoringElement> updatedScoringElements = new ArrayList<>();
        for (ScoringElement scoringElement : scoring.getElements()) {
          Condition updatedCondition =
              updateSegmentDependentCondition(scoringElement.getCondition(), segmentId);
          if (updatedCondition != null) {
            scoringElement.setCondition(updatedCondition);
            updatedScoringElements.add(scoringElement);
          }
        }
        scoring.setElements(updatedScoringElements);
        if (updatedScoringElements.isEmpty()) {
          clearAutoGeneratedRules(
              persistenceService.query(
                  "linkedItems", scoring.getMetadata().getId(), null, Rule.class),
              scoring.getMetadata().getId());
          scoring.getMetadata().setEnabled(false);
        }
        setScoringDefinition(scoring);
      }

      persistenceService.remove(segmentId, Segment.class);
      List<Rule> previousRules =
          persistenceService.query("linkedItems", segmentId, null, Rule.class);
      clearAutoGeneratedRules(previousRules, segmentId);
    }

    List<Metadata> segments = new LinkedList<>();
    List<Metadata> scorings = new LinkedList<>();
    for (Segment definition : impactedSegments) {
      segments.add(definition.getMetadata());
    }
    for (Scoring definition : impactedScorings) {
      scorings.add(definition.getMetadata());
    }
    return new DependentMetadata(segments, scorings);
  }