public static ActivityStatisticsQuery forProcesses(Set<ProcessDefinition> processes) {
    Set<String> processIds = CollectionUtils.newSet();
    for (Iterator<ProcessDefinition> i = processes.iterator(); i.hasNext(); ) {
      ProcessDefinition process = i.next();
      processIds.add(process.getQualifiedId());
    }

    return forProcessIds(processIds);
  }
  public static List<TransitionTarget> getRelocateTargets(
      long activityInstanceOid, TransitionOptions options, ScanDirection direction) {
    IActivityInstance ai = ActivityInstanceBean.findByOID(activityInstanceOid);
    IActivity activity = ai.getActivity();

    if (!activity.getBooleanAttribute(PredefinedConstants.ACTIVITY_IS_RELOCATE_SOURCE_ATT)) {
      // activity is not a relocation source
      return Collections.emptyList();
    }

    Stack<TransitionStep> steps = new Stack();
    List<TransitionTarget> targets = CollectionUtils.newList();
    Set<TransitionTarget> visited = CollectionUtils.newSet();
    switch (direction) {
      case FORWARD:
        addActivities(
            visited,
            targets,
            ai,
            options == null ? TransitionOptions.DEFAULT : options,
            true,
            steps);
        break;
      case BACKWARD:
        addActivities(
            visited,
            targets,
            ai,
            options == null ? TransitionOptions.DEFAULT : options,
            false,
            steps);
        break;
      default:
        addActivities(
            visited,
            targets,
            ai,
            options == null ? TransitionOptions.DEFAULT : options,
            true,
            steps);
        addActivities(
            visited,
            targets,
            ai,
            options == null ? TransitionOptions.DEFAULT : options,
            false,
            steps);
    }
    return targets;
  }
 private void checkValue(
     List<BusinessObject.Value> boValues, boolean strict, String name, Object... values) {
   Set<Object> expected = CollectionUtils.newSetFromIterator(Arrays.asList(values).iterator());
   Set<Object> actual = CollectionUtils.newSet();
   for (BusinessObject.Value boValue : boValues) {
     Map<?, ?> data = (Map<?, ?>) boValue.getValue();
     actual.add(data.get(name));
   }
   if (strict) {
     Assert.assertEquals("Values: ", expected, actual);
   } else {
     expected.removeAll(actual);
     Assert.assertTrue("Missing values: " + expected, expected.isEmpty());
   }
 }
 @Override
 public Collection<IDaemon> getDaemons() {
   List<IModel> models = ModelManagerFactory.getCurrent().findActiveModels();
   if (!models.isEmpty()) {
     Set<String> ids = CollectionUtils.newSet();
     List<IDaemon> daemons = CollectionUtils.newList();
     for (IModel model : models) {
       // Compute and store the model dependent daemons in model for faster lookup
       List<IDaemon> modelDependentDaemons;
       synchronized (model) {
         modelDependentDaemons =
             (List<IDaemon>) model.getRuntimeAttribute(CACHED_DAEMON_FACTORY);
         if (modelDependentDaemons == null) {
           modelDependentDaemons = CollectionUtils.newList();
           for (Iterator i = model.getAllTriggerTypes(); i.hasNext(); ) {
             ITriggerType type = (ITriggerType) i.next();
             if (type.isPullTrigger()) {
               modelDependentDaemons.add(new TriggerDaemon(type));
             }
           }
           model.setRuntimeAttribute(CACHED_DAEMON_FACTORY, modelDependentDaemons);
         }
       }
       // Compute union of all daemons
       // This always has to be computed as the daemons of a model might change
       // if new model version is deployed
       for (IDaemon daemon : modelDependentDaemons) {
         String type = daemon.getType();
         if (!ids.contains(type)) {
           daemons.add(daemon);
           ids.add(type);
         }
       }
     }
     return daemons;
   }
   return Collections.emptyList();
 }