public TypeValuePair evaluate(final FormulaContext context, final ParameterCallback parameters)
      throws EvaluationException {
    final int parameterCount = parameters.getParameterCount();
    if (parameterCount < 1) {
      throw EvaluationException.getInstance(LibFormulaErrorValue.ERROR_ARGUMENTS_VALUE);
    }

    final Type type1 = parameters.getType(0);
    final Object value = parameters.getValue(0);

    final TypeRegistry typeRegistry = context.getTypeRegistry();
    final Number number = typeRegistry.convertToNumber(type1, value);

    if (number == null) {
      throw EvaluationException.getInstance(LibFormulaErrorValue.ERROR_INVALID_ARGUMENT_VALUE);
    }

    int intValue = number.intValue();
    if (intValue < 0) {
      intValue *= -1;
    }

    if (intValue % 2 == 1) {
      return RETURN_TRUE;
    }

    return RETURN_FALSE;
  }
  public TypeValuePair evaluate(final FormulaContext context, final ParameterCallback parameters)
      throws EvaluationException {

    final int parameterCount = parameters.getParameterCount();
    if (parameterCount < 1) {
      throw EvaluationException.getInstance(LibFormulaErrorValue.ERROR_ARGUMENTS_VALUE);
    }

    final TypeRegistry typeRegistry = context.getTypeRegistry();
    final double value =
        typeRegistry.convertToNumber(parameters.getType(0), parameters.getValue(0)).doubleValue();

    if (value == 0) {
      return new TypeValuePair(TextType.TYPE, "0 ");
    }

    boolean fixedSize = false;
    int precision = 0;

    if (parameters.getParameterCount() > 1) {
      fixedSize = true;
      precision =
          typeRegistry.convertToNumber(parameters.getType(1), parameters.getValue(1)).intValue();
      if (parameters.getParameterCount() == 3) {
        final Boolean rawFixedSize =
            typeRegistry.convertToLogical(parameters.getType(2), parameters.getValue(2));
        fixedSize = rawFixedSize.booleanValue();
      }
    }

    final int log10 = computeLog10(value);

    // index will allow us to find the the index of the suffix to use
    final int index = (int) (Math.floor(log10 / 3.0) + OFFSET);
    if (index < 0 || index >= SUFFIXES.length) {
      throw EvaluationException.getInstance(LibFormulaErrorValue.ERROR_UNEXPECTED_VALUE);
    }

    // Find the adequate precision. % operator behaves badly in negative results, so we need to make
    // it work as expected
    final int roundPrecision =
        fixedSize ? (log10 - precision) : (log10 - (precision + (3 + log10 % 3) % 3));

    // Round the value
    final double roundingScale = Math.pow(10, roundPrecision);
    final double rounded = Math.round(value / roundingScale) * roundingScale;

    // Get it's eng format. Get it as string without trailing 0's
    final double outputValue = rounded / Math.pow(10, Math.floor(log10 / 3.0) * 3);
    final int outputValueDecimalPlaces = Math.max(1, computeLog10(outputValue));

    final Locale locale = context.getLocalizationContext().getLocale();
    final NumberFormat decimalFormat =
        createDecimalFormat(fixedSize, outputValueDecimalPlaces, precision, locale);
    final String result = decimalFormat.format(outputValue) + SUFFIXES[index];
    return new TypeValuePair(TextType.TYPE, result);
  }
  public TypeValuePair evaluate(final FormulaContext context, final ParameterCallback parameters)
      throws EvaluationException {
    final int parameterCount = parameters.getParameterCount();
    if (parameterCount < 1) {
      throw EvaluationException.getInstance(LibFormulaErrorValue.ERROR_ARGUMENTS_VALUE);
    }
    final Type type1 = parameters.getType(0);
    final Object value1 = parameters.getValue(0);
    final String result = context.getTypeRegistry().convertToText(type1, value1);

    if (result == null) {
      throw EvaluationException.getInstance(LibFormulaErrorValue.ERROR_INVALID_ARGUMENT_VALUE);
    }

    // remove all unnecessary spaces ..
    // we dont use regexps, because they are JDK 1.4, but this library is aimed
    // for JDK 1.2.2

    final char[] chars = result.toCharArray();
    final StringBuffer b = new StringBuffer(chars.length);
    boolean removeNextWs = true;

    for (int i = 0; i < chars.length; i++) {
      final char c = chars[i];
      if (Character.isWhitespace(c)) {
        if (removeNextWs) {
          continue;
        }
        b.append(c);
        removeNextWs = true;
        continue;
      }

      b.append(c);
      removeNextWs = false;
    }

    // now check whether the last char is a whitespace and remove that one
    // if neccessary
    final String trimmedResult;
    if (removeNextWs && b.length() > 0) {
      trimmedResult = b.substring(0, b.length() - 1);
    } else {
      trimmedResult = b.toString();
    }

    return new TypeValuePair(TextType.TYPE, trimmedResult);
  }
  public TypeValuePair evaluate(final FormulaContext context, final ParameterCallback parameters)
      throws EvaluationException {
    final int parameterCount = parameters.getParameterCount();

    if (parameterCount < 1) {
      throw EvaluationException.getInstance(LibFormulaErrorValue.ERROR_ARGUMENTS_VALUE);
    }

    try {
      Object value = parameters.getValue(0);

      if (value == null) return RETURN_TRUE;
      else return RETURN_FALSE;
    } catch (EvaluationException e) {
      throw e;
    }
  }
  public TypeValuePair evaluate(final FormulaContext context, final ParameterCallback parameters)
      throws EvaluationException {
    if (parameters.getParameterCount() != 0) {
      throw EvaluationException.getInstance(LibFormulaErrorValue.ERROR_ARGUMENTS_VALUE);
    }

    throw EvaluationException.getInstance(LibFormulaErrorValue.ERROR_NA_VALUE);
  }
  public TypeValuePair evaluate(final FormulaContext context, final ParameterCallback parameters)
      throws EvaluationException {
    if (parameters.getParameterCount() != 3) {
      throw EvaluationException.getInstance(LibFormulaErrorValue.ERROR_ARGUMENTS_VALUE);
    }

    // 0: Configuration-indicator (gives the pattern indirectly) never the pattern itself
    // 1: the report-path
    // 2: the parameter as 2d-array (name value pairs)

    final TypeRegistry typeRegistry = context.getTypeRegistry();
    final String configIndicator =
        typeRegistry.convertToText(parameters.getType(0), parameters.getValue(0));
    String path;
    try {
      path = typeRegistry.convertToText(parameters.getType(1), parameters.getValue(1));
    } catch (EvaluationException ee) {
      if (LibFormulaErrorValue.ERROR_NA_VALUE.equals(ee.getErrorValue())) {
        path = null;
      } else {
        throw ee;
      }
    }
    final ArrayCallback parameter =
        typeRegistry.convertToArray(parameters.getType(2), parameters.getValue(2));

    final LinkCustomizer pattern = createLinkCustomizer(configIndicator);
    return new TypeValuePair(
        TextType.TYPE,
        pattern.format(
            context, configIndicator, path, computeParameterEntries(parameter, typeRegistry)));
  }
  public TypeValuePair evaluate(final FormulaContext context, final ParameterCallback parameters)
      throws EvaluationException {
    if (context instanceof ReportFormulaContext == false) {
      throw EvaluationException.getInstance(LibFormulaErrorValue.ERROR_INVALID_FUNCTION_VALUE);
    }

    final ReportFormulaContext rfc = (ReportFormulaContext) context;

    final int parameterCount = parameters.getParameterCount();
    if (parameterCount < 1) {
      throw EvaluationException.getInstance(LibFormulaErrorValue.ERROR_ARGUMENTS_VALUE);
    }

    final Type textType = parameters.getType(0);
    final Object textValue = parameters.getValue(0);
    final String query = context.getTypeRegistry().convertToText(textType, textValue);

    if (query == null) {
      throw EvaluationException.getInstance(LibFormulaErrorValue.ERROR_INVALID_ARGUMENT_VALUE);
    }

    final String resultColumn;
    if (parameterCount > 1) {
      final Type encodingType = parameters.getType(1);
      final Object encodingValue = parameters.getValue(1);
      resultColumn = context.getTypeRegistry().convertToText(encodingType, encodingValue);
      if (resultColumn == null) {
        throw EvaluationException.getInstance(LibFormulaErrorValue.ERROR_INVALID_ARGUMENT_VALUE);
      }
    } else {
      resultColumn = null;
    }

    final int queryTimeOut;
    if (parameterCount > 2) {
      final Type encodingType = parameters.getType(2);
      final Object encodingValue = parameters.getValue(2);
      final Number number = context.getTypeRegistry().convertToNumber(encodingType, encodingValue);
      if (number == null) {
        throw EvaluationException.getInstance(LibFormulaErrorValue.ERROR_INVALID_ARGUMENT_VALUE);
      }
      queryTimeOut = number.intValue();
    } else {
      queryTimeOut = 0;
    }

    final int queryLimit;
    if (parameterCount > 3) {
      final Type encodingType = parameters.getType(3);
      final Object encodingValue = parameters.getValue(3);
      final Number number = context.getTypeRegistry().convertToNumber(encodingType, encodingValue);
      if (number == null) {
        throw EvaluationException.getInstance(LibFormulaErrorValue.ERROR_INVALID_ARGUMENT_VALUE);
      }
      queryLimit = number.intValue();
    } else {
      queryLimit = 0;
    }

    final Object result = performQuery(rfc, query, resultColumn, queryTimeOut, queryLimit);
    return new TypeValuePair(AnyType.ANY_ARRAY, result);
  }