public MatchResult match(EvaluationCtx context) {
        // start by evaluating the AD/AS
        EvaluationResult result = eval.evaluate(context);
        
        if (result.indeterminate()) {
            // in this case, we don't ask the function for anything, and we
            // simply return INDETERMINATE
            return new MatchResult(MatchResult.INDETERMINATE,
                                   result.getStatus());
        }

        // an AD/AS will always return a bag
        BagAttribute bag = (BagAttribute)(result.getAttributeValue());

        if (! bag.isEmpty()) {
            // we got back a set of attributes, so we need to iterate through
            // them, seeing if at least one matches
            Iterator it = bag.iterator();
            boolean atLeastOneError = false;
            Status firstIndeterminateStatus = null;

            while (it.hasNext()) {
                ArrayList inputs = new ArrayList();

                inputs.add(attrValue);
                inputs.add(it.next());

                // do the evaluation
                MatchResult match = evaluateMatch(inputs, context);
                
                // we only need one match for this whole thing to match
                if (match.getResult() == MatchResult.MATCH)
                    return match;

                // if it was INDETERMINATE, we want to remember for later
                if (match.getResult() == MatchResult.INDETERMINATE) {
                    atLeastOneError = true;

                    // there are no rules about exactly what status data
                    // should be returned here, so like in the combining
                    // algs, we'll just track the first error
                    if (firstIndeterminateStatus == null)
                        firstIndeterminateStatus = match.getStatus();
                }
            }

            // if we got here, then nothing matched, so we'll either return
            // INDETERMINATE or NO_MATCH
            if (atLeastOneError)
                return new MatchResult(MatchResult.INDETERMINATE,
                                       firstIndeterminateStatus);
            else
                return new MatchResult(MatchResult.NO_MATCH);

        } else {
            // this is just an optimization, since the loop above will
            // actually handle this case, but this is just a little
            // quicker way to handle an empty bag
            return new MatchResult(MatchResult.NO_MATCH);
        }
    }