public Result combine(EvaluationCtx context, List parameters,
                          List policyElements) {
        boolean atLeastOnePermit = false;
        Set permitObligations = new HashSet();
        Iterator it = policyElements.iterator();

        while (it.hasNext()) {
            AbstractPolicy policy =
                ((PolicyCombinerElement)(it.next())).getPolicy();

            // make sure that the policy matches the context
            MatchResult match = policy.match(context);

            if (match.getResult() == MatchResult.INDETERMINATE)
                return new Result(Result.DECISION_DENY,
                                  context.getResourceId().encode());

            if (match.getResult() == MatchResult.MATCH) {
                // evaluate the policy
                Result result = policy.evaluate(context);
                int effect = result.getDecision();
                
                // unlike in the RuleCombining version of this alg, we always
                // return DENY if any Policy returns DENY or INDETERMINATE
                if ((effect == Result.DECISION_DENY) ||
                    (effect == Result.DECISION_INDETERMINATE))
                    return new Result(Result.DECISION_DENY,
                                      context.getResourceId().encode(),
                                      result.getObligations());
                
                // remember if at least one Policy said PERMIT
                if (effect == Result.DECISION_PERMIT) {
                    atLeastOnePermit = true;
                    permitObligations.addAll(result.getObligations());
                }
            }
        }
        
        // if we got a PERMIT, return it, otherwise it's NOT_APPLICABLE
        if (atLeastOnePermit)
            return new Result(Result.DECISION_PERMIT,
                              context.getResourceId().encode(),
                              permitObligations);
        else
            return new Result(Result.DECISION_NOT_APPLICABLE,
                              context.getResourceId().encode());
    }