// Path: src/main/java/es/tid/fiware/iot/ac/xacml/Extractors.java
// public class Extractors {
// 
//     // XPath is not thread safe: <http://stackoverflow.com/a/3442674/1035380>
// 
//     private static XPathExpression decisionExp() {
//         return buildExp("//*[local-name()='Decision']/text()");
//     }
// 
//     private static XPathExpression sujectIdsExp() {
//         return buildExp("//*[@AttributeId='urn:oasis:names:tc:xacml:1.0:subject:subject-id']/*[local-name()='AttributeValue']");
//     }
// 
//     private static XPathExpression policyIdExp() {
//         return buildExp("//*[local-name()='Policy']/@PolicyId");
//     }
// 
//     private static XPathExpression policysetIdExp() {
//         return buildExp("//*[local-name()='PolicySet']/@PolicySetId");
//     }
// 
//     public static Collection<String> extractSubjectIds(String xacmlRequest)
//             throws XPathExpressionException, IOException, SAXException {
// 
//         Document xacml = Xml.toXml(xacmlRequest);
// 
//         NodeList nodes = (NodeList) sujectIdsExp().evaluate(xacml,
//                 XPathConstants.NODESET);
// 
//         List<String> subjects = new ArrayList<String>();
//         for (int i = 0; i < nodes.getLength(); i++) {
//             subjects.add(nodes.item(i).getTextContent());
//         }
// 
//         return subjects;
//     }
// 
//     public static String extractDecision(String xacmlRes)
//             throws XPathExpressionException, IOException, SAXException {
//         return decisionExp().evaluate(Xml.toXml(xacmlRes));
//     }
// 
//     public static String extractPolicyId(String xacmlPolicy)
//             throws XPathExpressionException, IOException, SAXException {
//         return policyIdExp().evaluate(Xml.toXml(xacmlPolicy));
//     }
// 
//     public static String extractPolicySetId(String xacmlPolicySet)
//             throws XPathExpressionException, IOException, SAXException {
//         return policysetIdExp().evaluate(Xml.toXml(xacmlPolicySet));
//     }
// 
//     private static XPathExpression buildExp(String exp) {
//         try {
//             return XPathFactory.newInstance().newXPath().compile(exp);
//         } catch (XPathExpressionException e) {
//             throw new RuntimeException(e);
//         }
//     }
// 
// }


import com.codahale.metrics.annotation.Timed;
import es.tid.fiware.iot.ac.rs.Tenant;
import es.tid.fiware.iot.ac.rs.Correlator;
import es.tid.fiware.iot.ac.xacml.Extractors;
import io.dropwizard.hibernate.UnitOfWork;
import java.io.IOException;
import org.hibernate.CacheMode;
import org.hibernate.FlushMode;
import org.wso2.balana.PDP;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.HashSet;
import java.util.Set;
import java.util.ArrayList;
import java.util.List;
import javax.xml.xpath.XPathExpressionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.SAXException;
                evaluation = pdp.evaluate(xacmlRequest);
                String response = extractDecision(evaluation);
                LOGGER.debug("XACML partial evaluation for Role {} is {}",
                             subjectId, response);
                if (response.equals("Permit")){
                    LOGGER.debug("XACML partial evaluation match for {}", subjectId);
                    LOGGER.debug("Skipping other subjects");
                    break;
                }
            }
        } else {
            PDP pdp = pdpFactory.get(tenant, extractSubjectIds(xacmlRequest));
            evaluation = pdp.evaluate(xacmlRequest);
            LOGGER.trace("XACML evaluation: {}", evaluation);
        }
        return Response.ok(evaluation).build();
    }

    private Set<String> extractSubjectIds(String xacmlRequest)
            throws WebApplicationException {
        try {
            return new HashSet(Extractors.extractSubjectIds(xacmlRequest));
        } catch (XPathExpressionException | IOException | SAXException e) {
            throw new WebApplicationException(400);
        }
    }

    private String extractDecision(String evaluation)
        throws WebApplicationException {
        try {
// Path: src/main/java/es/tid/fiware/iot/ac/xacml/Extractors.java
// public class Extractors {
// 
//     // XPath is not thread safe: <http://stackoverflow.com/a/3442674/1035380>
// 
//     private static XPathExpression decisionExp() {
//         return buildExp("//*[local-name()='Decision']/text()");
//     }
// 
//     private static XPathExpression sujectIdsExp() {
//         return buildExp("//*[@AttributeId='urn:oasis:names:tc:xacml:1.0:subject:subject-id']/*[local-name()='AttributeValue']");
//     }
// 
//     private static XPathExpression policyIdExp() {
//         return buildExp("//*[local-name()='Policy']/@PolicyId");
//     }
// 
//     private static XPathExpression policysetIdExp() {
//         return buildExp("//*[local-name()='PolicySet']/@PolicySetId");
//     }
// 
//     public static Collection<String> extractSubjectIds(String xacmlRequest)
//             throws XPathExpressionException, IOException, SAXException {
// 
//         Document xacml = Xml.toXml(xacmlRequest);
// 
//         NodeList nodes = (NodeList) sujectIdsExp().evaluate(xacml,
//                 XPathConstants.NODESET);
// 
//         List<String> subjects = new ArrayList<String>();
//         for (int i = 0; i < nodes.getLength(); i++) {
//             subjects.add(nodes.item(i).getTextContent());
//         }
// 
//         return subjects;
//     }
// 
//     public static String extractDecision(String xacmlRes)
//             throws XPathExpressionException, IOException, SAXException {
//         return decisionExp().evaluate(Xml.toXml(xacmlRes));
//     }
// 
//     public static String extractPolicyId(String xacmlPolicy)
//             throws XPathExpressionException, IOException, SAXException {
//         return policyIdExp().evaluate(Xml.toXml(xacmlPolicy));
//     }
// 
//     public static String extractPolicySetId(String xacmlPolicySet)
//             throws XPathExpressionException, IOException, SAXException {
//         return policysetIdExp().evaluate(Xml.toXml(xacmlPolicySet));
//     }
// 
//     private static XPathExpression buildExp(String exp) {
//         try {
//             return XPathFactory.newInstance().newXPath().compile(exp);
//         } catch (XPathExpressionException e) {
//             throw new RuntimeException(e);
//         }
//     }
// 
// }


// Path: src/main/java/es/tid/fiware/iot/ac/pdp/PdpEndpoint.java
import com.codahale.metrics.annotation.Timed;
import es.tid.fiware.iot.ac.rs.Tenant;
import es.tid.fiware.iot.ac.rs.Correlator;
import es.tid.fiware.iot.ac.xacml.Extractors;
import io.dropwizard.hibernate.UnitOfWork;
import java.io.IOException;
import org.hibernate.CacheMode;
import org.hibernate.FlushMode;
import org.wso2.balana.PDP;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.HashSet;
import java.util.Set;
import java.util.ArrayList;
import java.util.List;
import javax.xml.xpath.XPathExpressionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.SAXException;

                evaluation = pdp.evaluate(xacmlRequest);
                String response = extractDecision(evaluation);
                LOGGER.debug("XACML partial evaluation for Role {} is {}",
                             subjectId, response);
                if (response.equals("Permit")){
                    LOGGER.debug("XACML partial evaluation match for {}", subjectId);
                    LOGGER.debug("Skipping other subjects");
                    break;
                }
            }
        } else {
            PDP pdp = pdpFactory.get(tenant, extractSubjectIds(xacmlRequest));
            evaluation = pdp.evaluate(xacmlRequest);
            LOGGER.trace("XACML evaluation: {}", evaluation);
        }
        return Response.ok(evaluation).build();
    }

    private Set<String> extractSubjectIds(String xacmlRequest)
            throws WebApplicationException {
        try {
            return new HashSet(Extractors.extractSubjectIds(xacmlRequest));
        } catch (XPathExpressionException | IOException | SAXException e) {
            throw new WebApplicationException(400);
        }
    }

    private String extractDecision(String evaluation)
        throws WebApplicationException {
        try {
            String response = Extractors.extractDecision(evaluation);