/**
   * @param modelCache
   * @param ai
   * @return
   */
  private static Map<String, DescriptorDTO> getProcessDescriptors(
      ModelCache modelCache, ActivityInstance ai) {
    List<ProcessDescriptor> processDescriptorsList = CollectionUtils.newList();

    Model model = modelCache.getModel(ai.getModelOID());
    ProcessDefinition processDefinition =
        (model != null) ? model.getProcessDefinition(ai.getProcessDefinitionId()) : null;
    if (processDefinition != null) {
      ProcessInstanceDetails processInstanceDetails =
          (ProcessInstanceDetails) ai.getProcessInstance();
      Map<String, Object> descriptorValues = processInstanceDetails.getDescriptors();
      CommonDescriptorUtils.updateProcessDocumentDescriptors(
          descriptorValues, ai.getProcessInstance(), processDefinition);
      if (processInstanceDetails.isCaseProcessInstance()) {
        processDescriptorsList =
            CommonDescriptorUtils.createCaseDescriptors(
                processInstanceDetails.getDescriptorDefinitions(),
                descriptorValues,
                processDefinition,
                true);
      } else {
        processDescriptorsList =
            CommonDescriptorUtils.createProcessDescriptors(
                descriptorValues, processDefinition, true, true);
      }

      Map<String, DescriptorDTO> descriptors = new LinkedHashMap<String, DescriptorDTO>();
      for (Object descriptor : processDescriptorsList) {
        if (descriptor instanceof ProcessDocumentDescriptor) {
          ProcessDocumentDescriptor desc = (ProcessDocumentDescriptor) descriptor;

          List<DocumentDTO> documents = new ArrayList<DocumentDTO>();

          for (DocumentInfo documentInfo : desc.getDocuments()) {
            DocumentDTO documentDTO = new DocumentDTO();
            documentDTO.name = documentInfo.getName();
            documentDTO.uuid = documentInfo.getId();
            documentDTO.contentType =
                (MimeTypesHelper.detectMimeType(documentInfo.getName(), null).getType());
            documents.add(documentDTO);
          }

          DescriptorDTO descriptorDto =
              new DescriptorDTO(desc.getKey(), desc.getValue(), true, documents);
          descriptors.put(desc.getId(), descriptorDto);
        } else {
          ProcessDescriptor desc = (ProcessDescriptor) descriptor;
          DescriptorDTO descriptorDto =
              new DescriptorDTO(desc.getKey(), desc.getValue(), false, null);
          descriptors.put(desc.getId(), descriptorDto);
        }
      }
      return descriptors;
    }
    return null;
  }
  /**
   * @param query
   * @param options
   */
  public static void addSortCriteria(Query query, Options options) {
    boolean worklistQuery = query instanceof WorklistQuery;

    if (options.visibleDescriptorColumns.contains(options.orderBy)) {
      Map<String, DataPath> allDescriptors = ProcessDefinitionUtils.getAllDescriptors(false);
      String descriptorName = options.orderBy;
      if (allDescriptors.containsKey(descriptorName)) {
        DescriptorUtils.applyDescriptorPolicy(query, options);
        String columnName = DescriptorUtils.getDescriptorColumnName(descriptorName, allDescriptors);
        if (CommonDescriptorUtils.isStructuredData(allDescriptors.get(descriptorName))) {
          query.orderBy(
              new DataOrder(
                  columnName,
                  DescriptorUtils.getXpathName(descriptorName, allDescriptors),
                  options.asc));
        } else {
          query.orderBy(new DataOrder(columnName, options.asc));
        }
      }
    } else if (COL_ACTIVITY_NAME.equals(options.orderBy)) {
      query.orderBy(ActivityInstanceQuery.ACTIVITY_NAME.ascendig(options.asc));
    } else if (COL_ACTIVITY_INSTANCE_OID.equals(options.orderBy)) {
      query.orderBy(
          worklistQuery ? WorklistQuery.ACTIVITY_INSTANCE_OID : ActivityInstanceQuery.OID,
          options.asc);
    } else if (COL_START_TIME.equals(options.orderBy)) {
      query.orderBy(
          worklistQuery ? WorklistQuery.START_TIME : ActivityInstanceQuery.START_TIME, options.asc);
    } else if (COL_LAST_MODIFICATION_TIME.equals(options.orderBy)) {
      query.orderBy(
          worklistQuery
              ? WorklistQuery.LAST_MODIFICATION_TIME
              : ActivityInstanceQuery.LAST_MODIFICATION_TIME,
          options.asc);
    } else if (COL_PRIOIRTY.equals(options.orderBy)) {
      query.orderBy(
          worklistQuery
              ? WorklistQuery.PROCESS_INSTANCE_PRIORITY
              : ActivityInstanceQuery.PROCESS_INSTANCE_PRIORITY,
          options.asc);
    } else if (COL_CRITICALITY.equals(options.orderBy)) {
      query.orderBy(
          worklistQuery
              ? WorklistQuery.ACTIVITY_INSTANCE_CRITICALITY
              : ActivityInstanceQuery.CRITICALITY,
          options.asc);
    } else if (COL_PROCESS_OID.equals(options.orderBy)) {
      query.orderBy(
          worklistQuery
              ? WorklistQuery.PROCESS_INSTANCE_OID
              : ActivityInstanceQuery.PROCESS_INSTANCE_OID,
          options.asc);
    } else if (COL_BENCHMARK.equals(options.orderBy)) {
      query.orderBy(ActivityInstanceQuery.BENCHMARK_VALUE, options.asc);
    }
  }
  private void calculateIconStatus(ProcessProgressInstance instance) {
    if (instance != null && instance.getTerminationTime() != null) {
      this.completeIconStatus = true;
    } else {
      this.completeIconStatus = false;
    }

    this.completeText = "";

    if (instance != null && !instance.getDescriptors().isEmpty()) {
      this.descriptorIconStatus = true;

      List<ProcessDescriptor> processdescList =
          CommonDescriptorUtils.createProcessDescriptors(instance.getProcessInstance(), false);

      StringBuffer buffer = new StringBuffer();
      for (ProcessDescriptor processDescriptors : processdescList) {
        if (StringUtils.isNotEmpty(buffer.toString())) {
          buffer.append(", ");
        }
        buffer
            .append(processDescriptors.getKey())
            .append(" : ")
            .append(processDescriptors.getValue());
      }

      this.descriptorText = buffer.toString();

      if (instance.getNote() != null) {
        this.noteIconStatus = true;
        this.noteText = instance.getNote();
      } else {
        this.noteIconStatus = false;
      }

      if (instance.getError() != null) {
        this.errorIconStatus = true;
        this.errorText = instance.getError();
      } else {
        this.errorIconStatus = false;
      }
    } else {
      this.descriptorIconStatus = false;
      this.noteIconStatus = false;
      this.descriptorIconStatus = false;
    }
  }