@Override
  public Object evaluate(DeferredObject[] arguments) throws HiveException {
    List<?> inputs = (List<?>)
      ObjectInspectorUtils.copyToStandardObject(arguments[0].get(), listOI);

    if (inputs == null) {
      return null;
    }

    if (evaluator == null) {
      Text functionName = 
        (Text)ObjectInspectorUtils.copyToStandardObject(arguments[1].get(), stringOI);
  
      if (functionName == null) {
        throw new HiveException("Function name cannot be null.");
      }

      GenericUDAFResolver resolver =
        FunctionRegistry.getGenericUDAFResolver(functionName.toString());
      if (resolver == null) {
        throw new HiveException("Could not find function with name " + 
                                functionName.toString());
      }
      
      ObjectInspector[] objectInspectorArray = new ObjectInspector[1];
      objectInspectorArray[0] = elementOI;
     
      TypeInfo[] typeInfoArray = new TypeInfo[1];
      typeInfoArray[0] = 
        TypeInfoUtils.getTypeInfoFromObjectInspector(elementOI);
      
      evaluator = resolver.getEvaluator(typeInfoArray);
      converter = ObjectInspectorConverters.getConverter(
        evaluator.init(GenericUDAFEvaluator.Mode.COMPLETE, objectInspectorArray),
        elementOI);
      buffer = evaluator.getNewAggregationBuffer();
    } 

    evaluator.reset(buffer);

    for (Object input : inputs) {
      inputArray[0] = input;
      evaluator.iterate(buffer, inputArray);
    }

    return converter.convert(evaluator.terminate(buffer));
  }