private boolean haveSomeOrAllNonRepeatableOutputParameterValues() {
   InstrumentType instrumentType = getInstrumentType();
   InstrumentRun instrumentRun = activeInstrumentRunService.getInstrumentRun();
   for (InstrumentOutputParameter instrumentOutputParameter :
       instrumentType.getOutputParameters()) {
     InstrumentRunValue instrumentRunValue =
         instrumentRun.getInstrumentRunValue(instrumentOutputParameter);
     if (instrumentRunValue != null) {
       if (instrumentRunValue.getData(instrumentOutputParameter.getDataType()).getValue() != null)
         return true;
     }
   }
   return false; // No values found
 }
 private boolean haveSomeOrAllRepeatingOutputParameterValues() {
   InstrumentType instrumentType = getInstrumentType();
   InstrumentRun instrumentRun = activeInstrumentRunService.getInstrumentRun();
   Participant participant = activeInstrumentRunService.getParticipant();
   if (instrumentType.getExpectedMeasureCount(participant) == 0) return false; // No values
   for (Measure measure : instrumentRun.getMeasures()) {
     InstrumentRun measureInstrumentRun = measure.getInstrumentRun();
     for (InstrumentOutputParameter instrumentOutputParameter :
         instrumentType.getOutputParameters()) {
       InstrumentRunValue instrumentRunValue =
           measureInstrumentRun.getInstrumentRunValue(instrumentOutputParameter);
       if (instrumentRunValue != null) {
         if (instrumentRunValue.getData(instrumentOutputParameter.getDataType()).getValue()
             != null) return true;
       }
     }
   }
   return false; // No values found
 }
  /**
   * Convert the value from a source unit to a target unit Note: if the value is an age, the method
   * adjusts the value to return the right age
   *
   * @param activeInstrumentRunService
   * @param targetInstrumentRunValue
   * @param sourceInstrumentRunValue
   */
  @SuppressWarnings("unchecked")
  public void convert(
      ActiveInstrumentRunService activeInstrumentRunService,
      InstrumentRunValue targetInstrumentRunValue,
      InstrumentRunValue sourceInstrumentRunValue) {

    InstrumentParameter sourceParameter =
        activeInstrumentRunService
            .getInstrumentType()
            .getInstrumentParameter(sourceInstrumentRunValue.getInstrumentParameter());
    InstrumentParameter targetParameter =
        activeInstrumentRunService
            .getInstrumentType()
            .getInstrumentParameter(targetInstrumentRunValue.getInstrumentParameter());

    log.debug(
        "Converting parameters from source {} to target {}", sourceParameter, targetParameter);

    Unit sourceUnit = Unit.valueOf(sourceParameter.getMeasurementUnit());
    Unit targetUnit = Unit.valueOf(targetParameter.getMeasurementUnit());

    log.debug(
        "Converting units from source {} to target {}",
        sourceUnit.toString(),
        targetUnit.toString());

    double sourceValue;
    // Extract the source value and convert it to a double
    try {
      sourceValue =
          Double.parseDouble(
              sourceInstrumentRunValue.getData(sourceParameter.getDataType()).getValueAsString());
    } catch (NumberFormatException e) {
      Data sourceData = sourceInstrumentRunValue.getData(sourceParameter.getDataType());
      log.error(
          "Error converting between measurement units. Original value {} of type {} cannot be converted to a double, which is required to convert between measurement units.",
          sourceData.getValueAsString(),
          sourceData.getType());
      throw e;
    }

    double newValue = sourceUnit.getConverterTo(targetUnit).convert(sourceValue);

    switch (activeInstrumentRunService
        .getInstrumentType()
        .getInstrumentParameter(targetInstrumentRunValue.getInstrumentParameter())
        .getDataType()) {
      case DECIMAL:
        targetInstrumentRunValue.setData(DataBuilder.buildDecimal(newValue));
        break;

      case INTEGER:
        if (targetUnit.toString().equalsIgnoreCase("year")) newValue = Math.floor(newValue);
        targetInstrumentRunValue.setData(DataBuilder.buildInteger(Math.round(newValue)));
        break;
    }
  }
  @Override
  public boolean checkParameterValue(
      InstrumentParameter checkedParameter,
      Data paramData,
      InstrumentRunService runService,
      ActiveInstrumentRunService activeRunService) {
    if (parameterCode != null && (percent != null || offset != null)) {
      //
      // Get the other parameter's value.
      //
      InstrumentRunValue otherRunValue = activeRunService.getInstrumentRunValue(parameterCode);

      Data otherData = null;
      if (otherRunValue != null) {
        otherData = otherRunValue.getData(paramData.getType());
      }

      if (otherData != null && otherData.getValue() != null) {
        // Lazily instantiate the rangeCheck.
        if (rangeCheck == null) {
          rangeCheck = new RangeCheck();
        }

        if (checkedParameter.getDataType() == DataType.INTEGER) {
          initIntegerRangeCheck(paramData, otherData);
        } else if (checkedParameter.getDataType() == DataType.DECIMAL) {
          initDecimalRangeCheck(paramData, otherData);
        } else {
          return false;
        }

        return rangeCheck.checkParameterValue(
            checkedParameter, paramData, runService, activeRunService);
      } else { // no need to check the spread if the other parameter does not yet have a value
        return true;
      }
    } else { // nothing to check!
      return true;
    }
  }
  /**
   * Convert the value from a source DataType to a target DataType (DECIMAL vs INTEGER)
   *
   * @param targetInstrumentRunValue
   * @param sourceData
   */
  @SuppressWarnings("unchecked")
  public void convert(
      InstrumentParameter targetInstrumentParameter,
      InstrumentRunValue targetInstrumentRunValue,
      Data sourceData) {

    log.debug(
        "Converting parameters from source {} to target {}",
        sourceData.getType(),
        targetInstrumentParameter.getDataType());

    double newValue = Double.parseDouble(sourceData.getValueAsString());

    switch (targetInstrumentParameter.getDataType()) {
      case DECIMAL:
        targetInstrumentRunValue.setData(DataBuilder.buildDecimal(newValue));
        break;

      case INTEGER:
        targetInstrumentRunValue.setData(DataBuilder.buildInteger(Math.round(newValue)));
        break;
    }
  }
 /**
  * Returns true if at least one interpretive parameter has a value.
  *
  * @return True if we have at least one interpretive parameter value.
  */
 private boolean hasSomeOrAllInterpretiveParameterValues() {
   InstrumentType instrumentType = getInstrumentType();
   InstrumentRun instrumentRun = activeInstrumentRunService.getInstrumentRun();
   for (InterpretativeParameter interpretiveParameter :
       instrumentType.getInterpretativeParameters()) {
     InstrumentRunValue instrumentRunValue =
         instrumentRun.getInstrumentRunValue(interpretiveParameter);
     if (instrumentRunValue != null) {
       if (instrumentRunValue.getData(interpretiveParameter.getDataType()).getValue() != null)
         return true;
     }
   }
   for (InstrumentInputParameter instrumentInputParameter :
       instrumentType.getInputParameters(false)) {
     InstrumentRunValue instrumentRunValue =
         instrumentRun.getInstrumentRunValue(instrumentInputParameter);
     if (instrumentRunValue != null) {
       if (instrumentRunValue.getData(instrumentInputParameter.getDataType()).getValue() != null)
         return true;
     }
   }
   return false;
 }
  /**
   * Returns <code>true</code> if the specified instrument run value is equal to the value of the
   * configured other parameter.
   *
   * @param runValue instrument run value
   * @param runService instrument run service
   * @return <code>true</code> if instrument run value equals value of configured other parameter
   */
  public boolean checkParameterValue(
      InstrumentParameter checkedParameter,
      Data paramData,
      InstrumentRunService runService,
      ActiveInstrumentRunService activeRunService) {
    // If the other parameter has not been specified, there is nothing to check!
    if (parameterCode == null) {
      return true;
    }

    //
    // Get the other parameter's value.
    //
    log.debug("Retrieving parameter value : {}", parameterCode);

    InstrumentRunValue otherRunValue = activeRunService.getInstrumentRunValue(parameterCode);
    Data otherData = null;

    if (otherRunValue != null) {
      InstrumentParameter otherParam =
          activeRunService
              .getInstrumentType()
              .getInstrumentParameter(otherRunValue.getInstrumentParameter());

      if (!otherParam.getDataType().equals(paramData.getType())) {
        InstrumentRunValue targetRunValue = new InstrumentRunValue();
        targetRunValue.setInstrumentParameter(checkedParameter.getCode());
        UnitParameterValueConverter converter = new UnitParameterValueConverter();
        converter.convert(activeRunService, targetRunValue, otherRunValue);
        otherData = targetRunValue.getData(paramData.getType());
      } else {
        InstrumentParameter otherParameter =
            activeRunService.getInstrumentType().getInstrumentParameter(parameterCode);
        otherData = otherRunValue.getData(otherParameter.getDataType());
      }
    } else {
      log.debug("Value is : null");
    }

    // Lazily instantiate the equalsValueCheck.
    EqualsValueCheck equalsValueCheck = new EqualsValueCheck();

    // Update the equalsValueCheck accordingly.
    equalsValueCheck.setData(otherData);
    equalsValueCheck.setOperator(operator);

    return equalsValueCheck.checkParameterValue(
        checkedParameter, paramData, runService, activeRunService);
  }