public EvaluationResult evaluate(List inputs, EvaluationCtx context) {

        // Evaluate the arguments
        AttributeValue [] argValues = new AttributeValue[inputs.size()];
        EvaluationResult result = evalArgs(inputs, context, argValues);
        if (result != null)
            return result;

        // Now that we have real values, perform the requested operation.
        AttributeValue attrResult = null;

        switch (getFunctionId()) {
            
            // *-one-and-only takes a single bag and returns a
            // single value of baseType
        case ID_BASE_ONE_AND_ONLY: {
            BagAttribute bag = (BagAttribute)(argValues[0]);

            if (bag.size() != 1)
                return makeProcessingError(getFunctionName() + " expects " +
                                           "a bag that contains a single " +
                                           "element, got a bag with " +
                                           bag.size() + " elements");

            attrResult = (AttributeValue)(bag.iterator().next());
            break;
        }

            // *-size takes a single bag and returns an integer
        case ID_BASE_BAG_SIZE: {
            BagAttribute bag = (BagAttribute)(argValues[0]);

            attrResult = new IntegerAttribute(bag.size());
            break;
        }

            // *-bag takes any number of elements of baseType and
            // returns a bag containing those elements
        case ID_BASE_BAG: {
            List argsList = Arrays.asList(argValues);

            attrResult = new BagAttribute(getReturnType(), argsList);
            break;
        }
        }

        return new EvaluationResult(attrResult);
    }