http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/TestBase.java
----------------------------------------------------------------------
diff --git 
a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/TestBase.java
 
b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/TestBase.java
new file mode 100755
index 0000000..4a105c2
--- /dev/null
+++ 
b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/TestBase.java
@@ -0,0 +1,1074 @@
+/*
+ *                        AT&T - PROPRIETARY
+ *          THIS FILE CONTAINS PROPRIETARY INFORMATION OF
+ *        AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN
+ *             ACCORDANCE WITH APPLICABLE AGREEMENTS.
+ *
+ *          Copyright (c) 2014 AT&T Knowledge Ventures
+ *              Unpublished and Not for Publication
+ *                     All Rights Reserved
+ */
+package com.att.research.xacmlatt.pdp.test;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.GnuParser;
+import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.http.entity.ContentType;
+
+import com.att.research.xacml.api.AttributeValue;
+import com.att.research.xacml.api.DataType;
+import com.att.research.xacml.api.DataTypeException;
+import com.att.research.xacml.api.DataTypeFactory;
+import com.att.research.xacml.api.Decision;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.Request;
+import com.att.research.xacml.api.RequestAttributes;
+import com.att.research.xacml.api.Response;
+import com.att.research.xacml.api.Result;
+import com.att.research.xacml.api.pdp.PDPEngine;
+import com.att.research.xacml.api.pdp.PDPEngineFactory;
+import com.att.research.xacml.api.pdp.PDPException;
+import com.att.research.xacml.api.pep.PEPException;
+import com.att.research.xacml.std.IdentifierImpl;
+import com.att.research.xacml.std.StdAttributeValue;
+import com.att.research.xacml.std.StdMutableAttribute;
+import com.att.research.xacml.std.StdMutableRequest;
+import com.att.research.xacml.std.StdMutableRequestAttributes;
+import com.att.research.xacml.std.dom.DOMRequest;
+import com.att.research.xacml.std.dom.DOMResponse;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.json.JSONRequest;
+import com.att.research.xacml.std.json.JSONResponse;
+import com.att.research.xacml.std.json.JSONStructureException;
+import com.att.research.xacml.util.FactoryException;
+import com.att.research.xacml.util.XACMLProperties;
+import com.google.common.base.Splitter;
+import com.google.common.collect.Lists;
+
+/**
+ * This is a base class for setting up a test environment. Using properties 
files, it contains the
+ * necessary information for 
+ * 1. defining and providing attributes
+ * 2. defining and instantiating the PDP engine
+ * 3. creating PEP requests and calling the PDP engine
+ * 
+ * @author pameladragosh
+ *
+ */
+public class TestBase extends SimpleFileVisitor<Path> {
+       private static final Log logger = LogFactory.getLog(TestBase.class);
+       
+       public class HelpException extends Exception {
+               private static final long serialVersionUID = 1L;
+               
+       }
+       
+       /**
+        * This private class holds information for properties defined for 
attribute
+        * generation. The user can configure the properties file such that 
attributes
+        * can be automatically generated and added into each request.
+        * 
+        * @author pameladragosh
+        *
+        */
+       class Generator {
+               Path file;
+               InputStream is;
+               BufferedReader reader;
+               List<StdMutableAttribute> attributes = new 
ArrayList<StdMutableAttribute>();
+               
+               public Generator(Path path) {
+                       this.file = path;
+               }
+
+               /**
+                * read - reads in the next line of data
+                * 
+                * @return      String - a line from the csv containing 
attribute data
+                */
+               public String   read() {
+                       String str = null;
+                       if (is == null) {
+                               try {
+                                       is = Files.newInputStream(file);
+                               } catch (IOException e) {
+                                       logger.error(e);
+                                       return null;
+                               }
+                       }
+                       if (reader == null) {
+                               reader = new BufferedReader(new 
InputStreamReader(this.is));
+                       }
+                       try {
+                               str = reader.readLine();
+                               if (str == null) {
+                                       //
+                                       // No more strings, close up
+                                       //
+                                       this.close();
+                               }
+                               if (logger.isDebugEnabled()) {
+                                       logger.debug(str);
+                               }
+                       } catch (IOException e) {
+                               logger.error(e);
+                       }
+                       return str;
+               }
+               
+               public void     close() {
+                       if (this.reader != null) {
+                               try {
+                                       this.reader.close();
+                               } catch (IOException idontcare) {
+                               } finally {
+                                       this.reader = null;
+                                       this.is = null;
+                               }
+                       }
+               }
+               
+       }
+       
+       public static final String PROP_GENERATOR = "xacml.attribute.generator";
+       
+       public static final String OPTION_HELP = "help";
+       public static final String OPTION_TESTDIR = "dir";
+       public static final String OPTION_TESTREST = "rest";
+       public static final String OPTION_TESTURL = "url";
+       public static final String OPTION_TESTOUTPUT = "output";
+       public static final String OPTION_LOOP = "loop";
+       public static final String OPTION_TESTNUMBERS = "testNumbers";
+
+       public static final String DEFAULT_RESTURL = 
"https://localhost:8443/pdp/";;
+       
+       public static Options options = new Options();
+       static {
+               options.addOption(new Option(OPTION_HELP, false, "Prints 
help."));
+               options.addOption(new Option(OPTION_TESTDIR, true, "Directory 
path where all the test properties and data are located."));
+               options.addOption(new Option(OPTION_TESTREST, false, "Test 
against RESTful PDP."));
+               options.addOption(new Option(OPTION_TESTURL, true, "URL to the 
RESTful PDP. Default is " + DEFAULT_RESTURL));
+               options.addOption(new Option(OPTION_TESTOUTPUT, true, "Specify 
a different location for dumping responses."));
+               options.addOption(new Option(OPTION_LOOP, true, "Number of 
times to loop through the tests. Default is 1. A value of -1 runs 
indefinitely."));
+               options.addOption(new Option(OPTION_TESTNUMBERS, true, 
"Comma-separated list of numbers found in the names of the test files to be 
run.  Numbers must exactly match the file name, e.g. '02'.  Used to limit 
testing to specific set of tests."));
+       }
+       
+       protected String directory = null;
+       protected Path output = null;
+       protected boolean isREST;
+       protected URL restURL = null;
+       protected int loop = 1;
+       protected PDPEngine engine = null;
+       protected List<Generator> generators = new ArrayList<Generator>();
+       protected static DataTypeFactory dataTypeFactory                = null;
+       
+       private long    permits = 0;
+       private long    denies = 0;
+       private long    notapplicables = 0;
+       private long    indeterminates = 0;
+       
+       private long    expectedPermits = 0;
+       private long    expectedDenies = 0;
+       private long    expectedNotApplicables = 0;
+       private long    expectedIndeterminates = 0;
+       
+       private long    generatedpermits = 0;
+       private long    generateddenies = 0;
+       private long    generatednotapplicables = 0;
+       private long    generatedindeterminates = 0;
+       
+       private long    responseMatches = 0;
+       private long    responseNotMatches = 0;
+       
+       private String[]        testNumbersArray = null;
+       
+       protected final Pattern pattern = 
Pattern.compile("Request[.]\\d+[.](Permit|Deny|NA|Indeterminate|Generate|Unknown)\\.(json|xml)");
+       
+       public static boolean isJSON(Path file) {
+               return file.toString().endsWith(".json");
+       }
+       
+       public static boolean isXML(Path file) {
+               return file.toString().endsWith(".xml");
+       }
+       
+       public TestBase(String[] args) throws ParseException, 
MalformedURLException, HelpException {
+               //
+               // Finish Initialization
+               //
+               this.restURL = new URL(DEFAULT_RESTURL);
+               //
+               // Parse arguments
+               //
+               this.parseCommands(args);
+       }
+       
+       /**
+        * Parse in the command line arguments that the following parameters:
+        * 
+        * @param args - command line arguments
+        * @throws org.apache.commons.cli.ParseException
+        * @throws java.net.MalformedURLException
+        * @throws com.att.research.xacmlatt.pdp.test.TestBase.HelpException
+        */
+       protected void parseCommands(String[] args) throws ParseException, 
MalformedURLException, HelpException {
+               //
+               // Parse the command line options
+               //
+               CommandLine cl;
+               cl = new GnuParser().parse(options, args);
+               //
+               // Check for what we have
+               //
+               if (cl.hasOption(OPTION_HELP)) {
+               new HelpFormatter().printHelp("Usage: -dir testdirectory 
OPTIONS",
+                               options);
+               throw new HelpException();
+               }
+               if (cl.hasOption(OPTION_TESTDIR)) {
+                       this.directory = cl.getOptionValue(OPTION_TESTDIR);
+               } else {
+                       throw new IllegalArgumentException("You must specify a 
test directory. -dir path/to/some/where");
+               }
+               if (cl.hasOption(OPTION_TESTREST)) {
+                       this.isREST = true;
+               } else {
+                       this.isREST = false;
+               }
+               if (cl.hasOption(OPTION_TESTURL)) {
+                       this.restURL = new 
URL(cl.getOptionValue(OPTION_TESTURL));
+               }
+               if (cl.hasOption(OPTION_TESTOUTPUT)) {
+                       this.output = 
Paths.get(cl.getOptionValue(OPTION_TESTOUTPUT));
+               } else {
+                       this.output = Paths.get(this.directory, "results");
+               }
+               if (cl.hasOption(OPTION_LOOP)) {
+                       this.loop = 
Integer.parseInt(cl.getOptionValue(OPTION_LOOP));
+               }
+               if (cl.hasOption(OPTION_TESTNUMBERS)) {
+                       String testNumberString = 
cl.getOptionValue(OPTION_TESTNUMBERS);
+                       testNumbersArray = testNumberString.split(",");
+                       //
+                       // reset strings to include dots so they exactly match 
pattern in file name
+                       //
+                       for (int i = 0; i < testNumbersArray.length; i++) {
+                               testNumbersArray[i] = "." + testNumbersArray[i] 
+ ".";
+                       }
+               }
+       }
+       
+       /**
+        * Using the command line options that were parsed, configures our test 
instance.
+        * 
+        * @throws com.att.research.xacml.util.FactoryException
+        */
+       protected void configure() throws FactoryException {
+               //
+               // Setup the xacml.properties file
+               //
+               if (this.directory == null) {
+                       throw new IllegalArgumentException("Must supply a path 
to a test directory.");
+               }
+               Path pathDir = Paths.get(this.directory, "xacml.properties");
+               if (Files.notExists(pathDir)) {
+                       throw new IllegalArgumentException(pathDir.toString() + 
" does not exist.");
+               }
+               //
+               // Set it as the System variable so the XACML factories know 
where the properties are
+               // loaded from.
+               //
+               System.setProperty(XACMLProperties.XACML_PROPERTIES_NAME, 
pathDir.toString());
+               //
+               // Now we can create the data type factory
+               //
+               dataTypeFactory = DataTypeFactory.newInstance();
+               //
+               // Load in what generators we are to create
+               //
+               String generators = XACMLProperties.getProperty(PROP_GENERATOR);
+               if (generators != null) {
+                       //
+                       // Parse the generators
+                       //
+                       for (String generator : 
Splitter.on(',').trimResults().omitEmptyStrings().split(generators)) {
+                               this.configureGenerator(generator);
+                       }
+               }
+               //
+               // If we are embedded, create our engine
+               //
+               if (this.isREST == false) {
+                       PDPEngineFactory factory = 
PDPEngineFactory.newInstance();
+                       this.engine = factory.newEngine();
+               }
+               //
+               // Remove all the responses from the results directory
+               //
+               this.removeResults();
+       }
+       
+       /**
+        * Removes all the Response* files from the results directory.
+        * 
+        */
+       public void     removeResults() {
+               try {
+                       //
+                       // Determine where the results are supposed to be 
written to
+                       //
+                       Path resultsPath;
+                       if (this.output != null) {
+                               resultsPath = this.output;
+                       } else {
+                               resultsPath = 
Paths.get(this.directory.toString(), "results");
+                       }
+                       //
+                       // Walk the files
+                       //
+                       Files.walkFileTree(resultsPath, new 
SimpleFileVisitor<Path>() {
+
+                               @Override
+                               public FileVisitResult visitFile(Path file, 
BasicFileAttributes attrs) throws IOException {
+                                       if 
(file.getFileName().toString().startsWith("Response")) {
+                                               Files.delete(file);
+                                       }
+                                       return super.visitFile(file, attrs);
+                               }                               
+                       });
+               } catch (IOException e) {
+                       logger.error("Failed to removeRequests from " + 
this.directory + " " + e);
+               }
+       }
+       
+       /**
+        * Configure's a specific generator instance from the properties file.
+        * 
+        * @param generator
+        */
+       protected void configureGenerator(String generator) {
+               String prefix = PROP_GENERATOR + "." + generator;
+               String file = XACMLProperties.getProperty(prefix + ".file");
+               //
+               // Create a generator object
+               //
+               Generator gen = new Generator(Paths.get(this.directory, file));
+               this.generators.add(gen);
+               //
+               // Grab attributes
+               //
+               String attributes = XACMLProperties.getProperty(prefix + 
".attributes");
+               for (String attribute : 
Splitter.on(',').trimResults().omitEmptyStrings().split(attributes)) {
+                       String attributePrefix = prefix + ".attributes." + 
attribute;
+                       //
+                       // Create an attribute value. It is simply a 
placeholder for the field within
+                       // the CSV that contains the actual attribute value. It 
mainly holds the data type
+                       //
+                       Identifier datatype = new 
IdentifierImpl(XACMLProperties.getProperty(attributePrefix + ".datatype"));
+                       Integer field = 
Integer.parseInt(XACMLProperties.getProperty(attributePrefix + ".field"));
+                       StdAttributeValue<?> value = new 
StdAttributeValue<>(datatype, field);
+                       //
+                       // Get the rest of the attribute properties
+                       //
+                       Identifier category = new 
IdentifierImpl(XACMLProperties.getProperty(attributePrefix + ".category"));
+                       Identifier id = new 
IdentifierImpl(XACMLProperties.getProperty(attributePrefix + ".id"));
+                       String issuer = 
XACMLProperties.getProperty(attributePrefix + ".issuer");
+                       boolean include = 
Boolean.parseBoolean(XACMLProperties.getProperty(attributePrefix + ".include", 
"false"));
+                       //
+                       // Now we have a skeleton attribute
+                       //
+                       gen.attributes.add(new StdMutableAttribute(category, 
id, value, issuer, include));
+               }
+       }
+       
+       /**
+        * This runs() the test instance. It first configure's itself and then 
walks the
+        * requests directory issue each request to the PDP engine.
+        * 
+        * @throws java.io.IOException
+        * @throws com.att.research.xacml.util.FactoryException
+        * 
+        */
+       public void run() throws IOException, FactoryException {
+               //
+               // Configure ourselves
+               //
+               this.configure();
+               //
+               // Loop and run
+               //
+               int runs = 1;
+               do {
+                       long lTimeStart = System.currentTimeMillis();
+                       logger.info("Run number: " + runs);
+                       //
+                       // Walk the request directory
+                       //
+                       Files.walkFileTree(Paths.get(this.directory.toString(), 
"requests"), this);
+                       long lTimeEnd = System.currentTimeMillis();
+                       logger.info("Run elapsed time: " + (lTimeEnd - 
lTimeStart) + "ms");
+                       //
+                       // Dump the stats
+                       //
+                       this.dumpStats();
+                       this.resetStats();
+                       //
+                       // Increment
+                       //
+                       runs++;
+               } while ((this.loop == -1 ? true : runs <= this.loop));
+       }
+       
+       @Override
+       public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) 
throws IOException {
+               //
+               // Sanity check the file name
+               //
+               Matcher matcher = 
this.pattern.matcher(file.getFileName().toString());
+               if (matcher.matches()) {
+                       //
+                       // if user has limited which files to use, check that 
here
+                       //
+                       if (testNumbersArray != null) {
+                               String fileNameString = 
file.getFileName().toString();
+                               boolean found = false;
+                               for (String numberString : testNumbersArray) {
+                                       if 
(fileNameString.contains(numberString)) {
+                                               found = true;
+                                               break;
+                                       }
+                               }
+                               if (found == false) {
+                                       //
+                                       // this test is not in the list to be 
run, so skip it
+                                       //
+                                       return super.visitFile(file, attrs);
+                               }
+                       }
+                       try {
+                               //
+                               // Pull what this request is supposed to be
+                               //
+                               String group = null;
+                               int count = matcher.groupCount();
+                               if (count >= 1) {
+                                       group = matcher.group(count-1);
+                               }
+                               //
+                               // Send it
+                               //
+                               this.sendRequest(file, group);
+                       } catch (Exception e) {
+                               logger.error(e);
+                               e.printStackTrace();
+                       }
+               }
+               return super.visitFile(file, attrs);
+       }
+       
+       /**
+        * When a request file is encountered, this method is called send the 
request to the PDP engine. It will also dump
+        * the response object. If the group equals "Generate", then it will 
loop and send the request with generated attributes
+        * until that list is empty.
+        * 
+        * @param file - Request file. Eg. Request-01-Permit.json
+        * @param group - This is the parsed out string of the request file 
that defines if it is a Permit/Deny/Generate etc.
+        * @throws Exception
+        */
+       protected void sendRequest(Path file, String group) throws Exception {
+               logger.info(file.toString());
+               int requestCount = 0;
+               do {
+                       //
+                       // Generate the request
+                       //
+                       Request request = this.generateRequest(file, group);
+                       //
+                       // Was something generated?
+                       //
+                       if (request == null) {
+                               //
+                               // Get out of the loop
+                               //
+                               logger.info("NULL request generated.");
+                               break;
+                       }
+                       logger.info(request);
+                       //
+                       // Call the PDP
+                       //
+                       Response response = this.callPDP(request);
+                       //
+                       // Process the response
+                       //
+                       this.processResponse(file, request, response, group, 
requestCount);
+                       //
+                       // Is this a generated request?
+                       //
+                       if (group.equals("Generate")) {
+                               //
+                               // Yes, increment counter and move
+                               // on to the next generated request.
+                               //
+                               requestCount++;
+                       } else {
+                               //
+                               // Nope, exit the loop
+                               //
+                               break;
+                       }
+               } while (group.equals("Generate"));
+       }
+       
+       /**
+        * Sends the request object to the PDP engine. Either the embedded 
engine or the RESTful engine.
+        * 
+        * @param request - XACML request object
+        * @return Response - returns the XACML response object
+        */
+       protected Response callPDP(Request request) {
+               //
+               // Send it to the PDP
+               //
+               Response response = null;
+               if (this.isREST) {
+                       try {
+                               String jsonString = 
JSONRequest.toString(request, false);
+                               //
+                               // Call RESTful PDP
+                               //
+                               response = this.callRESTfulPDP(new 
ByteArrayInputStream(jsonString.getBytes()));
+                       } catch (Exception e) {
+                               logger.error("Error in sending RESTful request: 
" + e, e);
+                       }
+               } else {
+                       //
+                       // Embedded call to PDP
+                       //
+                       long lTimeStart = System.currentTimeMillis();
+                       try {
+                               response = this.engine.decide(request);
+                       } catch (PDPException e) {
+                               logger.error(e);
+                       }
+                       long lTimeEnd = System.currentTimeMillis();
+                       logger.info("Elapsed Time: " + (lTimeEnd - lTimeStart) 
+ "ms");
+               }
+               return response;
+       }
+       
+       /**
+        * Reads the request file into a Request object based on its type.
+        * 
+        * If the request has "Generate" in its filename, then this function 
will add
+        * generated attributes into the request.
+        * 
+        * @param file - Request file. Eg. Request-01-Permit.json
+        * @param group - This is the parsed out string of the request file 
that defines if it is a Permit/Deny/Generate etc.
+        * @return
+        * @throws com.att.research.xacml.std.json.JSONStructureException
+        * @throws com.att.research.xacml.std.dom.DOMStructureException
+        * @throws com.att.research.xacml.api.pep.PEPException
+        */
+       protected Request generateRequest(Path file, String group) throws 
JSONStructureException, DOMStructureException, PEPException {
+               //
+               // Convert to a XACML Request Object
+               //
+               Request request = null;
+               if (TestBase.isJSON(file)) {
+                       request = JSONRequest.load(file.toFile());
+               } else if (TestBase.isXML(file)) {
+                       request = DOMRequest.load(file.toFile());
+               }
+               if (request == null) {
+                       throw new PEPException("Invalid Request File: " + 
file.toString());
+               }
+               //
+               // Only if this request has "Generate"
+               // Request.XX.Generate.[json|xml]
+               //
+               if (group.equals("Generate")) {
+                       //
+                       // Add attributes to it
+                       //
+                       request = this.onNextRequest(request);
+               }
+               //
+               // Done
+               //
+               return request;
+       }
+
+       /**
+        * Called to add in generated attributes into the request.
+        * 
+        * @param request
+        * @return
+        */
+       protected Request onNextRequest(Request request) {
+               //
+               // If we have no generators, just return
+               //
+               if (this.generators.isEmpty()) {
+                       return request;
+               }
+               //
+               // Copy the request attributes
+               //
+               List<StdMutableRequestAttributes> attributes = new 
ArrayList<StdMutableRequestAttributes>();
+               for (RequestAttributes a : request.getRequestAttributes()) {
+                       attributes.add(new StdMutableRequestAttributes(a));
+               }
+               //
+               // Iterate the generators
+               //
+               for (Generator generator : this.generators) {
+                       //
+                       // Read a row in
+                       //
+                       String line = generator.read();
+                       //
+                       // Was something read?
+                       //
+                       if (line == null) {
+                               //
+                               // No more rows to read, return null
+                               //
+                               return null;
+                       }
+                       //
+                       // Split the line
+                       //
+                       List<String> fields = 
Lists.newArrayList(Splitter.on(',').trimResults().split(line));
+                       //
+                       // Now work on the attributes
+                       //
+                       for (StdMutableAttribute attribute : 
generator.attributes) {
+                               //
+                               // Grab the attribute holder, which holds the 
datatype and field. There should
+                               // be only ONE object in the collection.
+                               //
+                               AttributeValue<?> value = 
attribute.getValues().iterator().next();
+                               Integer field = (Integer) value.getValue();
+                               //
+                               // Is the field number valid?
+                               //
+                               if (field >= fields.size()) {
+                                       logger.error("Not enough fields: " + 
field + "(" + fields.size() + ")");
+                                       return null;
+                               }
+                               //
+                               // Determine what datatype it is
+                               //
+                               DataType<?> dataTypeExtended    = 
dataTypeFactory.getDataType(value.getDataTypeId());
+                               if (dataTypeExtended == null) {
+                                       logger.error("Failed to determine 
datatype");
+                                       return null;
+                               }
+                               //
+                               // Create the attribute value
+                               //
+                               try {
+                                       AttributeValue<?> attributeValue = 
dataTypeExtended.createAttributeValue(fields.get(field));                       
             
+                                       //
+                                       // Create the attribute
+                                       //
+                                       StdMutableAttribute newAttribute = new 
StdMutableAttribute(attribute.getCategory(),
+                                                                               
                                                                                
attribute.getAttributeId(),
+                                                                               
                                                                                
attributeValue,
+                                                                               
                                                                                
attribute.getIssuer(),
+                                                                               
                                                                                
attribute.getIncludeInResults());
+                                       boolean added = false;
+                                       for (StdMutableRequestAttributes a : 
attributes) {
+                                               //
+                                               // Does the category exist?
+                                               //
+                                               if 
(a.getCategory().equals(attribute.getCategory())) {
+                                                       //
+                                                       // Yes - add in the new 
attribute value
+                                                       //
+                                                       a.add(newAttribute);
+                                                       added = true;
+                                                       break;
+                                               }
+                                       }
+                                       if (added == false) {
+                                               //
+                                               // New category - create it and 
add it in
+                                               //
+                                               StdMutableRequestAttributes a = 
new StdMutableRequestAttributes(); 
+                                               
a.setCategory(newAttribute.getCategory());
+                                               a.add(newAttribute);
+                                               attributes.add(a);
+                                       }
+                               } catch (DataTypeException e) {
+                                       logger.error(e);
+                                       return null;
+                               }
+                       }
+               }
+               //
+               // Now form our final request
+               //
+               StdMutableRequest newRequest = new StdMutableRequest();
+               newRequest.setCombinedDecision(request.getCombinedDecision());
+               newRequest.setRequestDefaults(request.getRequestDefaults());
+               
newRequest.setReturnPolicyIdList(request.getReturnPolicyIdList());
+               newRequest.setStatus(request.getStatus());
+               for (StdMutableRequestAttributes a : attributes) {
+                       newRequest.add(a);
+               }
+               return newRequest;
+       }
+
+       /**
+        * This makes an HTTP POST call to a running PDP RESTful servlet to get 
a decision.
+        * 
+        * @param file
+        * @return
+        */
+       protected Response callRESTfulPDP(InputStream is) {
+               Response response = null;
+               HttpURLConnection connection = null;
+               try {
+
+                       //
+                       // Open up the connection
+                       //
+                       connection = (HttpURLConnection) 
this.restURL.openConnection();
+                       connection.setRequestProperty("Content-Type", 
"application/json");
+                       //
+                       // Setup our method and headers
+                       //
+            connection.setRequestMethod("POST");
+            connection.setUseCaches(false);
+            //
+            // Adding this in. It seems the HttpUrlConnection class does NOT
+            // properly forward our headers for POST re-direction. It does so
+            // for a GET re-direction.
+            //
+            // So we need to handle this ourselves.
+            //
+            connection.setInstanceFollowRedirects(false);
+                       connection.setDoOutput(true);
+                       connection.setDoInput(true);
+                       //
+                       // Send the request
+                       //
+                       try (OutputStream os = connection.getOutputStream()) {
+                               IOUtils.copy(is, os);
+                       }
+            //
+            // Do the connect
+            //
+            connection.connect();
+            if (connection.getResponseCode() == 200) {
+               //
+               // Read the response
+               //
+                       ContentType contentType = null;
+                       try {
+                               contentType = 
ContentType.parse(connection.getContentType());
+                               
+                               if 
(contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_JSON.getMimeType()))
 {
+                               response = 
JSONResponse.load(connection.getInputStream());
+                               } else if 
(contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_XML.getMimeType())
 ||
+                                               
contentType.getMimeType().equalsIgnoreCase("application/xacml+xml") ) {
+                               response = 
DOMResponse.load(connection.getInputStream());
+                               } else {
+                               logger.error("unknown content-type: " + 
contentType);
+                       }
+
+                } catch (Exception e) {
+                               String message = "Parsing Content-Type: " + 
connection.getContentType() + ", error=" + e.getMessage();
+                               logger.error(message, e);
+                       }
+
+            } else {
+               logger.error(connection.getResponseCode() + " " + 
connection.getResponseMessage());
+            }
+               } catch (Exception e) {
+                       logger.error(e);
+               }
+               
+               return response;
+       }
+       
+       /**
+        * This processes a response. Saves the response out to disk. If there 
is a corresponding response file for the request located
+        * in the "responses" sub-directory, then this method will compare that 
response file with what the engine returned to see if it
+        * matched.
+        * 
+        * @param requestFile
+        * @param request
+        * @param response
+        * @param group
+        * @param count
+        * @throws Exception
+        */
+       protected void processResponse(Path requestFile, Request request, 
Response response, String group, int count) throws Exception {
+               //
+               // Construct the output filename
+               //
+               Path responseFile = null;
+               Path resultFile = null;
+               int num = requestFile.getNameCount();
+               if (num < 2) {
+                       logger.error("Too few dir's in request filename.");
+                       throw new Exception("Too few dir's in request filename. 
Format should be Request.[0-9]+.{Permit|Deny|NA|Indeterminate}.{json|xml}");
+               }
+               String filename = requestFile.getFileName().toString();
+               if (group.equals("Generate")) {
+                       //
+                       // Using count variable, construct a filename
+                       //
+                       //              i.e. Response.03.Generate.{count}.json
+                       //
+                       filename = "Response" + 
filename.substring(filename.indexOf('.'), filename.lastIndexOf('.')) + 
String.format("%03d", count) + filename.substring(filename.lastIndexOf('.'));
+               } else {
+                       //
+                       // Construct filename
+                       //
+                       filename = "Response" + 
filename.substring(filename.indexOf('.'));
+               }
+               //
+               // Determine equivalent response file path
+               //
+               responseFile = Paths.get(requestFile.subpath(0, num - 
2).toString(), "responses");
+               if (Files.notExists(responseFile)) {
+                       //
+                       // Create it
+                       //
+                       logger.warn(responseFile.toString() + " does NOT exist, 
creating...");
+                       try {
+                               Files.createDirectories(responseFile);
+                       } catch (IOException e) {
+                               logger.error(e);
+                               throw new Exception("Cannot proceed without an 
output directory.");
+                       }
+               }
+               responseFile = Paths.get(responseFile.toString(), filename);
+               //
+               // Determine path to write result file
+               //
+               if (this.output != null) {
+                       //
+                       // User specified an output path
+                       //
+                       resultFile = this.output;
+               } else {
+                       //
+                       // Default path
+                       //
+                       resultFile = Paths.get(requestFile.subpath(0, num - 
2).toString(), "results");
+               }
+               //
+               // Check if the path exists
+               //
+               if (Files.notExists(resultFile)) {
+                       //
+                       // Create it
+                       //
+                       logger.warn(resultFile.toString() + " does NOT exist, 
creating...");
+                       try {
+                               Files.createDirectories(resultFile);
+                       } catch (IOException e) {
+                               logger.error(e);
+                               throw new Exception("Cannot proceed without an 
output directory.");
+                       }
+               }
+               //
+               // Add the filename to the path
+               //
+               resultFile = Paths.get(resultFile.toString(), filename);
+               //
+               // Check if there is an equivalent response in the response
+               // directory. If so, compare our response result with that one.
+               //
+               boolean succeeded = true;
+               if (responseFile != null && Files.exists(responseFile)) {
+                       //
+                       // Do comparison
+                       //
+                       Response expectedResponse = null;
+                       if (TestBase.isJSON(responseFile)) {
+                               expectedResponse = 
JSONResponse.load(responseFile);
+                       } else if (TestBase.isXML(responseFile)) {
+                               expectedResponse = 
DOMResponse.load(responseFile);
+                       }
+                       if (expectedResponse != null) {
+                               //
+                               // Do the compare
+                               //
+                               if (response == null) {
+                                       logger.error("NULL response returned.");
+                                       this.responseNotMatches++;
+                                       succeeded = false;
+                               } else {
+                                       if (response.equals(expectedResponse)) {
+                                               logger.info("Response matches 
expected response.");
+                                               this.responseMatches++;
+                                       } else {
+                                               logger.error("Response does not 
match expected response.");
+                                               logger.error("Expected: ");
+                                               
logger.error(expectedResponse.toString());
+                                               this.responseNotMatches++;
+                                               succeeded = false;
+                                       }
+                               }
+                       }
+               }
+               //
+               // Write the response to the result file
+               //
+               logger.info("Request: " + requestFile.getFileName() + " 
response is: " + (response == null ? "null" : response.toString()));
+               if (resultFile != null && response != null) {
+                       if (TestBase.isJSON(resultFile)) {
+                               Files.write(resultFile, 
JSONResponse.toString(response, true).getBytes());
+                       } else if (TestBase.isXML(resultFile)) {
+                               Files.write(resultFile, 
DOMResponse.toString(response, true).getBytes());
+                       }
+               }
+               //
+               // Stats
+               //              
+               if (group.equals("Permit")) {
+                       this.expectedPermits++;
+               } else if (group.equals("Deny")) {
+                       this.expectedDenies++;
+               } else if (group.equals("NA")) {
+                       this.expectedNotApplicables++;
+               } else if (group.equals("Indeterminate")) {
+                       this.expectedIndeterminates++;
+               }
+               if (response != null) {
+                       for (Result result : response.getResults()) {
+                               Decision decision = result.getDecision();
+                               if (group.equals("Generate")) {
+                                       if (decision.equals(Decision.PERMIT)) {
+                                               this.generatedpermits++;
+                                       } else if 
(decision.equals(Decision.DENY)) {
+                                               this.generateddenies++;
+                                       } else if 
(decision.equals(Decision.NOTAPPLICABLE)) {
+                                               this.generatednotapplicables++;
+                                       } else if 
(decision.equals(Decision.INDETERMINATE)) {
+                                               this.generatedindeterminates++;
+                                       }
+                                       continue;
+                               }
+                               if (decision.equals(Decision.PERMIT)) {
+                                       this.permits++;
+                                       if (group.equals("Permit") == false) {
+                                               succeeded = false;
+                                               logger.error("Expected " + 
group + " got " + decision);
+                                       }
+                               } else if (decision.equals(Decision.DENY)) {
+                                       this.denies++;
+                                       if (group.equals("Deny") == false) {
+                                               succeeded = false;
+                                               logger.error("Expected " + 
group + " got " + decision);
+                                       }
+                               } else if 
(decision.equals(Decision.NOTAPPLICABLE)) {
+                                       this.notapplicables++;
+                                       if (group.equals("NA") == false) {
+                                               succeeded = false;
+                                               logger.error("Expected " + 
group + " got " + decision);
+                                       }
+                               } else if 
(decision.equals(Decision.INDETERMINATE)) {
+                                       this.indeterminates++;
+                                       if (group.equals("Indeterminate") == 
false) {
+                                               succeeded = false;
+                                               logger.error("Expected " + 
group + " got " + decision);
+                                       }
+                               }
+                       }
+               }
+               if (succeeded) {
+                       logger.info("REQUEST SUCCEEDED");
+               } else {
+                       logger.info("REQUEST FAILED");
+               }
+       }
+
+       protected void  dumpStats() {
+               StringBuilder dump = new StringBuilder();
+               dump.append(System.lineSeparator());
+               dump.append("Permits: " + this.permits + " Expected: " + 
this.expectedPermits);
+               dump.append(System.lineSeparator());
+               dump.append("Denies: " + this.denies + " Expected: " + 
this.expectedDenies);
+               dump.append(System.lineSeparator());
+               dump.append("NA: " + this.notapplicables + " Expected: " + 
this.expectedNotApplicables);
+               dump.append(System.lineSeparator());
+               dump.append("Indeterminates: " + this.indeterminates + " 
Expected: " + this.expectedIndeterminates);
+               dump.append(System.lineSeparator());
+               dump.append("Generated Permits: " + this.generatedpermits);
+               dump.append(System.lineSeparator());
+               dump.append("Generated Denies: " + this.generateddenies);
+               dump.append(System.lineSeparator());
+               dump.append("Generated NA: " + this.generatednotapplicables);
+               dump.append(System.lineSeparator());
+               dump.append("Generated Indeterminates: " + 
this.generatedindeterminates);
+               dump.append(System.lineSeparator());
+               dump.append("Responses Matched: " + this.responseMatches);
+               dump.append(System.lineSeparator());
+               dump.append("Responses NOT Matched: " + 
this.responseNotMatches);
+               
+               if (this.permits != this.expectedPermits ||
+                       this.denies != this.expectedDenies ||
+                       this.notapplicables != this.expectedNotApplicables ||
+                       this.indeterminates != this.expectedIndeterminates ||
+                       this.responseNotMatches > 0) {
+                       logger.fatal(dump.toString());
+               } else {
+                       logger.info(dump.toString());
+               }
+       }
+       
+       protected void  resetStats() {
+               this.permits = 0;
+               this.denies = 0;
+               this.notapplicables = 0;
+               this.indeterminates = 0;
+               this.generatedpermits = 0;
+               this.generateddenies = 0;
+               this.generatednotapplicables = 0;
+               this.generatedindeterminates = 0;
+               this.responseMatches = 0;
+               this.responseNotMatches = 0;
+       }
+
+       public static void main(String[] args) {
+               try {
+                       new TestBase(args).run();
+               } catch (ParseException | IOException | FactoryException e) {
+                       logger.error(e);
+               } catch (HelpException e) {
+               }               
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/annotations/TestAnnotation.java
----------------------------------------------------------------------
diff --git 
a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/annotations/TestAnnotation.java
 
b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/annotations/TestAnnotation.java
new file mode 100755
index 0000000..a1d679b
--- /dev/null
+++ 
b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/annotations/TestAnnotation.java
@@ -0,0 +1,232 @@
+/*
+ *                        AT&T - PROPRIETARY
+ *          THIS FILE CONTAINS PROPRIETARY INFORMATION OF
+ *        AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN
+ *             ACCORDANCE WITH APPLICABLE AGREEMENTS.
+ *
+ *          Copyright (c) 2014 AT&T Knowledge Ventures
+ *              Unpublished and Not for Publication
+ *                     All Rights Reserved
+ */
+package com.att.research.xacmlatt.pdp.test.annotations;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Date;
+import java.util.TimeZone;
+
+import org.apache.commons.cli.ParseException;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.att.research.xacml.api.DataTypeException;
+import com.att.research.xacml.api.Response;
+import com.att.research.xacml.std.annotations.RequestParser;
+import com.att.research.xacml.std.annotations.XACMLAction;
+import com.att.research.xacml.std.annotations.XACMLAttribute;
+import com.att.research.xacml.std.annotations.XACMLEnvironment;
+import com.att.research.xacml.std.annotations.XACMLMultiRequest;
+import com.att.research.xacml.std.annotations.XACMLRequest;
+import com.att.research.xacml.std.annotations.XACMLRequestReference;
+import com.att.research.xacml.std.annotations.XACMLResource;
+import com.att.research.xacml.std.annotations.XACMLSubject;
+import com.att.research.xacml.std.datatypes.HexBinary;
+import com.att.research.xacml.std.datatypes.IPAddress;
+import com.att.research.xacml.std.datatypes.IPv4Address;
+import com.att.research.xacml.std.datatypes.ISO8601DateTime;
+import com.att.research.xacml.std.datatypes.ISO8601Time;
+import com.att.research.xacml.util.FactoryException;
+import com.att.research.xacmlatt.pdp.test.TestBase;
+
+/**
+ * This example application shows how to use annotations for Java classes to 
create requests to send to the
+ * engine.
+ * 
+ * @author pameladragosh
+ *
+ */
+public class TestAnnotation extends TestBase {
+       private static final Log logger = 
LogFactory.getLog(TestAnnotation.class);
+       
+       private int     num;
+       
+       /**
+        * This is a sample class that uses annotations. In addition to 
demonstrating how to use XACML annotations,
+        * it also demonstrates the various Java objects that can be used and 
how the request parser will
+        * resolve each object's datatype.
+        * 
+        * @author pameladragosh
+        *
+        */
+       @XACMLRequest(ReturnPolicyIdList=true)
+       public class MyRequestAttributes {
+               
+               public MyRequestAttributes(String user, String action, String 
resource) {
+                       this.userID = user;
+                       this.action = action;
+                       this.resource = resource;
+                       this.today = new Date();
+                       this.yesterday = Calendar.getInstance();
+                       this.yesterday.add(Calendar.DAY_OF_MONTH, -1);
+               }
+
+               @XACMLSubject(includeInResults=true)
+               String  userID;
+               
+               
@XACMLSubject(attributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id-qualifier")
+               boolean admin = false;
+               
+               
@XACMLSubject(attributeId="urn:oasis:names:tc:xacml:1.0:subject:key-info", 
issuer="com:foo:security")
+               HexBinary publicKey = new HexBinary(new byte[] {'1', '0'});
+               
+               
@XACMLSubject(attributeId="urn:oasis:names:tc:xacml:1.0:subject:authentication-time")
+               ISO8601Time     authenticationTime = new ISO8601Time(8, 0, 0, 
0);
+               
+               /**
+                * Here our base object is "Object", but it is reflected as a 
Java "String". The parser
+                * will then use the XACML 
http://www.w3.org/2001/XMLSchema#string as the datatype.
+                */
+               
@XACMLSubject(attributeId="urn:oasis:names:tc:xacml:1.0:subject:authentication-method")
+               Object authenticationMethod = new String("RSA Public Key");
+               
+               /**
+                * Here our base object is "String", but we use the annotation 
for datatype to clarify
+                * that the real XACML data type is 
http://www.w3.org/2001/XMLSchema#time. The parser will
+                * use the data type factory to convert the "String" to a 
"ISO8601Time" Java object.
+                */
+               
@XACMLSubject(attributeId="urn:oasis:names:tc:xacml:1.0:subject:request-time", 
datatype="http://www.w3.org/2001/XMLSchema#time";)
+               String requestTime = new String("13:20:00-05:00");
+               
+               
@XACMLSubject(attributeId="urn:oasis:names:tc:xacml:1.0:subject:session-start-time")
+               ISO8601DateTime sessionStart = new 
ISO8601DateTime(TimeZone.getDefault().getID(), 2014, 1, 1, 10, 0, 0, 0);
+               
+               
@XACMLSubject(attributeId="urn:oasis:names:tc:xacml:3.0:subject:authn-locality:ip-address")
+               IPAddress ip = new IPv4Address(new short[] {123, 134, 156, 255 
}, null, null);
+               
+               
@XACMLSubject(attributeId="urn:oasis:names:tc:xacml:3.0:subject:authn-locality:dns-name")
+               String dnsName = "localhost";
+               
+               @XACMLAction()
+               String  action;
+               
+               
@XACMLAction(attributeId="urn:oasis:names:tc:xacml:1.0:action:implied-action")
+               long    impliedAction;
+               
+               @XACMLResource()
+               String  resource;
+               
+               @XACMLEnvironment()
+               Date            today;
+               
+               @XACMLEnvironment()
+               Calendar        yesterday;
+               
+               /**
+                * This field demonstrates how the parser can detect 
collections and build a bag of values.
+                */
+               @XACMLAttribute(attributeId="foo:bar:attribute")
+               Collection<Double>              fooBar = Arrays.asList(2.5, 
3.5);
+               
+               /**
+                * The XACMLAttribute annotation allows one to specify all the 
+                */
+               @XACMLAttribute(category="foo:bar:category", 
attributeId="foo:bar:attribute2")
+               double          fooBar2 = 3.999;
+               
+               /**
+                * This field demonstrates how the parser can detect arrays and 
build a bag of values.
+                */
+               @XACMLAttribute(category="foo:bar:category", 
attributeId="foo:bar:attribute:many")
+               URI[]           fooBarMany = new URI[] 
{URI.create("file://opt/app/test"), URI.create("https://localhost:8443/";)};
+               
+       };
+
+       @XACMLRequest(
+               Defaults="http://www.w3.org/TR/1999/Rec-xpath-19991116";,
+               multiRequest=@XACMLMultiRequest(values={
+                       @XACMLRequestReference(values={"subject1", "action", 
"resource"}),
+                       @XACMLRequestReference(values={"subject2", "action", 
"resource"})})
+       )
+       public class MyMultiRequestAttributes {
+               
+               @XACMLSubject(id="subject1")
+               String  userID1 = "John";
+               
+               @XACMLSubject(id="subject2")
+               String  userID2 = "Ringo";
+
+               @XACMLAction(id="action")
+               String  action = "access";
+
+               @XACMLResource(id="resource")
+               String  resource = "www.mywebsite.com";
+       }
+
+       public TestAnnotation(String[] args) throws MalformedURLException, 
ParseException, HelpException {
+               super(args);
+       }
+
+       @Override
+       public void run() throws IOException, FactoryException {
+               //
+               // We are not going to iterate any existing request files. So 
we will override
+               // any TestBase code that assumes there are request files 
present.
+               //
+               //
+               // Configure ourselves
+               //
+               this.configure();
+               //
+               // Cycle through creating a few objects
+               //
+               this.num = 0;
+               this.doRequest(new MyRequestAttributes("John", "access", 
"www.mywebsite.com"));
+               this.num++;
+               this.doRequest(new MyRequestAttributes("Ringo", "access", 
"www.mywebsite.com"));
+               this.num++;
+               this.doRequest(new MyMultiRequestAttributes());
+               this.num++;
+       }
+
+       private void doRequest(Object info) {
+               try {
+                       Response response = 
this.callPDP(RequestParser.parseRequest(info));
+                       Path resultFile;
+                       if (this.output != null) {
+                               resultFile = Paths.get(this.output.toString(), 
"Response." + String.format("%03d", this.num) + ".json");
+                       } else {
+                               resultFile = Paths.get(this.directory, 
"results", "Response." + String.format("%03d", this.num) + ".json");
+                       }
+                       //
+                       // Write the response to the result file
+                       //
+                       logger.info("Response is: " + response.toString());
+                       if (resultFile != null) {
+                               Files.write(resultFile, 
response.toString().getBytes());
+                       }
+               } catch (IllegalArgumentException | IllegalAccessException | 
DataTypeException | IOException e) {
+                       logger.error(e);
+                       e.printStackTrace();
+               }
+       }
+       
+       public static void main(String[] args) {
+               try {
+                       new TestAnnotation(args).run();
+               } catch (ParseException | IOException | FactoryException e) {
+                       logger.error(e);
+               } catch (HelpException e) {
+                       //
+                       // ignore this, its thrown just to exit the application
+                       // after dumping help to stdout.
+                       //
+               }               
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Conformance.java
----------------------------------------------------------------------
diff --git 
a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Conformance.java
 
b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Conformance.java
new file mode 100755
index 0000000..06c17bd
--- /dev/null
+++ 
b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Conformance.java
@@ -0,0 +1,625 @@
+/*
+ *                        AT&T - PROPRIETARY
+ *          THIS FILE CONTAINS PROPRIETARY INFORMATION OF
+ *        AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN
+ *             ACCORDANCE WITH APPLICABLE AGREEMENTS.
+ *
+ *          Copyright (c) 2013 AT&T Knowledge Ventures
+ *              Unpublished and Not for Publication
+ *                     All Rights Reserved
+ */
+package com.att.research.xacmlatt.pdp.test.conformance;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.Advice;
+import com.att.research.xacml.api.Attribute;
+import com.att.research.xacml.api.AttributeAssignment;
+import com.att.research.xacml.api.AttributeCategory;
+import com.att.research.xacml.api.AttributeValue;
+import com.att.research.xacml.api.IdReference;
+import com.att.research.xacml.api.Obligation;
+import com.att.research.xacml.api.Response;
+import com.att.research.xacml.api.Result;
+
+/**
+ * Conformance is an application that runs a <code>ConformanceTestSet</code> 
and dumps results comparing the actual and
+ * expected results.
+ * 
+ * TO RUN in Eclipse:
+ * This is run as a Java Application.
+ * You must first create a Run/Debug Configuration: 
+ *             Under the Argument tab, in Program Arguments you must set the 
-i or --input command line argument.
+ *             You should also direct the output to a file using -o or 
--output. (default is Console)
+ *             See the init() method in this file for other useful arguments.
+ *             Example for a Windows machine:
+ *                     -i testsets/conformance/xacml3.0-ct-v.0.4
+ *                     -o \Users\yourLogin\Downloads\conformance.txt
+ *             You must also set the VM arguments:
+ *                     
-Dxacml.properties=testsets/conformance/xacml.properties .
+ *                     -Dlog4j.configuration=.\logging.properties
+ * 
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class Conformance {
+       private ConformanceScopeResolver scopeResolver;
+       private ConformanceTestEngine testEngine;
+       private ConformanceTestSet testSet                      = new 
ConformanceTestSet();
+       private File outputFile;
+       private PrintWriter outputFileWriter;
+       
+       private List<String> testNamesToRun = new ArrayList<String>();
+       
+       private boolean verbose;
+       private boolean failuresOnly;
+       private boolean strict;
+       private boolean stopOnFirstError;
+       
+       private int testsRun;
+       private int decisionsMatch;
+       private int statusCodesMatch;
+       private int attributesMatch;
+       private int policyIdsMatch;
+       private int policySetIdsMatch;
+       private int associatedAdviceMatch;
+       private int obligationsMatch;
+       private int unknownFunctions;
+       
+       
+
+       
+       protected synchronized ConformanceScopeResolver getScopeResolver() {
+               if (this.scopeResolver == null) {
+                       this.scopeResolver      = new 
ConformanceScopeResolver();
+                       
+                       /*
+                        * TODO:
+                        * Add the known scopes for the 2.0 conformance test.  
This could be made more general by allowing loading
+                        * from a properties file eventually.
+                        */
+                       try {
+                               URI ID_SCOPE_ROOT       = new URI("urn:root");
+                               URI ID_SCOPE_CHILD1     = new 
URI("urn:root:child1");
+                               URI ID_SCOPE_CHILD2     = new 
URI("urn:root:child2");
+                               URI ID_SCOPE_C1D1       = new 
URI("urn:root:child1:descendant1");
+                               URI ID_SCOPE_C1D2       = new 
URI("urn:root:child1:descendant2");
+                               URI ID_SCOPE_C2D1       = new 
URI("urn:root:child2:descendant1");
+                               URI ID_SCOPE_C2D2       = new 
URI("urn:root:child2:descendant2");
+                               
+                               this.scopeResolver.add(ID_SCOPE_ROOT, 
ID_SCOPE_CHILD1);
+                               this.scopeResolver.add(ID_SCOPE_CHILD1, 
ID_SCOPE_C1D1);
+                               this.scopeResolver.add(ID_SCOPE_CHILD1, 
ID_SCOPE_C1D2);
+                               this.scopeResolver.add(ID_SCOPE_ROOT, 
ID_SCOPE_CHILD2);
+                               this.scopeResolver.add(ID_SCOPE_CHILD2, 
ID_SCOPE_C2D1);
+                               this.scopeResolver.add(ID_SCOPE_CHILD2, 
ID_SCOPE_C2D2);
+                       } catch (Exception ex) {
+                               ex.printStackTrace(System.err);
+                       }
+                       
+               }
+               return this.scopeResolver;
+       }
+       
+       private void close() throws IOException {
+               if (this.outputFileWriter != null) {
+                       this.outputFileWriter.close();
+               }
+       }
+       
+       private boolean init(String[] args) {
+               boolean lenientRequests = true;
+               boolean lenientPolicies = false;
+               // default is to not run any non-first-time iterations
+               int iterations                  = -1;
+               String testSetDirectoryNames = "";
+               for (int i = 0 ; i < args.length ; ) {
+                       
+                       if (args[i].equals("-h") || args[i].equals("--help") || 
args[i].equals("-help")) {
+                               printHelp();
+                               return false;
+                       }
+                       
+                       
+                       // where the XML Request/Response files are located
+                       if (args[i].equals("-i") || args[i].equals("--input")) {
+                               i++;
+                               while (i < args.length && 
!args[i].startsWith("-")) {
+                                       testSetDirectoryNames += " " + args[i];
+                                       try {
+                                               
testSet.addConformanceTestSet(ConformanceTestSet.loadDirectory(new 
File(args[i])));
+                                       } catch (Exception ex) {
+                                               ex.printStackTrace(System.err);
+                                               return false;
+                                       }
+                                       i++;
+                               }
+
+                       // File path name where output will be put - default is 
stdout == Console
+                       } else if (args[i].equals("-o") || 
args[i].equals("--output")) {
+                               if (i+1 < args.length) {
+                                       this.outputFile = new File(args[i+1]);
+                                       i       += 2;
+                               } else {
+                                       System.err.println("Missing argument to 
" + args[i] + " command line option");
+                                       return false;
+                               }
+                       // A list of specific test names (e.g.: -t IIA001 
IIA007 IIIE301) - default is to run all tests
+                       } else if (args[i].equals("-t") || 
args[i].equals("--tests")) {
+                               i++;
+                               while (i < args.length && 
!args[i].startsWith("-")) {
+                                       testNamesToRun.add(args[i]);
+                                       i++;
+                               }
+                               if (testNamesToRun.size() == 0) {
+                                       System.err.println("Missing test names 
after -t or --tests argument");
+                                       return false;
+                               }
+                       // Include full details in the response, both the 
expected reqsponse (from file) and the actual response
+                       } else if (args[i].equals("-v") || 
args[i].equals("--verbose")) {
+                               this.verbose    = true;
+                               i++;
+                       // Report only failures (success is silent)
+                       } else if (args[i].equals("-f") || 
args[i].equals("--failures")) {
+                               this.failuresOnly       = true;
+                               i++;
+                       // When set, the XML must not contain extra 
attibutes/elements.  Default is "lenient" where unexpected entries are ignored
+                       } else if (args[i].equals("-s") || 
args[i].equals("--strict")) {
+                               this.strict     = true;
+                               i++;
+                       // (self explanatory)
+                       } else if (args[i].equals("--stop-on-error")) {
+                               this.stopOnFirstError   = true;
+                               i++;
+                       } else if (args[i].equals("--lenient")) {
+                               lenientPolicies = true;
+                               lenientRequests = true;
+                               i++;
+                       } else if (args[i].equals("--lenient-policies")) {
+                               lenientPolicies = true;
+                               i++;
+                       } else if (args[i].equals("--lenient-requests")) {
+                               lenientRequests = true;
+                               i++;
+                       } else if (args[i].equals("--strict-policies")) {
+                               lenientPolicies = false;
+                               i++;
+                       } else if (args[i].equals("--strict-requests")) {
+                               lenientRequests = false;
+                               i++;
+                       } else if (args[i].equals("--iterations")) {
+                               // this is a count of how many ADDITIONAL times 
the decide() should be called.
+                               // The first time decide() is called it takes a 
long time to set up,
+                               // so to get an accurate number for how fast a 
single Request is handled we need to ignore the time for the first run
+                               // and timings for 1 or more non-first-time 
calls to decide().
+                               if (i+1 < args.length) {
+                                       try {
+                                               iterations      = 
Integer.parseInt(args[i+1]);
+                                               i       += 2;
+                                       } catch (NumberFormatException ex) {
+                                               System.err.println("Invalid 
iteration count '" + args[i+1] + "'");
+                                               return false;
+                                       }
+                               } else {
+                                       System.err.println("Missing argument to 
" + args[i] + " command line option");
+                                       return false;                           
        
+                               }
+                               if (iterations < 1) {
+                                       System.err.println("Cannot use 
--iterations " + iterations + ".  Must use an integer greater than 0");
+                                       return false;
+                               }
+                       } else {
+                               System.err.println("Unknown command line option 
" + args[i]);
+                               return false;
+                       }
+               }
+       
+               this.testEngine = new 
ConformanceTestEngine(this.getScopeResolver(), lenientRequests, 
lenientPolicies, iterations);
+
+               if (testSetDirectoryNames.length() == 0) {
+                       System.err.println("No test set directory given (need 
-i or --iniput command line option)");
+                       return false;
+               }
+               if (testSet.getListConformanceTests().size() == 0) {
+                       System.err.println("No tests in given directories: " + 
testSetDirectoryNames);
+               }
+               
+               if (testNamesToRun.size() > 0) {
+                       String s = "";
+                       for (String name : testNamesToRun) {
+                               s += ", " + name;
+                       }
+                       System.out.println("Tests limited to: " + 
s.substring(1));
+               }
+               
+               if (this.outputFile == null) {
+                       this.outputFileWriter   = new PrintWriter(System.out);
+               } else {
+                       try {
+                               this.outputFileWriter   = new PrintWriter(new 
FileOutputStream(this.outputFile));
+                       } catch (IOException ex) {
+                               System.err.println("Cannot open " + 
this.outputFile.getAbsolutePath() + " for writing.");
+                               return false;
+                       }
+               }
+               
+               return true;
+       }
+       
+       private void printHelp() {
+               System.out.println("usage: Conformance --input 
<tests_directory> OPTIONS");
+               System.out.println("");
+               System.out.println(" -f, --failures             Only include 
failed tests in the output.  \n"+
+                                                       "                       
Default is to include all test's results in the output file.");
+               System.out.println("");
+               System.out.println(" -h, --help         Prints help.");
+                       
+               System.out.println("");
+               System.out.println(" -i, --input <dir>  Directory containing 
the XML Request/Response files.  \n"+
+                                                       "                       
This may be multiple space-separated directory paths.  REQUIRED");
+               
+               System.out.println("");
+               System.out.println(" --iterations               The number of 
times to run through the set of tests in the input directory.");
+               
+               System.out.println("");
+               System.out.println(" --lenient          Allow both Requests and 
Policies to have unexpected elements, no data in <Content>, etc. \n"+
+                                                       "                       
Default is to not allow anything that is not explicitly listed in the XACML 
spec.");
+               
+               System.out.println("");
+               System.out.println(" --lenient-policies Allow Policies to have 
unexpected elements, no data in <Content>, etc.  \n" +
+                                                       "                       
Default is to not allow anything that is not explicitly listed in the XACML 
spec.");
+               
+               System.out.println("");
+               System.out.println(" --lenient-requests Allow Requests to have 
unexpected elements, no data in <Content>, etc.  \n" +
+                                                       "                       
Default is to not allow anything that is not explicitly listed in the XACML 
spec.");
+               
+               System.out.println("");
+               System.out.println(" -o, --output <dir> Directory where the 
output results file will be put.");
+               
+               System.out.println("");
+               System.out.println(" -s, --strict               Check both the 
Decision and all other parts of the Response (Attributes, Obligations and 
Advice). \n "+
+                                                       "                       
Default is to check just the Decision.");
+               
+               System.out.println("");
+               System.out.println(" --stop-on-error    Stop running 
conformance tests the first time one fails.  Default is to continue through all 
tests.");
+
+               System.out.println("");
+               System.out.println(" --strict-policies  Require Policies to 
have no unexpected elements, data in <Content>, etc.  \n" +
+                                                       "                       
This is the default, but can be used to override Policies when option --lenient 
is used.");
+               
+               System.out.println("");
+               System.out.println(" --strict-requests  Require Requests to 
have no unexpected elements, data in <Content>, etc.  \n" +
+                                                       "                       
This is the default, but can be used to override Requests when option --lenient 
is used.");
+               
+               System.out.println("");
+               System.out.println(" -t, --tests <list of test names>   A 
space-separated list of specific tests to be run. \n" +
+                                                       "                       
These are just the names of the tests as in 'IIA001 IIC178'.  \n" +
+                                                       "                       
Default is to run all tests in the input directory.");
+               
+               System.out.println("");
+               System.out.println(" -v, --verbose              The entire 
expected and actual Response objects in the output.  \n"+
+                                                       "                       
Default is just a summary line.");
+               
+       }
+       
+       private boolean failed(ConformanceTestResult conformanceTestResult) {
+               ResponseMatchResult responseMatchResult = 
conformanceTestResult.getResponseMatchResult();
+               if (responseMatchResult == null) {
+                       return true;
+               }
+               if (!responseMatchResult.decisionsMatch() || 
!responseMatchResult.statusCodesMatch()) {
+                       return true;
+               } else if (this.strict) {
+                       if (!responseMatchResult.associatedAdviceMatches() ||
+                               !responseMatchResult.attributesMatch() ||
+                               !responseMatchResult.obligationsMatch() ||
+                               !responseMatchResult.policyIdentifiersMatch() ||
+                               !responseMatchResult.policySetIdentifiersMatch()
+                                       ) {
+                               return true;
+                       }
+               }
+               return false;
+       }
+       
+       private void dump(AttributeAssignment attributeAssignment) {
+               this.outputFileWriter.println("\t\t\t\tAttributeAssignment:");
+               if (attributeAssignment.getCategory() != null) {
+                       this.outputFileWriter.println("\t\t\t\t\tCategory: " + 
attributeAssignment.getCategory().stringValue());
+               }
+               if (attributeAssignment.getAttributeId() != null) {
+                       this.outputFileWriter.println("\t\t\t\t\tAttributeId: " 
+ attributeAssignment.getAttributeId().stringValue());
+               }
+               if (attributeAssignment.getDataTypeId() != null) {
+                       this.outputFileWriter.println("\t\t\t\t\tDataType: " + 
attributeAssignment.getDataTypeId().stringValue());
+               }
+               if (attributeAssignment.getIssuer() != null) {
+                       this.outputFileWriter.println("\t\t\t\t\tIssuer: " + 
attributeAssignment.getIssuer());
+               }
+               if (attributeAssignment.getAttributeValue() != null && 
attributeAssignment.getAttributeValue().getValue() != null) {
+                       this.outputFileWriter.println("\t\t\t\t\tValue: " + 
attributeAssignment.getAttributeValue().getValue().toString());
+               }
+       }
+       
+       private void dump(Attribute attribute) {
+               this.outputFileWriter.println("\t\t\t\t\tAttribute: " + 
(attribute.getAttributeId() == null ? "" : 
attribute.getAttributeId().stringValue()));
+               if (attribute.getIssuer() != null) {
+                       this.outputFileWriter.println("\t\t\t\t\t\tIssuer: " + 
attribute.getIssuer());
+               }
+               Iterator<AttributeValue<?>> iterAttributeValues = 
attribute.getValues().iterator();
+               if (iterAttributeValues.hasNext()) {
+                       this.outputFileWriter.println("\t\t\t\t\t\tValues: ");
+                       while (iterAttributeValues.hasNext()) {
+                               this.outputFileWriter.print("\t\t\t\t\t\t\t");
+                               AttributeValue<?> attributeValue        = 
iterAttributeValues.next();
+                               if (attributeValue.getDataTypeId() != null) {
+                                       this.outputFileWriter.print("DataType: 
" + attributeValue.getDataTypeId().stringValue() + " ");
+                               }
+                               if (attributeValue.getValue() != null) {
+                                       this.outputFileWriter.print("Value: " + 
attributeValue.getValue().toString());
+                               }
+                               this.outputFileWriter.println();
+                       }
+               }
+       }
+       
+       private void dump(AttributeCategory attributeCategory) {
+               this.outputFileWriter.println("\t\t\tAttributeCategory: " + 
(attributeCategory.getCategory() == null ? "" : 
attributeCategory.getCategory().stringValue()));
+               Collection<Attribute> listAttributes    = 
attributeCategory.getAttributes();
+               if (listAttributes.size() > 0) {
+                       this.outputFileWriter.println("\t\t\t\tAttributes:");
+                       for (Attribute attribute: listAttributes) {
+                               this.dump(attribute);
+                       }
+               }
+       }
+       
+       private void dump(Result result) {
+               this.outputFileWriter.println("\t\t======== Result ==========");
+               this.outputFileWriter.println("\t\tDecision: " + 
(result.getDecision() == null ? "null" : result.getDecision().name()));
+               if (result.getStatus() == null) {
+                       this.outputFileWriter.println("\t\tStatus: null");
+               } else {
+                       this.outputFileWriter.println("\t\tStatus:");
+                       if (result.getStatus().getStatusCode() != null) {
+                               
this.outputFileWriter.println("\t\t\tStatusCode: " + 
result.getStatus().getStatusCode().toString());
+                       }
+                       if (result.getStatus().getStatusMessage() != null) {
+                               
this.outputFileWriter.println("\t\t\tStatusMessage: " + 
result.getStatus().getStatusMessage());
+                       }
+                       if (result.getStatus().getStatusDetail() != null) {
+                               
this.outputFileWriter.println("\t\t\tStatusDetail: " + 
result.getStatus().getStatusDetail().toString());
+                       }
+               }
+               Collection<Advice> listAdvice   = result.getAssociatedAdvice();
+               if (listAdvice.size() > 0) {
+                       this.outputFileWriter.println("\t\tAdvice:");
+                       for (Advice advice : listAdvice) {
+                               if (advice.getId() != null) {
+                                       
this.outputFileWriter.println("\t\t\tId: " + advice.getId().stringValue());
+                               }
+                               Collection<AttributeAssignment> 
attributeAssignments    = advice.getAttributeAssignments();
+                               if (attributeAssignments.size() > 0) {
+                                       
this.outputFileWriter.println("\t\t\tAttributeAssignments:");
+                                       for (AttributeAssignment 
attributeAssignment: attributeAssignments) {
+                                               this.dump(attributeAssignment);
+                                       }
+                               }                               
+                       }
+               }
+               Collection<Obligation> listObligations  = 
result.getObligations();
+               if (listObligations.size() > 0) {
+                       for (Obligation obligation: listObligations) {
+                               if (obligation.getId() != null) {
+                                       
this.outputFileWriter.println("\t\t\tId: " + obligation.getId().stringValue());
+                               }
+                               Collection<AttributeAssignment> 
attributeAssignments    = obligation.getAttributeAssignments();
+                               if (attributeAssignments.size() > 0) {
+                                       
this.outputFileWriter.println("\t\t\tAttributeAssignments:");
+                                       for (AttributeAssignment 
attributeAssignment : attributeAssignments) {
+                                               this.dump(attributeAssignment);
+                                       }
+                               }                               
+                       }
+               }
+               Collection<AttributeCategory> listAttributeCategories   = 
result.getAttributes();
+               if (listAttributeCategories.size() > 0) {
+                       this.outputFileWriter.println("\t\tAttributes:");
+                       for (AttributeCategory attributeCategory : 
listAttributeCategories) {
+                               this.dump(attributeCategory);
+                       }
+               }
+               Collection<IdReference> listIdReferences;
+               if ((listIdReferences = result.getPolicyIdentifiers()).size() > 
0) {
+                       this.outputFileWriter.println("\t\tPolicyIds:");
+                       for (IdReference idReference : listIdReferences) {
+                               this.outputFileWriter.println("\t\t\t" + 
idReference.toString());                               
+                       }
+               }
+               if ((listIdReferences = 
result.getPolicySetIdentifiers()).size() > 0) {
+                       this.outputFileWriter.println("\t\tPolicySetIds:");
+                       for (IdReference idReference : listIdReferences) {
+                               this.outputFileWriter.println("\t\t\t" + 
idReference.toString());                               
+                       }
+               }
+       }
+       
+       private void dump(String label, Response response) {
+               this.outputFileWriter.println("\t========== " + label + 
"==========");
+               if (response == null) {
+                       this.outputFileWriter.println("null");
+                       return;
+               }
+               
+               for (Result result : response.getResults()) {
+                       this.dump(result);
+               }
+       }
+       
+       private void dump(ConformanceTestResult conformanceTestResult) {
+               
+               ResponseMatchResult responseMatchResult = 
conformanceTestResult.getResponseMatchResult();
+               if (this.verbose) {
+                       this.outputFileWriter.println("========== Test " + 
conformanceTestResult.getConformanceTest().getTestName() + " ==========");
+                       this.dump("Expected Response", 
conformanceTestResult.getExpectedResponse());
+                       this.dump("Actual Response", 
conformanceTestResult.getActualResponse());
+                       if (responseMatchResult != null) {
+                               this.outputFileWriter.println("\t========== 
Matching ==========");
+                               this.outputFileWriter.println("\tDecisions 
Match? " + responseMatchResult.decisionsMatch());
+                               this.outputFileWriter.println("\tStatus Codes 
Match? " + responseMatchResult.statusCodesMatch());
+                               this.outputFileWriter.println("\tAttributes 
Match? " + responseMatchResult.attributesMatch());
+                               this.outputFileWriter.println("\tPolicyIds 
Match? " + responseMatchResult.policyIdentifiersMatch());
+                               this.outputFileWriter.println("\tPolicySetIds 
Match? " + responseMatchResult.policySetIdentifiersMatch());
+                               this.outputFileWriter.println("\tAssociated 
Advice Match? " + responseMatchResult.associatedAdviceMatches());
+                               this.outputFileWriter.println("\tObligations 
Match? " + responseMatchResult.obligationsMatch());
+                               this.outputFileWriter.println("========== End 
==========");                             
+                       }
+               } else {
+                       String testName = 
conformanceTestResult.getConformanceTest().getTestName();
+                       if (responseMatchResult != null) {
+                               Iterator<ResultMatchResult> iterResultMatches   
= responseMatchResult.getResultMatchResults();
+                               if (iterResultMatches == null || 
!iterResultMatches.hasNext()) {
+                                       this.outputFileWriter.println(testName);
+                               } else {
+                                       while (iterResultMatches.hasNext()) {
+                                               ResultMatchResult 
resultMatchResult     = iterResultMatches.next();
+                                               
this.outputFileWriter.printf("%s,%s,%s,%s,%s,%s,%s,%s,%d,%d\n",
+                                                               testName,
+                                                               
resultMatchResult.decisionsMatch(),
+                                                               
resultMatchResult.statusCodesMatch(),
+                                                               
resultMatchResult.attributesMatch(),
+                                                               
resultMatchResult.policyIdentifiersMatch(),
+                                                               
resultMatchResult.policySetIdentifiersMatch(),
+                                                               
resultMatchResult.associatedAdviceMatches(),
+                                                               
resultMatchResult.obligationsMatch(),
+                                                               
conformanceTestResult.getFirstCallTime(),
+                                                               
conformanceTestResult.getAverageTotalLoopTime()
+                                                               );
+                                       }
+                               }
+                       }
+               }
+               this.outputFileWriter.flush();
+       }
+       
+       private boolean run(ConformanceTest conformanceTest) throws Exception {
+               this.testsRun++;
+               ConformanceTestResult conformanceTestResult     = 
this.testEngine.run(conformanceTest);
+               boolean bFailed                                                 
        = true;
+               if (conformanceTestResult != null) {
+                       ResponseMatchResult responseMatchResult = 
conformanceTestResult.getResponseMatchResult();
+                       if (responseMatchResult != null) {
+                               if (responseMatchResult.decisionsMatch()) {
+                                       this.decisionsMatch++;
+                                       this.statusCodesMatch   += 
(responseMatchResult.statusCodesMatch() ? 1 : 0);
+                                       this.attributesMatch    += 
(responseMatchResult.attributesMatch() ? 1 : 0);
+                                       this.policyIdsMatch             += 
(responseMatchResult.policyIdentifiersMatch() ? 1 : 0);
+                                       this.policySetIdsMatch  += 
(responseMatchResult.policySetIdentifiersMatch() ? 1 : 0);
+                                       this.associatedAdviceMatch      += 
(responseMatchResult.associatedAdviceMatches() ? 1 : 0);
+                                       this.obligationsMatch           += 
(responseMatchResult.obligationsMatch() ? 1 : 0);
+                               }
+                               this.unknownFunctions           += 
(responseMatchResult.unknownFunction() ? 1 : 0);
+                               bFailed = this.failed(conformanceTestResult);
+                               if (bFailed || !this.failuresOnly) {
+                                       this.dump(conformanceTestResult);
+                               }
+                       } else if (conformanceTestResult.getError() != null) {
+                               
this.outputFileWriter.println(conformanceTestResult.getError());
+                       }
+               }
+               return (!bFailed || !this.stopOnFirstError);
+       }
+       
+       private void run() throws Exception {
+               long tStart     = System.currentTimeMillis();
+               
+               if (!this.verbose) {
+                       
this.outputFileWriter.println("Test,Decision,Status,Attributes,PolicyIds,PolicySetIds,Advice,Obligations");
+               }
+               Iterator<ConformanceTest> iterConformanceTests  = 
this.testSet.getConformanceTests();
+               boolean bContinue                                               
                = true;
+               while (bContinue && iterConformanceTests.hasNext()) {
+//                     bContinue       = this.run(iterConformanceTests.next());
+                       ConformanceTest test = iterConformanceTests.next();
+                       if (testNamesToRun.size() > 0) {
+                               if ( ! 
testNamesToRun.contains(test.getTestName())) {
+                                       continue;
+                               }
+                       }
+                       bContinue       = this.run(test);
+               }
+               
+               long tElapsed   = System.currentTimeMillis() - tStart;
+               
+               if (this.verbose) {
+                       this.outputFileWriter.println("Tests run = " + 
this.testsRun);
+                       this.outputFileWriter.println("Decisions match = " + 
this.decisionsMatch);
+                       this.outputFileWriter.println("Status Codes match = " + 
this.statusCodesMatch);
+                       this.outputFileWriter.println("Attributes match = " + 
this.attributesMatch);
+                       this.outputFileWriter.println("PolicyIds match = " + 
this.policyIdsMatch);
+                       this.outputFileWriter.println("PolicySetIds match = " + 
this.policySetIdsMatch);
+                       this.outputFileWriter.println("Associated Advice match 
= " + this.associatedAdviceMatch);
+                       this.outputFileWriter.println("Obligations match = " + 
this.obligationsMatch);
+                       this.outputFileWriter.println("Unknown functions = " + 
this.unknownFunctions);
+               } else {
+                       this.outputFileWriter.printf("Total 
(%d),%d,%d,%d,%d,%d,%d,%d,%d\n",
+                                       this.testsRun,
+                                       this.decisionsMatch,
+                                       this.statusCodesMatch,
+                                       this.attributesMatch,
+                                       this.policyIdsMatch,
+                                       this.policySetIdsMatch,
+                                       this.associatedAdviceMatch,
+                                       this.obligationsMatch,
+                                       this.unknownFunctions);
+               }
+               
+               if (tElapsed > 0) {
+                       long tHours             = tElapsed / (60*60*1000);
+                       tElapsed                = tElapsed - tHours * 60 * 60 
*1000;
+                       long tMinutes   = tElapsed / (60*1000);
+                       tElapsed                = tElapsed - tMinutes * 60 * 
1000;
+                       long tSeconds   = tElapsed / 1000;
+                       tElapsed                = tElapsed - tSeconds * 1000;
+                       
+                       this.outputFileWriter.printf("Elapsed time = 
%02d:%02d:%02d.%03d\n", tHours, tMinutes, tSeconds, tElapsed);
+                       this.outputFileWriter.printf("First decide time in 
nano-seconds %d\n", this.testEngine.getFirstDecideTime());
+                       this.outputFileWriter.printf("Total Multiple decide 
time in nano-seconds %d\n", this.testEngine.getDecideTimeMultiple());
+                       
+                       this.outputFileWriter.printf("\nAverage First decide 
time in nano-seconds %d\n", this.testEngine.getAvgFirstDecideTime());
+                       this.outputFileWriter.printf("Average decide time after 
first call in nano-seconds %d\n", this.testEngine.getAvgDecideTimeMultiple());
+               }
+       }
+       
+       public Conformance() {
+       }
+
+       public static void main(String[] args) {
+               Conformance conformance = new Conformance();
+               try {
+                       if (conformance.init(args)) {
+                               conformance.run();
+                       }
+                       
+               } catch (Exception ex) {
+                       ex.printStackTrace(System.err);
+                       System.exit(1);
+               } finally {
+                       try {
+                               conformance.close();
+                       } catch (IOException ex) {
+                               ex.printStackTrace(System.err);
+                       }
+               }
+               System.exit(0);
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ConformancePIPEngine.java
----------------------------------------------------------------------
diff --git 
a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ConformancePIPEngine.java
 
b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ConformancePIPEngine.java
new file mode 100755
index 0000000..2d5f0dd
--- /dev/null
+++ 
b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ConformancePIPEngine.java
@@ -0,0 +1,233 @@
+/*
+ *                        AT&T - PROPRIETARY
+ *          THIS FILE CONTAINS PROPRIETARY INFORMATION OF
+ *        AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN
+ *             ACCORDANCE WITH APPLICABLE AGREEMENTS.
+ *
+ *          Copyright (c) 2013 AT&T Knowledge Ventures
+ *              Unpublished and Not for Publication
+ *                     All Rights Reserved
+ */
+package com.att.research.xacmlatt.pdp.test.conformance;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.att.research.xacml.api.Attribute;
+import com.att.research.xacml.api.AttributeValue;
+import com.att.research.xacml.api.DataType;
+import com.att.research.xacml.api.DataTypeException;
+import com.att.research.xacml.api.DataTypeFactory;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.pip.PIPException;
+import com.att.research.xacml.api.pip.PIPFinder;
+import com.att.research.xacml.api.pip.PIPRequest;
+import com.att.research.xacml.api.pip.PIPResponse;
+import com.att.research.xacml.std.IdentifierImpl;
+import com.att.research.xacml.std.StdMutableAttribute;
+import com.att.research.xacml.std.pip.StdPIPResponse;
+import com.att.research.xacml.std.pip.engines.ConfigurableEngine;
+import com.att.research.xacml.util.FactoryException;
+
+/**
+ * ConformancePIPEngine implements the {@link 
com.att.research.xacml.api.pip.PIPFinder} interface to find attributes
+ * loaded from a text file containing the following fields:
+ *     category-id,attribute-id,datatype-id,issuer,value
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class ConformancePIPEngine implements ConfigurableEngine {
+       public static final String PROP_DESCRIPTION     = ".description";
+       public static final String PROP_FILE            = ".file";
+       
+       private static final Log logger = 
LogFactory.getLog(ConformancePIPEngine.class);
+       
+       private String name;
+       private String description;
+       private Map<String,PIPResponse> cache   = new 
HashMap<String,PIPResponse>();
+       private List<Attribute> listAttributes  = new ArrayList<Attribute>();
+       private DataTypeFactory dataTypeFactory;
+       
+       public ConformancePIPEngine() {
+               
+       }
+       
+       protected DataTypeFactory getDataTypeFactory() throws FactoryException {
+               if (this.dataTypeFactory == null) {
+                       this.dataTypeFactory    = DataTypeFactory.newInstance();
+               }
+               return this.dataTypeFactory;
+       }
+       
+       protected static String generateKey(PIPRequest pipRequest) {
+               StringBuilder stringBuilder     = new 
StringBuilder(pipRequest.getCategory().toString());
+               stringBuilder.append('+');
+               stringBuilder.append(pipRequest.getAttributeId().toString());
+               stringBuilder.append('+');
+               stringBuilder.append(pipRequest.getDataTypeId().toString());
+               String issuer   = pipRequest.getIssuer();
+               if (issuer != null) {
+                       stringBuilder.append('+');
+                       stringBuilder.append(issuer);
+               }
+               return stringBuilder.toString();
+       }
+       
+       protected void store(String[] fields) throws FactoryException {
+               DataTypeFactory thisDataTypeFactory     = 
this.getDataTypeFactory();
+               Identifier identifierCategory           = new 
IdentifierImpl(fields[0]);
+               Identifier identifierAttribute          = new 
IdentifierImpl(fields[1]);
+               Identifier identifierDataType           = new 
IdentifierImpl(fields[2]);
+               String issuer                                           = 
(fields.length == 5 ? fields[3] : null);
+               String value                                            = 
fields[fields.length - 1];
+               
+               DataType<?> dataType                            = 
thisDataTypeFactory.getDataType(identifierDataType);
+               if (dataType == null) {
+                       logger.error("Unknown data type " + 
identifierDataType.stringValue());
+                       return;
+               }
+               
+               AttributeValue<?> attributeValue        = null;
+               try {
+                       attributeValue  = dataType.createAttributeValue(value);
+               } catch (DataTypeException ex) {
+                       throw new FactoryException("DataTypeException creating 
AttributeValue", ex);
+               }
+               Attribute attribute                                     = new 
StdMutableAttribute(identifierCategory, identifierAttribute, attributeValue, 
issuer, false);
+               this.listAttributes.add(attribute);
+       }
+       
+       public void loadAttributes(File fileAttributes) throws IOException, 
ParseException, FactoryException {
+               if (fileAttributes != null) {
+                       if (!fileAttributes.exists()) {
+                               throw new FileNotFoundException("Attributes 
file " + fileAttributes.getAbsolutePath() + " not found.");
+                       } else if (!fileAttributes.canRead()) {
+                               throw new IOException("Attributes file " + 
fileAttributes.getAbsolutePath() + " is not readable.");
+                       }
+                       
+                       BufferedReader bufferedReader   = null;
+                       try {
+                               bufferedReader  = new BufferedReader(new 
InputStreamReader(new FileInputStream(fileAttributes)));
+                               String line;
+                               while ((line = bufferedReader.readLine()) != 
null) {
+                                       if (line.length() > 0) {
+                                               String[] fields = 
line.split("[|]",-1);
+                                               if (fields.length < 4) {
+                                                       logger.warn("Not enough 
fields in record \"" + line + "\"");
+                                                       continue;
+                                               }
+                                               this.store(fields);
+                                               
+                                       }
+                               }
+                       } finally {
+                               if (bufferedReader != null) {
+                                       bufferedReader.close();
+                               }
+                       }
+               }
+       }
+       
+       protected Attribute findAttribute(PIPRequest pipRequest) {
+               Attribute attributeResult                       = null;
+               Iterator<Attribute> iterAttributes      = 
this.listAttributes.iterator();
+               while ((attributeResult == null) && iterAttributes.hasNext()) {
+                       Attribute attributeTest = iterAttributes.next();
+                       if 
(pipRequest.getCategory().equals(attributeTest.getCategory()) &&
+                               
pipRequest.getAttributeId().equals(attributeTest.getAttributeId()) &&
+                               (pipRequest.getIssuer() == null || 
pipRequest.getIssuer().equals(attributeTest.getIssuer()))) {
+                               attributeResult = attributeTest;
+                       }
+               }
+               return attributeResult;
+       }
+
+       @Override
+       public PIPResponse getAttributes(PIPRequest pipRequest, PIPFinder 
pipFinder) throws PIPException {
+               String pipRequestKey    = generateKey(pipRequest);
+               PIPResponse pipResponse = this.cache.get(pipRequestKey);
+               if (pipResponse != null) {
+                       return pipResponse;
+               }
+               Attribute attributeMatch        = 
this.findAttribute(pipRequest);
+               if (attributeMatch == null) {
+                       return StdPIPResponse.PIP_RESPONSE_EMPTY;
+               }
+               /*
+                * Iterate through the values and only return the ones that 
match the requested data type
+                */
+               List<AttributeValue<?>> matchingValues  = new 
ArrayList<AttributeValue<?>>();
+               Iterator<AttributeValue<?>> iterAttributeValues = 
attributeMatch.getValues().iterator();
+               while (iterAttributeValues.hasNext()) {
+                       AttributeValue<?> attributeValue        = 
iterAttributeValues.next();
+                       if 
(pipRequest.getDataTypeId().equals(attributeValue.getDataTypeId())) {
+                               matchingValues.add(attributeValue);
+                       }
+               }
+               if (matchingValues.size() > 0) {
+                       Attribute attributeResponse     = new 
StdMutableAttribute(attributeMatch.getCategory(), 
attributeMatch.getAttributeId(), matchingValues, attributeMatch.getIssuer(), 
false);
+                       pipResponse                                     = new 
StdPIPResponse(attributeResponse);
+                       this.cache.put(pipRequestKey, pipResponse);
+               }
+               return pipResponse;
+       }
+
+       @Override
+       public String getName() {
+               return this.name;
+       }
+
+       @Override
+       public String getDescription() {
+               return this.description;
+       }
+
+       @Override
+       public void configure(String id, Properties properties) throws 
PIPException {
+               this.name       = id;
+               this.description        = properties.getProperty(id + 
PROP_DESCRIPTION);
+               if (this.description == null) {
+                       this.description        = "PIPEngine for the 
Conformance tests that loads attributes from a CSV file";
+               }
+               String pipFile          = properties.getProperty(id + 
PROP_FILE);
+               if (pipFile != null) {
+                       try {
+                               this.loadAttributes(new File(pipFile));
+                       } catch (Exception ex) {
+                               logger.error("Exception loading PIP file " + 
pipFile, ex);
+                               throw new PIPException("Exception loading PIP 
file " + pipFile, ex);
+                       }
+               }
+       }
+
+       @Override
+       public Collection<PIPRequest> attributesRequired() {
+               return Collections.emptyList();
+       }
+
+       @Override
+       public Collection<PIPRequest> attributesProvided() {
+               //
+               // We could return everything in our list
+               //
+               return Collections.emptyList();
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ConformanceRepository.java
----------------------------------------------------------------------
diff --git 
a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ConformanceRepository.java
 
b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ConformanceRepository.java
new file mode 100755
index 0000000..f402a73
--- /dev/null
+++ 
b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ConformanceRepository.java
@@ -0,0 +1,118 @@
+/*
+ *                        AT&T - PROPRIETARY
+ *          THIS FILE CONTAINS PROPRIETARY INFORMATION OF
+ *        AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN
+ *             ACCORDANCE WITH APPLICABLE AGREEMENTS.
+ *
+ *          Copyright (c) 2013 AT&T Knowledge Ventures
+ *              Unpublished and Not for Publication
+ *                     All Rights Reserved
+ */
+package com.att.research.xacmlatt.pdp.test.conformance;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+
+import com.att.research.xacml.util.StringUtils;
+import com.att.research.xacml.util.XACMLProperties;
+import com.att.research.xacmlatt.pdp.std.StdPolicyFinderFactory;
+
+/**
+ * ConformanceRepository represents one or more policies for a single policy 
test, which will include one or more root policies, and
+ * zero or more referenced policies.
+ * 
+ * @author car
+ * @version $Revision$
+ */
+public class ConformanceRepository {
+       private List<File> rootPolicies                 = new ArrayList<File>();
+       private List<File> referencedPolicies   = new ArrayList<File>();
+       
+       private void setXACMLProperty(String propertyName, List<File> 
listFiles) {
+               Iterator<File> iterFiles                        = 
listFiles.iterator();
+               StringBuilder stringBuilderIdList       = new StringBuilder();
+               while (iterFiles.hasNext()) {
+                       File file       = iterFiles.next();
+                       if (stringBuilderIdList.length() > 0) {
+                               stringBuilderIdList.append(',');
+                       }
+                       stringBuilderIdList.append(file.getName());
+                       
+                       XACMLProperties.setProperty(file.getName() + 
StdPolicyFinderFactory.PROP_FILE, file.getAbsolutePath());
+               }
+               XACMLProperties.setProperty(propertyName, 
stringBuilderIdList.toString());
+       }
+       
+       public ConformanceRepository() {
+       }
+       
+       public void setXACMLProperties() {
+               if (this.rootPolicies.size() > 0) {
+                       
this.setXACMLProperty(XACMLProperties.PROP_ROOTPOLICIES, this.rootPolicies);
+               }
+               if (this.referencedPolicies.size() > 0) {
+                       
this.setXACMLProperty(XACMLProperties.PROP_REFERENCEDPOLICIES, 
this.referencedPolicies);
+               }
+       }
+       
+       private void loadProperty(File fileDir, Properties properties, String 
propertyName, List<File> listFiles) {
+               String fileNameList     = properties.getProperty(propertyName);
+               if (fileNameList != null) {
+                       String[] fileNameArray  = fileNameList.split("[,]",0);
+                       if (fileNameArray != null && fileNameArray.length > 0) {
+                               for (String fileName : fileNameArray) {
+                                       File file       = new File(fileDir, 
fileName);
+                                       if (file.exists() && file.canRead()) {
+                                               listFiles.add(file);
+                                       }
+                               }
+                       }
+               }
+       }
+       
+       public void load(File fileRepository) throws IOException {
+               Properties propertiesRepository = new Properties();
+               try (InputStream is = new FileInputStream(fileRepository)) {
+                       propertiesRepository.load(is);
+               }
+               this.loadProperty(fileRepository.getParentFile(), 
propertiesRepository, XACMLProperties.PROP_ROOTPOLICIES, this.rootPolicies);
+               this.loadProperty(fileRepository.getParentFile(), 
propertiesRepository, XACMLProperties.PROP_REFERENCEDPOLICIES, 
this.referencedPolicies);
+       }
+       
+       public void addRootPolicy(File filePolicy) {
+               this.rootPolicies.add(filePolicy);
+       }
+       
+       public boolean hasRootPolicy() {
+               return (this.rootPolicies.size() > 0);
+       }
+       
+       @Override
+       public String toString() {
+               StringBuilder stringBuilder     = new StringBuilder("{");
+               boolean needComma                       = false;
+               
+               if (this.rootPolicies != null && this.rootPolicies.size() > 0) {
+                       stringBuilder.append("rootPolicies=");
+                       
stringBuilder.append(StringUtils.toString(this.rootPolicies.iterator()));
+                       needComma       = true;
+               }
+               if (this.referencedPolicies != null && 
this.referencedPolicies.size() > 0) {
+                       if (needComma) {
+                               stringBuilder.append(',');
+                       }
+                       stringBuilder.append("referencedPolicies=");
+                       
stringBuilder.append(StringUtils.toString(this.referencedPolicies.iterator()));
+                       needComma       = true;
+               }
+               stringBuilder.append('}');
+               return stringBuilder.toString();
+       }
+       
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ConformanceScopeResolver.java
----------------------------------------------------------------------
diff --git 
a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ConformanceScopeResolver.java
 
b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ConformanceScopeResolver.java
new file mode 100755
index 0000000..8359591
--- /dev/null
+++ 
b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ConformanceScopeResolver.java
@@ -0,0 +1,112 @@
+/*
+ *                        AT&T - PROPRIETARY
+ *          THIS FILE CONTAINS PROPRIETARY INFORMATION OF
+ *        AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN
+ *             ACCORDANCE WITH APPLICABLE AGREEMENTS.
+ *
+ *          Copyright (c) 2013 AT&T Knowledge Ventures
+ *              Unpublished and Not for Publication
+ *                     All Rights Reserved
+ */
+package com.att.research.xacmlatt.pdp.test.conformance;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.att.research.xacml.api.Attribute;
+import com.att.research.xacml.api.AttributeValue;
+import com.att.research.xacml.api.pdp.ScopeQualifier;
+import com.att.research.xacml.api.pdp.ScopeResolver;
+import com.att.research.xacml.api.pdp.ScopeResolverException;
+import com.att.research.xacml.api.pdp.ScopeResolverResult;
+import com.att.research.xacml.std.StdMutableAttribute;
+import com.att.research.xacml.std.StdScopeResolverResult;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.datatypes.DataTypes;
+
+/**
+ * ConformanceScopeResolver implements {@link 
com.att.research.xacml.pdp.ScopeResolver} for the conformance tests
+ * using a fixed set of hierarchical resources defined in a map.
+ * 
+ * @author car
+ * @version $Revision$
+ */
+public class ConformanceScopeResolver implements ScopeResolver {
+       private Log logger                                                      
                = LogFactory.getLog(ConformanceScopeResolver.class);
+       private Map<URI, List<URI>> mapIdentifierToChildren     = new 
HashMap<URI,List<URI>>();
+       
+       public ConformanceScopeResolver() {
+       }
+       
+       public void add(URI identifierRoot, URI identifierChild) {
+               List<URI> listChildrenRoot      = 
this.mapIdentifierToChildren.get(identifierRoot);
+               if (listChildrenRoot == null) {
+                       listChildrenRoot        = new ArrayList<URI>();
+                       this.mapIdentifierToChildren.put(identifierRoot, 
listChildrenRoot);
+               }
+               listChildrenRoot.add(identifierChild);
+       }
+       
+       private void addChildren(Attribute attributeResourceId, URI 
urnResourceIdValue, boolean bDescendants, List<Attribute> listAttributes) {
+               List<URI> listChildren  = 
this.mapIdentifierToChildren.get(urnResourceIdValue);
+               if (listChildren != null) {
+                       for (URI uriChild : listChildren) {
+                               AttributeValue<URI> attributeValueURI   = null;
+                               try {
+                                       attributeValueURI       = 
DataTypes.DT_ANYURI.createAttributeValue(uriChild);
+                                       if (attributeValueURI != null) {
+                                               listAttributes.add(new 
StdMutableAttribute(attributeResourceId.getCategory(), 
attributeResourceId.getAttributeId(), attributeValueURI, 
attributeResourceId.getIssuer(), attributeResourceId.getIncludeInResults()));
+                                       }
+                               } catch (Exception ex) {
+                                       this.logger.error("Exception converting 
URI to an AttributeValue");
+                               }
+                               if (bDescendants) {
+                                       this.addChildren(attributeResourceId, 
uriChild, bDescendants, listAttributes);
+                               }
+                       }
+               }
+       }
+       
+       private void addChildren(Attribute attributeResourceId, boolean 
bDescendants, List<Attribute> listAttributes) {
+               /*
+                * Iterate over the values that are URNs
+                */
+               Iterator<AttributeValue<URI>> iterAttributeValueURNs    = 
attributeResourceId.findValues(DataTypes.DT_ANYURI);
+               if (iterAttributeValueURNs != null) {
+                       while (iterAttributeValueURNs.hasNext()) {
+                               this.addChildren(attributeResourceId, 
iterAttributeValueURNs.next().getValue(), bDescendants, listAttributes);
+                       }
+               }
+       }
+       
+       @Override
+       public ScopeResolverResult resolveScope(Attribute attributeResourceId, 
ScopeQualifier scopeQualifier) throws ScopeResolverException {
+               List<Attribute> listAttributes  = new ArrayList<Attribute>();
+               switch(scopeQualifier) {
+               case CHILDREN:
+                       listAttributes.add(attributeResourceId);
+                       this.addChildren(attributeResourceId, false, 
listAttributes);
+                       break;
+               case DESCENDANTS:
+                       listAttributes.add(attributeResourceId);
+                       this.addChildren(attributeResourceId, true, 
listAttributes);
+                       break;
+               case IMMEDIATE:
+                       listAttributes.add(attributeResourceId);
+                       break;
+               default:
+                       this.logger.error("Unknown ScopeQualifier: " + 
scopeQualifier.name());
+                       return new StdScopeResolverResult(new 
StdStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Unknown ScopeQualifier " + 
scopeQualifier.name()));
+               }
+               return new StdScopeResolverResult(listAttributes);
+       }
+
+}

Reply via email to