/** @see org.vedantatree.expressionoasis.expressions.UnaryOperatorExpression#validate() */
  @Override
  protected void validate(ExpressionContext expressionContext) throws ExpressionEngineException {
    // Initializes the function provider.
    ParanthesisExpression argsExpression = (ParanthesisExpression) getOperandExpression();
    List<Type> types = new ArrayList<Type>();
    List values = new ArrayList();
    populateTypesAndValues(argsExpression.getOperandExpression(), types, values);

    Type[] parameterTypes = (Type[]) types.toArray(new Type[types.size()]);

    for (Iterator functionProviders = expressionContext.getFunctionProviders().iterator();
        functionProviders.hasNext(); ) {
      FunctionProvider functionProvider = (FunctionProvider) functionProviders.next();

      if (functionProvider.supportsFunction(functionName, parameterTypes)) {
        this.functionProvider = functionProvider;

        break;
      }
    }

    if (functionProvider == null) {
      throw new ExpressionEngineException(
          "No Function Provider exists for function: ["
              + MethodKey.generateKey(functionName, parameterTypes)
              + "]");
    }
  }
  /** @see org.vedantatree.expressionoasis.expressions.Expression#getValue(java.lang.Object) */
  public ValueObject getValue() throws ExpressionEngineException {
    List<ValueObject> values = new ArrayList<ValueObject>();
    ParanthesisExpression argsExpression = (ParanthesisExpression) getOperandExpression();
    populateTypesAndValues(argsExpression.getOperandExpression(), null, values);

    ValueObject[] parameters = (ValueObject[]) values.toArray(new ValueObject[values.size()]);

    return functionProvider.getFunctionValue(functionName, parameters);
  }
  /** @see org.vedantatree.expressionoasis.expressions.Expression#getReturnType() */
  @Override
  public Type getReturnType() throws ExpressionEngineException {
    List<Type> types = new ArrayList<Type>();
    ParanthesisExpression argsExpression = (ParanthesisExpression) getOperandExpression();
    populateTypesAndValues(argsExpression.getOperandExpression(), types, null);

    Type[] parameterTypes = (Type[]) types.toArray(new Type[types.size()]);

    return functionProvider.getFunctionType(functionName, parameterTypes);
  }