private ProcessRuntimeMetrics getRuntimeMetrics(final ProcessIdentifier identifier) {
    final CriteriaBuilder cb = em.getCriteriaBuilder();
    final CriteriaQuery<MeasuredProcessInstance> cq = cb.createQuery(MeasuredProcessInstance.class);
    final Root<MeasuredProcessInstance> processInstanceRoot =
        cq.from(MeasuredProcessInstance.class);
    cq.where(
        cb.equal(
            processInstanceRoot
                .get(MeasuredProcessInstance_.identifier)
                .get(ProcessInstanceIdentifier_.metricsId),
            identifier.getMetricsId()),
        cb.equal(
            processInstanceRoot
                .get(MeasuredProcessInstance_.identifier)
                .get(ProcessInstanceIdentifier_.packageName),
            identifier.getPackageName()),
        cb.equal(
            processInstanceRoot
                .get(MeasuredProcessInstance_.identifier)
                .get(ProcessInstanceIdentifier_.processId),
            identifier.getProcessId()));
    final List<MeasuredProcessInstance> instances = em.createQuery(cq).getResultList();

    final ProcessRuntimeMetrics metrics = new ProcessRuntimeMetrics();
    long totalRuntime = 0L;
    for (final MeasuredProcessInstance instance : instances) {
      if (instance.getTimeToComplete() == null) {
        continue;
      }
      final long runtime = instance.getTimeToComplete().longValue();
      totalRuntime += runtime;
      if ((metrics.getMinRuntime() == 0) || (metrics.getMinRuntime() > runtime)) {
        metrics.setMinRuntime(runtime);
      }
      if ((metrics.getMaxRuntime() == 0) || (metrics.getMaxRuntime() < runtime)) {
        metrics.setMaxRuntime(runtime);
      }
    }
    final long totalInstances = instances.size();
    metrics.setNumberOfInstances(totalInstances);
    if (totalInstances != 0) {
      metrics.setMeanRuntime(totalRuntime / totalInstances);
    } else {
      metrics.setMeanRuntime(0);
    }
    return metrics;
  }
 public ProcessRuntimeMetrics getRuntimeMetrics(final List<ProcessIdentifier> identifiers) {
   final ProcessRuntimeMetrics totalMetrics = new ProcessRuntimeMetrics();
   long sumOfRuntimes = 0;
   long sumOfInstances = 0;
   for (final ProcessIdentifier identifier : identifiers) {
     final ProcessRuntimeMetrics procMetrics = getRuntimeMetrics(identifier);
     sumOfRuntimes += procMetrics.getMeanRuntime() * procMetrics.getNumberOfInstances();
     sumOfInstances += procMetrics.getNumberOfInstances();
     if ((totalMetrics.getMinRuntime() == 0)
         || (totalMetrics.getMinRuntime() > procMetrics.getMinRuntime())) {
       totalMetrics.setMinRuntime(procMetrics.getMinRuntime());
     }
     if ((totalMetrics.getMaxRuntime() == 0)
         || (totalMetrics.getMaxRuntime() < procMetrics.getMaxRuntime())) {
       totalMetrics.setMaxRuntime(procMetrics.getMaxRuntime());
     }
   }
   totalMetrics.setNumberOfInstances(sumOfInstances);
   if (sumOfInstances != 0) {
     totalMetrics.setMeanRuntime(sumOfRuntimes / sumOfInstances);
   } else {
     totalMetrics.setMeanRuntime(0);
   }
   return totalMetrics;
 }