Initial seed of merged of AT&T and JP Morgan code
diff --git a/openaz-pep/pom.xml b/openaz-pep/pom.xml
new file mode 100755
index 0000000..bcf6443
--- /dev/null
+++ b/openaz-pep/pom.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>openaz</artifactId>
+        <groupId>org.openliberty.openaz</groupId>
+        <version>0.0.1-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>openaz-pep</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>openaz-xacml</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>openaz-xacml-pdp</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-logging</groupId>
+            <artifactId>commons-logging</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Action.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Action.java
new file mode 100755
index 0000000..cd7975d
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Action.java
@@ -0,0 +1,62 @@
+package org.openliberty.openaz.pepapi;
+
+import com.att.research.xacml.api.XACML3;
+
+;
+
+/**
+ * Container class that maps attributes to predefined XACML Action category.
+ * 
+ * @author Ajith Nair, David Laurance, Darshak Kothari
+ *
+ */
+public class Action extends CategoryContainer {
+
+	public static final String ACTION_ID_KEY = "ACTION_ID_KEY";
+	
+	private String actionIdValue;
+	
+	private Action() {
+		super(XACML3.ID_ATTRIBUTE_CATEGORY_ACTION);
+	}
+	
+	/**
+	 * Creates a new Action instance
+	 * 
+	 * @return
+	 */
+	public static Action newInstance() {
+		return new Action();
+	}
+	
+	/**
+	 * Create a new Action instance containing a single default attribute with the given value
+	 * 
+	 * @param actionIdValue
+	 * @return
+	 */
+	public static Action newInstance(String actionIdValue) {
+		Action a = new Action();
+		a.actionIdValue = actionIdValue;
+		a.addAttribute(ACTION_ID_KEY, actionIdValue);
+		return a;
+	}
+	
+	/**
+	 * Get the value for default attribute.
+	 * 
+	 * @return
+	 */
+	public String getActionIdValue() {
+		return actionIdValue;
+	}
+
+	@Override
+	public String toString() {
+		StringBuilder builder = new StringBuilder();
+		builder.append("action-id value: " + actionIdValue);
+		builder.append("\n");
+		builder.append(super.toString());
+		return builder.toString();
+	}
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ActionResourcePair.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ActionResourcePair.java
new file mode 100755
index 0000000..4d9cc8c
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ActionResourcePair.java
@@ -0,0 +1,92 @@
+package org.openliberty.openaz.pepapi;

+

+

+/**

+ * A convenient abstraction for an action - resource pair.

+ * 

+ * @author Ajith Nair, David Laurance, Darshak Kothari

+ * 

+ */

+public final class ActionResourcePair {

+	

+	private final Object action;

+

+	private final Object resource;

+	

+	/**

+	 * Creates a new action - resource pair

+	 * 

+	 * @param action	an Object representing the action being performed.

+	 * @param resource	an Object representing the resource on which the action is being performed.

+	 */

+	public ActionResourcePair(Object action, Object resource){

+		this.resource = resource;

+		this.action = action;

+	}

+	

+	/**

+	 * Returns the resource associated with this action - resource pair

+	 * 

+	 * @return an Object representing the resource.

+	 */

+	public Object getResource() {

+		return resource;

+	}

+	

+	/**

+	 * Returns the action associated with this action - resource pair.

+	 * 

+	 * @return an Object representing the action.

+	 */

+	public Object getAction() {

+		return action;

+	}

+

+	@Override

+	public int hashCode() {

+		final int prime = 31;

+		int result = 1;

+		result = prime * result + ((action == null) ? 0 : action.hashCode());

+		result = prime * result

+				+ ((resource == null) ? 0 : resource.hashCode());

+		return result;

+	}

+

+	@Override

+	public boolean equals(Object obj) {

+		if (this == obj) {

+			return true;

+		}

+		if (obj == null) {

+			return false;

+		}

+		if (getClass() != obj.getClass()) {

+			return false;

+		}

+		ActionResourcePair other = (ActionResourcePair) obj;

+		if (action == null) {

+			if (other.action != null)

+				return false;

+		} else if (!action.equals(other.action)) {

+			return false;

+		}

+		

+		if (resource == null) {

+			if (other.resource != null) {

+				return false;

+			}

+		} else if (!resource.equals(other.resource)) {

+			return false;

+		}

+		return true;

+	}

+	

+	@Override

+	public String toString() {

+		StringBuilder builder = new StringBuilder();

+		builder.append("\nAction: " + action.toString());

+		builder.append("\nResource: " + resource.toString());

+		return builder.toString();

+	}

+	

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Advice.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Advice.java
new file mode 100755
index 0000000..46682d0
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Advice.java
@@ -0,0 +1,21 @@
+package org.openliberty.openaz.pepapi;
+
+import java.util.Map;
+
+/**
+ *
+ */
+public interface Advice {
+
+    /**
+     *
+     * @return
+     */
+    public String getId();
+
+    /**
+     *
+     */
+    public Map<String, Object[]> getAttributeMap();
+
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Attribute.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Attribute.java
new file mode 100755
index 0000000..c6c84bb
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Attribute.java
@@ -0,0 +1,30 @@
+package org.openliberty.openaz.pepapi;

+

+import java.lang.annotation.Retention;

+import java.lang.annotation.RetentionPolicy;

+import java.lang.annotation.Target;

+

+/**

+ * 

+ * Represents an Attribute match criterion, where an attribute with the given Id can take any of the values provided.

+ * If no value is available, then value matching is ignored. 

+ * 

+ * @author Ajith Nair, David Laurance, Darshak Kothari

+ *

+ */

+@Target({})

+@Retention(RetentionPolicy.CLASS)

+public @interface Attribute {

+	

+	/**

+	 * 

+	 * @return

+	 */

+	String id();

+	

+	/**

+	 * 

+	 * @return

+	 */

+	String[] anyValue() default {};

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/CategoryContainer.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/CategoryContainer.java
new file mode 100755
index 0000000..010bc6f
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/CategoryContainer.java
@@ -0,0 +1,140 @@
+package org.openliberty.openaz.pepapi;

+

+import com.att.research.xacml.api.Identifier;

+

+import java.net.URI;

+import java.util.Collections;

+import java.util.Date;

+import java.util.HashMap;

+import java.util.Map;

+import java.util.Map.Entry;

+

+/**

+ * Abstraction for an attribute container of a specific XACML category.

+ * 

+ * @author Ajith Nair, David Laurance, Darshak Kothari

+ * 

+ */

+public class CategoryContainer {

+

+	private final Map<String, Object[]> attributeMap;

+	

+	private final Identifier categoryIdentifier;

+

+	CategoryContainer(Identifier categoryIdentifier) {

+		this.categoryIdentifier = categoryIdentifier;

+		this.attributeMap = new HashMap<String, Object[]>();

+	}

+

+	private final void addToMap(String id, Object[] values) {

+		if (values != null && values.length > 0) {

+			attributeMap.put(id, values);

+		}else {

+			throw new IllegalArgumentException("Values cannot be null");

+		}

+	}

+	

+	public Identifier getCategoryIdentifier() {

+		return this.categoryIdentifier;

+	}

+	

+	/**

+	 * Returns all the contained attributes as a Map of key - value pairs.

+	 * 

+	 * @return

+	 */

+	public Map<String, Object[]> getAttributeMap() {

+		return Collections.unmodifiableMap(attributeMap);

+	}

+	

+	/**

+	 * Add a new attribute with the given id and one or more String values

+	 * 

+	 * @param id

+	 * @param values

+	 * @throws IllegalArgumentException, if values are null;

+	 */

+	public void addAttribute(String id, String... values) {

+		addToMap(id, values);

+	}

+	

+	/**

+	 * Add a new attribute with the given id and one or more Long values

+	 * 

+	 * @param id

+	 * @param values

+	 * @throws IllegalArgumentException, if values are null;

+	 */

+	public void addAttribute(String id, Long... values) {

+		addToMap(id, values);

+	}

+	

+	/**

+	 * Add a new attribute with the given id and one or more Integer values

+	 * 

+	 * @param id

+	 * @param values

+	 * @throws IllegalArgumentException, if values are null;

+	 */

+	public void addAttribute(String id, Integer... values) {

+		addToMap(id, values);

+	}

+	

+	/**

+	 * Add a new attribute with the given id and one or more Double values

+	 * 

+	 * @param id

+	 * @param values

+	 * @throws IllegalArgumentException, if values are null;

+	 */

+	public void addAttribute(String id, Double... values) {

+		addToMap(id, values);

+	}

+	

+	/**

+	 * Add a new attribute with the given id and one or more Boolean values

+	 * 

+	 * @param id

+	 * @param values

+	 * @throws IllegalArgumentException, if values are null;

+	 */

+	public void addAttribute(String id, Boolean... values) {

+		addToMap(id, values);

+	}

+	

+	/**

+	 * Add a new attribute with the given id and one or more <code>java.util.Date</code> values

+	 * 

+	 * @param id

+	 * @param values

+	 * @throws IllegalArgumentException, if values are null;

+	 */

+	public void addAttribute(String id, Date... values) {

+		addToMap(id, values);

+	}

+	

+	/**

+	 * Add a new attribute with the given id and one or more URI values

+	 * 

+	 * @param id

+	 * @param values

+	 * @throws IllegalArgumentException, if values are null;

+	 */

+	public void addAttribute(String id, URI... values) {

+		addToMap(id, values);

+	}

+

+	@Override

+	public String toString() {

+		StringBuilder builder = new StringBuilder();

+		for(Entry<String, Object[]> e: attributeMap.entrySet()) {

+			builder.append("Attribute Id: " + e.getKey());

+			builder.append(", Attribute Values: ");

+			for(Object o: e.getValue()) {

+				builder.append(o.toString() + ", ");

+			}

+			builder.append("\n");

+		}

+		return builder.toString();

+	}

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Environment.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Environment.java
new file mode 100755
index 0000000..42f8c64
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Environment.java
@@ -0,0 +1,27 @@
+package org.openliberty.openaz.pepapi;

+

+import com.att.research.xacml.api.XACML3;

+

+/**

+ * 

+ * Container class that maps attributes to predefined XACML Environment category.

+ * 

+ * @author Ajith Nair, David Laurance, Darshak Kothari

+ *

+ */

+public final class Environment extends CategoryContainer {

+

+	private Environment() {

+		super(XACML3.ID_ATTRIBUTE_CATEGORY_ENVIRONMENT);

+	}

+	

+	/**

+	 * Creates a new Environment instance

+	 * 

+	 * @return

+	 */

+	public static Environment newInstance() {

+		return new Environment();

+	}

+

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/InvalidAnnotationException.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/InvalidAnnotationException.java
new file mode 100755
index 0000000..39a220b
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/InvalidAnnotationException.java
@@ -0,0 +1,29 @@
+package org.openliberty.openaz.pepapi;

+

+/**

+ * RuntimeException thrown when a registered handler class does not contain one of the 

+ * required annotations - <code>@MatchAnyObligation</code>, <code>@MatchAllObligationAttributes</code>.

+ *   

+ * @author Ajith Nair, David Laurance, Darshak Kothari

+ *

+ */

+@SuppressWarnings("serial")

+public class InvalidAnnotationException extends RuntimeException {

+

+	public InvalidAnnotationException() {

+		super();

+	}

+

+	public InvalidAnnotationException(String message, Throwable cause) {

+		super(message, cause);

+	}

+

+	public InvalidAnnotationException(String message) {

+		super(message);

+	}

+

+	public InvalidAnnotationException(Throwable cause) {

+		super(cause);

+	}

+

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/MapperRegistry.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/MapperRegistry.java
new file mode 100755
index 0000000..41ea381
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/MapperRegistry.java
@@ -0,0 +1,35 @@
+package org.openliberty.openaz.pepapi;

+

+

+/**

+ * Container that holds <code>ObjectMapper</code> instances registered with the framework.

+ * 

+ * @author Ajith Nair, David Laurance, Darshak Kothari

+ *

+ */

+public interface MapperRegistry {

+	

+	/**

+	 * Registers the provided ObjectMapper instance 

+	 * 

+	 * @param mapper

+	 */

+	public void registerMapper(ObjectMapper mapper);

+

+	/**

+	 * Registers the provided ObjectMapper instances

+	 *

+	 * @param mappers

+	 */

+	public void registerMappers(Iterable<? extends ObjectMapper> mappers);

+

+	/**

+	 * Returns the ObjectMapper instance registered for the given Class.

+	 * 

+	 * @param clazz 

+	 * @return an ObjectMapper instance

+	 * @throws org.openliberty.openaz.pepapi.PepException if no ObjectMapper could be found for class clazz;

+	 */

+	public ObjectMapper getMapper(Class<?> clazz);

+	

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/MatchAllObligationAttributes.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/MatchAllObligationAttributes.java
new file mode 100755
index 0000000..19f2859
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/MatchAllObligationAttributes.java
@@ -0,0 +1,25 @@
+package org.openliberty.openaz.pepapi;

+

+import java.lang.annotation.ElementType;

+import java.lang.annotation.Retention;

+import java.lang.annotation.RetentionPolicy;

+import java.lang.annotation.Target;

+

+/**

+ * Represents a union of Obligation Attribute match criterion. 

+ * All attribute criterion supplied will be conjunctively matched by the framework.

+ * 

+ * @author Ajith Nair, David Laurance, Darshak Kothari

+ *

+ */

+@Target(ElementType.TYPE)

+@Retention(RetentionPolicy.RUNTIME)

+public @interface MatchAllObligationAttributes {

+	

+	/**

+	 * 

+	 * @return

+	 */

+	Attribute[] value();

+	

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/MatchAnyObligation.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/MatchAnyObligation.java
new file mode 100755
index 0000000..502c3fd
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/MatchAnyObligation.java
@@ -0,0 +1,25 @@
+package org.openliberty.openaz.pepapi;

+

+import java.lang.annotation.ElementType;

+import java.lang.annotation.Retention;

+import java.lang.annotation.RetentionPolicy;

+import java.lang.annotation.Target;

+

+/**

+ * Represents an Obligation criteria that matches any of the supplied Obligation ids.

+ * If no ids are provided, then any Obligation will be matched(catch-all).   

+ * 

+ * @author Ajith Nair, David Laurance, Darshak Kothari

+ *

+ */

+@Target(ElementType.TYPE)

+@Retention(RetentionPolicy.RUNTIME)

+public @interface MatchAnyObligation {

+	

+	/**

+	 * 

+	 * @return

+	 */

+	String[] value() default {};

+		

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Matchable.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Matchable.java
new file mode 100755
index 0000000..554523f
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Matchable.java
@@ -0,0 +1,19 @@
+package org.openliberty.openaz.pepapi;

+

+/**

+ * Interface that abstracts an object that can be matched. Concrete implementations provide a match() function. 

+ * 

+ * @author Ajith Nair, David Laurance, Darshak Kothari

+ * @param <T>

+ */

+public interface Matchable<T> {

+	

+	/**

+	 * Returns a boolean result after matching the given Object 

+	 * 

+	 * @param t

+	 * @return a <code>boolean</code> value 

+	 */

+	public boolean match(T t);

+	

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObjectMapper.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObjectMapper.java
new file mode 100755
index 0000000..0af85d9
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObjectMapper.java
@@ -0,0 +1,47 @@
+package org.openliberty.openaz.pepapi;

+

+

+

+/**

+ * Converts a Java Class (typically an application Domain Object) into request attributes of some Category. 

+ * Applications are expected to provide only a single ObjectMapper instance per Domain Type.

+ * 

+ * Typically, there is a one-to-one relationship between the Domain Type and Attribute Category. The interface, however, takes

+ * a general approach allowing a Domain Type to be mapped to multiple categories.

+ * 

+ * The conversion for the most part involves obtaining a <code>CategoryAttributes</code> instance for a specific category from the

+ * request context and then mapping Object properties as name-value pairs using one of the overloaded <code>setAttribute</code>

+ * methods.

+ * 

+ * @author Ajith Nair, David Laurance, Darshak Kothari

+ *

+ */

+public interface ObjectMapper {

+

+	/**

+	 * Returns a Class that represents the mapped domain type.

+	 * 

+	 * @return a Class object

+	 */

+	public Class<?> getMappedClass();

+	

+	/**

+	 * Maps Object properties to attributes

+	 * 

+	 * @param o - an instance of the domain object to be mapped

+	 * @param pepRequest - the current Request Context

+	 */

+	public void map(Object o, PepRequest pepRequest);

+

+	/**

+	 *

+	 * @param mapperRegistry

+	 */

+	public void setMapperRegistry(MapperRegistry mapperRegistry);

+

+	/**

+	 *

+	 * @param pepConfig

+	 */

+	public void setPepConfig(PepConfig pepConfig);

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Obligation.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Obligation.java
new file mode 100755
index 0000000..76f3656
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Obligation.java
@@ -0,0 +1,44 @@
+package org.openliberty.openaz.pepapi;

+

+import java.util.Map;

+

+/**

+ * The Obligation interface provides access to an Obligation

+ * object implementation that contains a set of zero or more

+ * Attributes.

+ * <p>

+ * The Obligation has an id: {@link #getId()}

+ * <p> 

+ * Each attribute has an id, as well, which are used as the key Strings

+ * of the Maps returned by method:

+ * <ul>

+ * <li>{@link #getAttributeMap()}</li>

+ * </ul>

+ * Each key String has an associated value, which can be an

+ * an array of Objects.

+ * <p>

+ *

+ * @author Josh Bregman, Rich Levinson, Prateek Mishra

+ *

+ */

+public interface Obligation {

+	

+    /**

+     * Return the Id for this Obligation.

+     *

+     * @return a string containing the Id of this Obligation

+     */

+    public String getId();

+    

+    /**

+     * Returns a Map of Obligation Attribute name,object-value-array pairs,

+     * indexed by name, where name is the AttributeId and the value

+     * is an array of one or more Object values of the "attribute"

+     * (where an array with length > 1 indicates a multi-valued attribute).

+     * <p>

+     * @return a Map of String (AttributeId name), Object array 

+     * (Attribute values) pairs

+     */

+    public Map<String, Object[]> getAttributeMap();

+

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationHandler.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationHandler.java
new file mode 100755
index 0000000..13cd008
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationHandler.java
@@ -0,0 +1,11 @@
+package org.openliberty.openaz.pepapi;

+

+

+/**

+ * 

+ * @author Ajith Nair, David Laurance, Darshak Kothari

+ *

+ */

+public interface ObligationHandler extends Matchable<Obligation>, ObligationStoreAware {

+	

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationHandlerRegistry.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationHandlerRegistry.java
new file mode 100755
index 0000000..a76733f
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationHandlerRegistry.java
@@ -0,0 +1,20 @@
+package org.openliberty.openaz.pepapi;

+

+

+import java.util.Map;

+

+/**

+ * Abstraction for a Obligation Handler registration mechanism. Subclasses provide specific implementations.   

+ * 

+ * @author Ajith Nair, David Laurance, Darshak Kothari

+ */

+public interface ObligationHandlerRegistry {

+	

+	/**

+	 * Returns a Map of <code>Matchable</code> implementations keyed by handler Class. 

+	 * 

+	 * @return

+	 */

+	public Map<Class<?>, Matchable<Obligation>> getRegisteredHandlerMap();

+	

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationRouter.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationRouter.java
new file mode 100755
index 0000000..1d3b368
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationRouter.java
@@ -0,0 +1,18 @@
+package org.openliberty.openaz.pepapi;

+

+import java.util.Map;

+

+/**

+ * 

+ * @author Ajith Nair, David Laurance, Darshak Kothari

+ *

+ */

+public interface ObligationRouter {

+	

+	/**

+	 * 

+	 * @param obligationMap

+	 */

+	public void routeObligations(Map<String, Obligation> obligationMap);

+	

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationStore.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationStore.java
new file mode 100755
index 0000000..9b65f95
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationStore.java
@@ -0,0 +1,27 @@
+package org.openliberty.openaz.pepapi;

+

+import java.util.Set;

+

+/**

+ * 

+ * @author Ajith Nair, David Laurance, Darshak Kothari

+ *

+ */

+public interface ObligationStore {

+	

+	/**

+	 * 

+	 * @param oHandlerClass

+	 * @return

+	 */

+	public Set<Obligation> getHandlerObligations(Class<?> oHandlerClass);

+	

+	/**

+	 * 

+	 * @param oHandlerClass

+	 * @param obligationId

+	 * @return

+	 */

+	public Obligation getHandlerObligationById(Class<?> oHandlerClass, String obligationId);

+	

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationStoreAware.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationStoreAware.java
new file mode 100755
index 0000000..99a65a2
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationStoreAware.java
@@ -0,0 +1,17 @@
+package org.openliberty.openaz.pepapi;

+

+

+/**

+ * 

+ * @author Ajith Nair, David Laurance, Darshak Kothari

+ *

+ */

+public interface ObligationStoreAware {

+	

+	/**

+	 * 

+	 * @param oStore

+	 */

+	public void setObligationStore(ObligationStore oStore);

+	

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepAgent.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepAgent.java
new file mode 100755
index 0000000..20b95fb
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepAgent.java
@@ -0,0 +1,89 @@
+package org.openliberty.openaz.pepapi;

+

+import java.util.List;

+

+/**

+ * 

+ * Serves as the main entry point into the PepAPI framework. It coordinates authorization request creation, execution and 

+ * response assemblage. Applications typically work with a single instance of PepAgent which is thread-safe.

+ * 

+ * The <code>decide()</code> method, which provides the most general mechanism for authorization, accepts a collection of application Domain Objects,

+ * each with it's own <code>ObjectMapper</code> defined.  The client application thus passes these Domain Objects directly,  <code>decide()</code> uses

+ * reflection to determine their type, and then finds a type-specific mapper.

+ * 

+ * This mechanism relies on application defined library of Object Mappers, one for each Domain Object that the client

+ * program expects to use in an authorization call.

+ * 

+ * It is important to note that Java Primitives/Wrappers and other standard types(except Collections) are not supported out of the box. 

+ * This is primarily because there is no sensible default mapping between a Java Standard Type and a XACML category and hence 

+ * it's impossible for the framework to make a mapping decision at runtime. However, client applications may enforce their own rules as 

+ * they see fit by providing Custom ObjectMapper(s) for these types.

+ * 

+ * <code>simpleDecide()</code> method addresses the simplest of use cases where attributes involved are simple userId, actionId and resourceId Strings.

+ * 

+ * <code>bulkDecide()</code> provides an abstraction for a MultiRequest, where in client applications may provide collection of Domain Object 

+ * bindings/associations each of which map to individual requests. The method separates out Domain Object associations with multiple cardinality 

+ * from the ones shared across requests.

+ * 

+ * Thus, in a <code>bulkDecide()</code> call applications provide two sets of arguments: 

+ * 		- a List of Domain Object bindings, each of which map to an individual request.

+ * 		- a collection of common Domain Objects shared across all requests.

+ * 

+ * Specific AzService implementations(PDP Providers) may implement bulkDecide() as a XACML MultiRequest (Note: XACML Multi Decision Profile is optional) 

+ * or as individual requests executed iteratively. 

+ * 

+ * @author Ajith Nair, David Laurance, Darshak Kothari

+ *

+ */

+public interface PepAgent {

+	

+	

+	/**

+	 * Returns a authorization decision for the given subjectId, actionId, 

+	 * resourceId Strings.

+	 * 

+	 * @param subjectId

+	 * @param actionId

+	 * @param resourceId

+	 * @return

+	 * @throws PepException 

+	 * 			- if an appropriate ObjectMapper cannot be found.

+	 * 			- if the underlying AzService instance/PDP throws an exception

+	 * 			- if the PepAgent is configured to throw PepExceptions for "Indeterminate" or "Not Applicable" decisions.

+	 * @throws IllegalArgumentException if any of the arguments are null

+	 */

+	public PepResponse simpleDecide(String subjectId, String actionId, String resourceId);

+	

+	/**

+	 * Returns an authorization decision for the given collection of Domain Objects each with it's own 

+	 * ObjectMapper instance. Java Primitives/Wrappers or other Standard types (except Collections) are not supported

+	 * out of the box. However, client applications may enforce their own rules as they see fit by providing Custom ObjectMapper(s) 

+	 * for these types.

+	 *  

+	 * @param objects

+	 * @return 

+	 * @throws PepException 

+	 * 			- if an appropriate ObjectMapper cannot be found.

+	 * 			- if the underlying AzService instance/PDP throws an exception

+	 * 			- if the PepAgent is configured to throw PepException for "Indeterminate" or "Not Applicable" decisions.

+	 * @throws IllegalArgumentException if any of the arguments are null

+	 */

+	public PepResponse decide(Object... objects);

+	

+	/**

+	 * Returns a PepResponse instance representing a collection of decisions, each of which corresponds to

+	 * an association. Each association represents a specific instance of Domain Object binding. A typical example for an association 

+	 * would be an Action-Resource pair.     

+	 * 

+	 * @param associations a list of Domain Object bindings, each of which maps to a individual Request.

+	 * @param objects a collection of common Domain Objects shared across all Requests.

+	 * @return

+	 * @throws PepException 

+	 * 			- if an appropriate ObjectMapper cannot be found.

+	 * 			- if the underlying AzService instance/PDP throws an exception

+	 * 			- if the PepAgent is configured to throw PepExceptions for "Indeterminate" or "Not Applicable" decisions.

+	 * @throws IllegalArgumentException if any of the arguments are null

+	 */

+	public List<PepResponse> bulkDecide(List<?> associations, Object... objects);

+	

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepAgentFactory.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepAgentFactory.java
new file mode 100755
index 0000000..3cb7601
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepAgentFactory.java
@@ -0,0 +1,16 @@
+package org.openliberty.openaz.pepapi;

+

+/**

+ * 

+ * @author Ajith Nair, David Laurance, Darshak Kothari

+ *

+ */

+public interface PepAgentFactory {

+	

+	/**

+	 * Returns a PepAgent instance

+	 * 

+	 * @return

+	 */

+	public PepAgent getPepAgent();

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepConfig.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepConfig.java
new file mode 100755
index 0000000..897c2f1
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepConfig.java
@@ -0,0 +1,51 @@
+package org.openliberty.openaz.pepapi;
+
+import java.util.List;
+
+/**
+ * @authors Ajith Nair, David Laurance, Darshak Kothari
+ */
+public interface PepConfig {
+
+    /**
+     *
+     * @return
+     */
+    public String getIssuer();
+
+    /**
+     *
+     * @return
+     */
+    public String getDefaultSubjectId();
+
+    /**
+     *
+     * @return
+     */
+    public String getDefaultResourceId();
+
+    /**
+     *
+     * @return
+     */
+    public String getDefaultActionId();
+
+    /**
+     *
+     * @return
+     */
+    public PepResponseBehavior getIndeterminateBehavior();
+
+    /**
+     *
+     * @return
+     */
+    public PepResponseBehavior getNotApplicableBehavior();
+
+    /**
+     *
+     * @return
+     */
+    public List<String> getMapperClassNames();
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepException.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepException.java
new file mode 100755
index 0000000..6f141d6
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepException.java
@@ -0,0 +1,66 @@
+/**

+ * Copyright 2009-2011 Oracle, Inc.

+ * Licensed under the Apache License, Version 2.0 (the "License"); 

+ * you may not use this file except in compliance with the License. 

+ * You may obtain a copy of the License at 

+ *   http://www.apache.org/licenses/LICENSE-2.0 

+ * Unless required by applicable law or agreed to in writing, software 

+ * distributed under the License is distributed on an "AS IS" BASIS, 

+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

+ * See the License for the specific language governing permissions and 

+ * limitations under the License.

+ *

+ * Authors:

+ * 	  1.1 (2011): Rich Levinson, Prateek Mishra (Oracle)

+ * 	  1.0 (2009): Josh Bregman, Rich Levinson, Prateek Mishra (Oracle)

+ * Contributor:

+ * 	  Rich Levinson (Oracle)

+ */

+package org.openliberty.openaz.pepapi;

+

+/**

+ * The PepException is used to provide additional

+ * information to callers of the PepApi when

+ * exception conditions occur.

+ * <p>

+ * PepApi 1.1: now extends RuntimeException in order

+ *  that users do not require try/catch blocks

+ *  when using PepApi 1.1.

+ * <p>

+ * @author Josh Bregman, Rich Levinson, Prateek Mishra

+ */

+public class PepException extends RuntimeException {

+

+	private static final long serialVersionUID = 1L;

+

+	/** 

+	 * Create a PepException containing a Throwable that

+	 * specifies the cause of this PepException.

+	 * @param cause

+	 */

+	public PepException(Throwable cause) {

+        super(cause);

+    }

+

+	/**

+	 * Create a PepException containing the message provided

+	 * and a Throwable containing further information as to

+	 * the cause of the PepException.

+	 * @param message

+	 * @param cause

+	 */

+    public PepException(String message, Throwable cause) {

+        super(message, cause);

+    }

+

+    /**

+     * Create a PepException containing the message provided.

+     * @param message

+     */

+    public PepException(String message) {

+        super(message);

+    }

+

+	public PepException() {super();}

+}

+

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepRequest.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepRequest.java
new file mode 100755
index 0000000..fe7391c
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepRequest.java
@@ -0,0 +1,46 @@
+/**

+ * Copyright 2009-2011 Oracle, Inc.

+ * Licensed under the Apache License, Version 2.0 (the "License"); 

+ * you may not use this file except in compliance with the License. 

+ * You may obtain a copy of the License at 

+ *   http://www.apache.org/licenses/LICENSE-2.0 

+ * Unless required by applicable law or agreed to in writing, software 

+ * distributed under the License is distributed on an "AS IS" BASIS, 

+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

+ * See the License for the specific language governing permissions and 

+ * limitations under the License.

+ *

+ * Authors:

+ *    (2014): Ajith Nair, David Laurance

+ * 	  1.1 (2011): Rich Levinson, Prateek Mishra (Oracle)

+ * 	  1.0 (2009): Josh Bregman, Rich Levinson, Prateek Mishra (Oracle)

+ * Contributor:

+ * 	  Rich Levinson (Oracle)

+ */

+package org.openliberty.openaz.pepapi;

+

+import com.att.research.xacml.api.Identifier;

+import com.att.research.xacml.api.Request;

+

+/**

+ *

+ * @author Josh Bregman, Rich Levinson, Prateek Mishra

+ *

+ */

+public interface PepRequest {

+

+    /**

+     * Returns a PepRequestAttributes instance that represents the attribute category identified

+     * by the categoryIdentfier parameter.

+     *

+     * @param categoryIdentifier an identifier for a category

+     */

+    public PepRequestAttributes getPepRequestAttributes(Identifier categoryIdentifier);

+

+    /**

+     *

+     * @return

+     */

+    public Request getWrappedRequest();

+

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepRequestAttributes.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepRequestAttributes.java
new file mode 100755
index 0000000..b011e9b
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepRequestAttributes.java
@@ -0,0 +1,128 @@
+package org.openliberty.openaz.pepapi;

+

+import com.att.research.xacml.api.Identifier;

+import com.att.research.xacml.api.RequestAttributes;

+

+import java.net.URI;

+import java.util.Date;

+

+/**

+ * Convenient wrapper around a RequestAttributes{@link com.att.research.xacml.api.RequestAttributes} instance,

+ * representing a collection of request attributes that belong to a particular category.

+ *

+ */

+public interface PepRequestAttributes {

+

+	/**

+	 * Returns an Indentifier representing the attribute category that the PepRequestAttributes encapsulates

+	 *

+	 * @return Identifier

+	 */

+	public Identifier getCategory();

+

+	/**

+	 * Returns an id representing the xml:id

+	 *

+	 * @return Identifier

+	 */

+	public String getId();

+

+	/**

+	 * Creates and adds an attribute with the name as the AttributeId,

+	 * Date array elements as AttributeValue(s) into the underlying attribute collection.

+	 * The attribute will NOT be returned by the PDP in the response after request evaluation.

+	 * 

+	 * @param name

+	 *            a string with a name to be used as AttributeId

+	 * @param values

+	 *            a Date array to be used as AttributeValue(s)

+	 * @throws IllegalArgumentException if the array is null

+	 */

+	public void addAttribute(String name, Date... values);

+

+	/**

+	 * Creates and adds an attribute with the name as the AttributeId,

+	 * String array elements as AttributeValue(s) into the underlying attribute collection.

+	 * The attribute will NOT be returned by the PDP in the response after request evaluation.

+	 *

+	 * @param name

+	 *            a string with a name to be used as AttributeId

+	 * @param values

+	 *            a String array to be used as AttributeValue(s)

+	 * @throws IllegalArgumentException if the array is null

+	 */

+	public void addAttribute(String name, String... values);

+

+	/**

+	 * Creates and adds an attribute with the name as the AttributeId,

+	 * Integer array elements as AttributeValue(s) into the underlying attribute collection.

+	 * The attribute will NOT be returned by the PDP in the response after request evaluation.

+	 *

+	 * @param name

+	 *            a string with a name to be used as AttributeId

+	 * @param values

+	 *            an Integer array to be used as AttributeValue(s)

+	 * @throws IllegalArgumentException if the array is null

+	 */

+	public void addAttribute(String name, Integer... values);

+

+	/**

+	 * Creates and adds an attribute with the name as the AttributeId,

+	 * Boolean array elements as AttributeValue(s) into the underlying attribute collection.

+	 * The attribute will NOT be returned by the PDP in the response after request evaluation.

+	 *

+	 * @param name

+	 *            a string with a name to be used as AttributeId

+	 * @param values

+	 *            a Boolean array to be used as AttributeValue(s)

+	 * @throws IllegalArgumentException if the array is null

+	 */

+	public void addAttribute(String name, Boolean... values);

+

+

+	/**

+	 * Creates and adds an attribute with the name as the AttributeId,

+	 * Long array elements as AttributeValue(s) into the underlying attribute collection.

+	 * The attribute will NOT be returned by the PDP in the response after request evaluation.

+	 *

+	 * @param name

+	 *            a string with a name to be used as AttributeId

+	 * @param values

+	 *            a Long array to be used as AttributeValue(s)

+	 * @throws IllegalArgumentException if the array is null

+	 */

+	public void addAttribute(String name, Long... values);

+

+	/**

+	 * Creates and adds an attribute with the name as the AttributeId,

+	 * Double array elements as AttributeValue(s) into the underlying attribute collection.

+	 * The attribute will NOT be returned by the PDP in the response after request evaluation.

+	 *

+	 * @param name

+	 *            a string with a name to be used as AttributeId

+	 * @param values

+	 *            a Double array to be used as AttributeValue(s)

+	 * @throws IllegalArgumentException if the array is null

+	 */

+	public void addAttribute(String name, Double... values);

+

+	/**

+	 * Creates and adds an attribute with the name as the AttributeId,

+	 * URI array elements as AttributeValue(s) into the underlying attribute collection.

+	 * The attribute will NOT be returned by the PDP in the response after request evaluation.

+	 * 

+	 * @param name

+	 *            a string AttributeId of the attribute being set

+	 * @param values

+	 *            a URI array to be used as AttributeValue(s

+	 * @throws IllegalArgumentException if the array is null

+	 */

+	public void addAttribute(String name, URI... values);

+

+	/**

+	 *

+	 * @return

+	 */

+	public RequestAttributes getWrappedRequestAttributes();

+

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepRequestFactory.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepRequestFactory.java
new file mode 100755
index 0000000..5b9a2ee
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepRequestFactory.java
@@ -0,0 +1,48 @@
+/**

+ * Copyright 2009-2011 Oracle, Inc.

+ * Licensed under the Apache License, Version 2.0 (the "License"); 

+ * you may not use this file except in compliance with the License. 

+ * You may obtain a copy of the License at 

+ *   http://www.apache.org/licenses/LICENSE-2.0 

+ * Unless required by applicable law or agreed to in writing, software 

+ * distributed under the License is distributed on an "AS IS" BASIS, 

+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

+ * See the License for the specific language governing permissions and 

+ * limitations under the License.

+ *

+ * Authors:

+ * 	  1.1 (2011): Rich Levinson, Prateek Mishra (Oracle)

+ * 	  1.0 (2009): Josh Bregman, Rich Levinson, Prateek Mishra (Oracle)

+ * Contributor:

+ * 	  Rich Levinson (Oracle)

+ */

+package org.openliberty.openaz.pepapi;

+

+import java.util.List;

+

+/**

+ *

+ * @author Josh Bregman, Rich Levinson, Prateek Mishra

+ *

+ */

+public interface PepRequestFactory {

+	

+    /**

+     *

+     * @return

+     * @throws org.openliberty.openaz.pepapi.PepException, if no ObjectMappers found.

+     * @throws IllegalArgumentException,, if any argument is null.

+     */

+    public PepRequest newPepRequest(Object[] objects);

+

+    /**

+     *

+     * @param associations

+     * @param objects

+     * @return

+     * @throws org.openliberty.openaz.pepapi.PepException, if ObjectMappers are not found.

+     * @throws IllegalArgumentException,, if the arguments are null.

+     */

+    public PepRequest newBulkPepRequest(List<?> associations, Object[] objects);

+

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponse.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponse.java
new file mode 100755
index 0000000..b27ea6b
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponse.java
@@ -0,0 +1,72 @@
+package org.openliberty.openaz.pepapi;

+

+import com.att.research.xacml.api.Attribute;

+import com.att.research.xacml.api.Identifier;

+import com.att.research.xacml.api.Result;

+

+import java.util.Collection;

+import java.util.Map;

+

+/**

+ * @author Josh Bregman, Rich Levinson, Prateek Mishra

+ */

+public interface PepResponse {

+	 

+	/**

+	 * Returns the decision associated with the current result.

+	 * @return true if the user was granted access to the resource, 

+	 * otherwise false

+	 * @throws PepException if the {@link PepResponseBehavior} 

+	 * configured in the {@link PepResponseFactory}

+	 * indicates that for the response should be thrown

+	 */

+    public boolean allowed() throws PepException;

+

+    /**

+     * Return the set of {@link org.openliberty.openaz.pepapi.Obligation}s associated with the

+     * current result indexed by ObligationId.

+     * @return a Map of ObligationId, Obligation pairs

+     * @throws PepException

+     * @see org.openliberty.openaz.pepapi.Obligation#getId()

+     */

+    public Map<String, Obligation> getObligations() throws PepException;

+

+    /**

+     * Return the set of {@link org.openliberty.openaz.pepapi.Advice}s associated with the

+     * current result indexed by adviceId.

+     * @return a Map of adviceId, Advice pairs

+     * @throws PepException

+     * @see org.openliberty.openaz.pepapi.Advice#getId()

+     */

+    public Map<String, Advice> getAdvices() throws PepException;

+

+	 /**

+     * Return the object association that is tied to the current

+     * result. The association is the same object that was

+     * used to create the PepRequest and may be used to 

+     * correlate the PepResponse results with the association

+     * pairs that were used to create the PepRequest.

+     * @return an object that was used as the action-resource in the PepRequest

+     * @throws PepException

+     */

+    public Object getAssociation() throws PepException;

+

+    /**

+     *

+     * @return

+     */

+    public Collection<Attribute> getAttributes();

+

+    /**

+     *

+     * @return

+     */

+    public Map<Identifier, Collection<Attribute>> getAttributesByCategory();

+

+    /**

+     *

+     * @return

+     */

+    public Result getWrappedResult();

+

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponseBehavior.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponseBehavior.java
new file mode 100755
index 0000000..ad1c70d
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponseBehavior.java
@@ -0,0 +1,22 @@
+package org.openliberty.openaz.pepapi;

+

+/**

+ * This enum provides the options that can be set using the

+ * {@link org.openliberty.openaz.pepapi.PepResponseFactory} to determine the behavior when

+ * {@link org.openliberty.openaz.pepapi.PepResponse#allowed()} is called AND the

+ * decision is either Indeterminate or NotApplicable.

+ *

+ * @author Josh Bregman, Rich Levinson, Prateek Mishra

+ *

+ */

+public enum PepResponseBehavior {

+	

+	/** The behavior is to allow (Permit) access by returning true when the condition for which this behavior is assigned occurs  */

+    RETURN_YES,

+    

+	/** The behavior is to disallow (Deny) access by returning false when the condition for which this behavior is assigned occurs  */

+    RETURN_NO,

+    

+	/** The behavior is to disallow (Deny) access by throwing a PepException when the condition for which this behavior is assigned occurs  */

+    THROW_EXCEPTION

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponseFactory.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponseFactory.java
new file mode 100755
index 0000000..82b92c7
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponseFactory.java
@@ -0,0 +1,51 @@
+package org.openliberty.openaz.pepapi;

+

+import com.att.research.xacml.api.Result;

+

+/**

+ * Factory for creating and configuring <code>PepResponse</code>.

+ * <br>  

+ * This class creates {@link org.openliberty.openaz.pepapi.PepResponse} objects and configures

+ * the behavior of how the <code>PepResponse</code> interprets the 

+ * results from the AzService or any other PDP that is supported

+ * by an implementation of PepApi (org.openliberty.openaz.azapi.pep.*).  

+ * <br>

+ * The {@link PepResponseBehavior} that is invoked when

+ * {@link org.openliberty.openaz.pepapi.PepResponse#allowed()} is called and the associated status code

+ * has been returned by the PDP and is being handled by the PepResponse

+ * provider impl, can be configured to be one of: 

+ * <ul>

+ * <li>

+ * {@link org.openliberty.openaz.pepapi.PepResponse#allowed()} returns true (PERMIT: {@link PepResponseBehavior#RETURN_YES}),

+ * <li>

+ * {@link org.openliberty.openaz.pepapi.PepResponse#allowed()} returns false (DENY: {@link PepResponseBehavior#RETURN_NO}),

+ * <li>

+ * or{@link org.openliberty.openaz.pepapi.PepResponse#allowed()} throws an exception (DENY: {@link PepResponseBehavior#THROW_EXCEPTION}).

+ * </ul>

+ * <p>

+ * In general, a Permit returns true, and a Deny returns false, 

+ * but there are also other types of returns, including 

+ * NotApplicable and Indeterminate. The configuration is to 

+ * specify for each of the 4 xacml-defined conditions, what 

+ * the behavior will be. i.e. for each of the "special" 

+ * conditions there is a choice to return either true (Permit), 

+ * false (Deny), or throw an Exception.

+ * <p>

+ * In addition, PDP-specific status codes can be specified, such

+ * that when the impl detects one of the configured status codes

+ * has been returned, then the {@link PepResponseBehavior} configured

+ * for that status code will be returned.

+ * <p>

+ * Finally, a default {@link PepResponseBehavior} may be configured

+ * for any status code that has not been explicitly configured

+ * or does not have its own default provided by the impl. The

+ * default if the statusCode default has not been configured is

+ * {@link PepResponseBehavior#THROW_EXCEPTION}.

+ * <p>

+ * @author Josh Bregman, Rich Levinson, Prateek Mishra

+ */

+public interface PepResponseFactory {

+	

+	public PepResponse newPepResponse(Result result);

+    

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponseType.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponseType.java
new file mode 100755
index 0000000..09b6203
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponseType.java
@@ -0,0 +1,25 @@
+package org.openliberty.openaz.pepapi;

+

+/**

+ *

+ * @author Josh Bregman, Rich Levinson, Prateek Mishra

+ */

+public enum PepResponseType {

+	/** The PepResponse returned for this query type will contain

+	 * only the list of resource action associations that are

+	 * allowed.

+	 */

+	ONLY_ALLOWED_RESULTS, 

+	/**

+	 * The PepResponse returned for this query type will contain

+	 * only the list of resource action associations that are

+	 * denied.

+	 */

+	ONLY_DENIED_RESULTS, 

+	/** The PepResponse returned for this query type will contain

+	 * the complete list of results for each resource action association

+	 * that was requested, including allowed, denied, notapplicable,

+	 * and indeterminate.

+	 */

+	ALL_RESULTS;

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PostDecisionHandler.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PostDecisionHandler.java
new file mode 100755
index 0000000..851f3a1
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PostDecisionHandler.java
@@ -0,0 +1,24 @@
+package org.openliberty.openaz.pepapi;

+

+/**

+ * An interface that may be implemented to process the 

+ * PepResponse that is returned from the main decide()

+ * call before the final results are returned to the user.

+ *

+ * @author Josh Bregman, Rich Levinson, Prateek Mishra

+ *

+ */

+public interface PostDecisionHandler {

+    

+	/** 

+	 * This method is used to apply post-decision custom

+	 * processing to the {@link org.openliberty.openaz.pepapi.PepResponse} after it has

+	 * been returned.

+	 *

+	 * @param request

+	 * @throws org.openliberty.openaz.pepapi.PepException

+	 */

+    public void postDecide(PepRequest request, PepResponse response) 

+    	throws PepException;

+    

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PreDecisionHandler.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PreDecisionHandler.java
new file mode 100755
index 0000000..472c9e8
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PreDecisionHandler.java
@@ -0,0 +1,23 @@
+package org.openliberty.openaz.pepapi;

+

+/**

+ * An interface that can be used for preliminary processing

+ * of a PepRequest before it is actually submitted to the 

+ * main decide() method.

+ *

+ * @author Josh Bregman, Rich Levinson, Prateek Mishra

+ *

+ */

+public interface PreDecisionHandler {

+    

+	/** 

+	 * This method is used to apply preliminary custom

+	 * processing to the {@link org.openliberty.openaz.pepapi.PepRequest} prior to its

+	 * being submitted.

+	 *

+	 * @param request

+	 * @throws org.openliberty.openaz.pepapi.PepException

+	 */

+	public void preDecide(PepRequest request) 

+    	throws PepException;

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Resource.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Resource.java
new file mode 100755
index 0000000..aa878d1
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Resource.java
@@ -0,0 +1,129 @@
+package org.openliberty.openaz.pepapi;

+

+import com.att.research.xacml.api.XACML3;

+

+import java.net.URI;

+import java.util.Date;

+

+/**

+ * Container class that maps attributes to predefined XACML Resource category.

+ * 

+ * @author Ajith Nair, David Laurance, Darshak Kothari

+ *

+ */

+public final class Resource extends CategoryContainer {

+

+	public static final String RESOURCE_ID_KEY = "RESOURCE_ID_KEY";

+	

+	private Object resourceIdValue;

+	

+	private Resource(){

+		super(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE);

+	}

+	

+	/**

+	 * Creates a new Resource instance

+	 * 

+	 * @return

+	 */

+	public static Resource newInstance() {

+		return new Resource();

+	}

+	

+	/**

+	 * Creates a new Resource instance containing a single default attribute with the given String value.

+	 * 

+	 * @param resourceIdValue

+	 * @return

+	 */

+	public static Resource newInstance(String resourceIdValue) {

+		Resource r = new Resource();

+		r.resourceIdValue = resourceIdValue;

+		r.addAttribute(RESOURCE_ID_KEY, resourceIdValue);

+		return r;

+	}

+	

+	/**

+	 * Creates a new Resource instance containing a single default attribute with the given URI value.

+	 * 

+	 * @param resourceIdValue

+	 * @return

+	 */

+	public static Resource newInstance(URI resourceIdValue) {

+		Resource r = new Resource();

+		r.resourceIdValue = resourceIdValue;

+		r.addAttribute(RESOURCE_ID_KEY, resourceIdValue);

+		return r;

+	}

+	

+	/**

+	 * Creates a new Resource instance containing a single default attribute with the given Long value.

+	 * 

+	 * @param resourceIdValue

+	 * @return

+	 */

+	public static Resource newInstance(Long resourceIdValue) {

+		Resource r = new Resource();

+		r.resourceIdValue = resourceIdValue;

+		r.addAttribute(RESOURCE_ID_KEY, resourceIdValue);

+		return r;

+	}

+	

+	/**

+	 * Creates a new Resource instance containing a single default attribute with the given Double value.

+	 * 

+	 * @param resourceIdValue

+	 * @return

+	 */

+	public static Resource newInstance(Double resourceIdValue) {

+		Resource r = new Resource();

+		r.resourceIdValue = resourceIdValue;

+		r.addAttribute(RESOURCE_ID_KEY, resourceIdValue);

+		return r;

+	}

+	

+	/**

+	 * Creates a new Resource instance containing a single default attribute with the given Boolean value.

+	 * 

+	 * @param resourceIdValue

+	 * @return

+	 */

+	public static Resource newInstance(Boolean resourceIdValue) {

+		Resource r = new Resource();

+		r.resourceIdValue = resourceIdValue;

+		r.addAttribute(RESOURCE_ID_KEY, resourceIdValue);

+		return r;

+	}

+	

+	/**

+	 * Creates a new Resource instance containing a single default attribute with the given <code>java.util.Date</code> value.

+	 * 

+	 * @param resourceIdValue

+	 * @return

+	 */

+	public static Resource newInstance(Date resourceIdValue) {

+		Resource r = new Resource();

+		r.resourceIdValue = resourceIdValue;

+		r.addAttribute(RESOURCE_ID_KEY, resourceIdValue);

+		return r;

+	}

+	

+	/**

+	 * Returns the value of the default resourceIdValue attribute

+	 * 

+	 * @return

+	 */

+	public Object getResourceIdValue() {

+		return resourceIdValue;

+	}

+

+

+	@Override

+	public String toString() {

+		StringBuilder builder = new StringBuilder();

+		builder.append("resource-id value : " + resourceIdValue);

+		builder.append("\n");

+		builder.append(super.toString());

+		return builder.toString();

+	}

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Subject.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Subject.java
new file mode 100755
index 0000000..011be09
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Subject.java
@@ -0,0 +1,60 @@
+package org.openliberty.openaz.pepapi;
+
+import com.att.research.xacml.api.XACML3;
+
+/**
+ * Container class that maps attributes to predefined XACML AccessSubject category.
+ * 
+ * @author Ajith Nair, David Laurance, Darshak Kothari
+ *
+ */
+public class Subject extends CategoryContainer {
+
+	public static final String SUBJECT_ID_KEY = "SUBJECT_ID_KEY";
+	
+	private String subjectIdValue;
+	
+	private Subject() {
+		super(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT);
+	}
+	
+	/**
+	 * Creates a new Subject instance
+	 * 
+	 * @return
+	 */
+	public static Subject newInstance() {
+		return new Subject();
+	}
+	
+	/**
+	 * Creates a new Subject instance containing a single default attribute with the given String value.
+	 * 
+	 * @param subjectIdValue
+	 * @return
+	 */
+	public static Subject newInstance(String subjectIdValue) {
+		Subject s = new Subject();
+		s.subjectIdValue = subjectIdValue;
+		s.addAttribute(SUBJECT_ID_KEY, subjectIdValue);
+		return s;
+	}
+	
+	/**
+	 * Returns the value of the default subjectIdValue attribute
+	 * 
+	 * @return
+	 */
+	public String getSubjectIdValue() {
+		return subjectIdValue;
+	}
+
+	@Override
+	public String toString() {
+		StringBuilder builder = new StringBuilder();
+		builder.append("subject-id value : " + subjectIdValue);
+		builder.append("\n");
+		builder.append(super.toString());
+		return builder.toString();
+	}
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/UnhandleableObligationException.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/UnhandleableObligationException.java
new file mode 100755
index 0000000..7c52cb6
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/UnhandleableObligationException.java
@@ -0,0 +1,27 @@
+package org.openliberty.openaz.pepapi;

+

+/**

+ * Runtime Exception thrown when the framework cannot find a registered handler to deal with the obligation.

+ * 

+ * @author Ajith Nair, David Laurance, Darshak Kothari

+ * 

+ */

+@SuppressWarnings("serial")

+public class UnhandleableObligationException extends RuntimeException {

+	

+	public UnhandleableObligationException() {

+		super();

+	}

+

+	public UnhandleableObligationException(String message, Throwable cause) {

+		super(message, cause);

+	}

+

+	public UnhandleableObligationException(String message) {

+		super(message);

+	}

+

+	public UnhandleableObligationException(Throwable cause) {

+		super(cause);

+	}

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/package.html b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/package.html
new file mode 100755
index 0000000..40d15ff
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/package.html
@@ -0,0 +1,75 @@
+<html>

+<body>

+The goal of this 

+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/azapi/pep/package-summary.html"

+>"PepApi interface package"</a>

+is to provide a set of interfaces that provide a framework

+that will simplify the creation of Policy Enforcement Points (PEPs) 

+that use an underlying authorization provider that is accessed through the 

+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/azapi/package-summary.html"

+>"AzApi"</a> package.  

+<p>

+To accomplish this goal, the PepApi interface package provides a common 

+interface that applications and containers can use to make authorization

+calls to possibly any kind of authorization provider that uses a

+request/response interface.

+<p> 

+To keep the common interface both flexible and easy to use, this

+PepApi package makes some simplifying assumptions:

+

+<P>

+<ul>

+	<li>An authorization request context can be one of three varieties:

+	<ul>

+	<li>A single request for authorization of a single action on 

+	a single resource

+	<li>A bulk request that consists of multiple single requests.

+	<li>A query request that returns (in minimal or verbose form) 

+	the set of decisions on all resources and actions within a "scope"

+	</ul> 

+    <li>An authorization request consists of a single subject, 

+    a single action, and a single resource, with an optional environment

+    <li>Most applications can represent the subject,action,resource as Strings. 

+    <li>Most applications need the Date, Boolean, Double, Integer, String, Time and DateTime types of XACML

+    <li>All attributes have a single issuer

+    <li>Some applications need to represent the subject,action,resource as an object with attributes (i.e a Map)

+    <li>Some frameworks and containers needs to represent the subject,action,resources as native objects, and want to

+    use the same API as their applications.

+    <li>An authorization response is primarily a yes/no decision

+    <li>Applications use obligations, and want to consume the attributes of the obligation as Strings.

+    

+</ul>

+</P>

+The pep package is a simple layer on top of the azapi package.  

+All of the state is held inside of the classes in the azapi package.  

+This was done for both simplicity and to accommodate the creation of PEPs 

+that can benefit from the simpler API but may need a little more than the 

+above assumptions allow.  

+This additional capability is accomplished by being able to retrieve the 

+AzApiRequestContext from the PepRequest and being able to retrieve the 

+AzApiResponseContext from the PepResponse.  

+Since all of the state is in the azapi package, PEPs can just grab a 

+handle and continue building the request or processing the response.

+<p>

+Note: the "scope" of the PepApi has been conceptually expanded to

+include non-AzApi authorization providers as well as AzApi-based 

+providers. This change has not impacted the PepApi, but it has impacted

+how to most effectively conceptualize the implementations of PepApi.

+<p>

+The primary concept is to consider the 

+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/pep/package-summary.html"

+>reference impl</a>

+to be an application of a general framework, where this particular 

+instance the framework is being applied to an AzApi-packaged authorization

+provider. In fact, the 

+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/pdp/provider/SimpleConcreteSunXacmlService.html"

+>"reference AzApi SunXacml PDP impl"</a>, 

+may be considered to be just such an "AzApi-packaged" provider.

+<p>

+There is a tutorial provided with the 

+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/pep/package-summary.html#package_description"

+>PepApiImpl</a>

+package javadoc page that provides general guidelines for implementing a

+non-AzApi provider to be used by PepApi.

+</body>

+</html>
\ No newline at end of file
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ActionMapper.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ActionMapper.java
new file mode 100755
index 0000000..be24376
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ActionMapper.java
@@ -0,0 +1,22 @@
+package org.openliberty.openaz.pepapi.std;
+
+
+import org.openliberty.openaz.pepapi.Action;
+
+/**
+ * Created by ajith on 12/11/14.
+ */
+public class ActionMapper extends CategoryContainerMapper {
+
+    public ActionMapper() {
+        super(Action.class);
+    }
+
+    @Override
+    protected String resolveAttributeId(String attributeId) {
+        if(attributeId.equals(Action.ACTION_ID_KEY)) {
+            return getPepConfig().getDefaultActionId();
+        }
+        return attributeId;
+    }
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ActionResourcePairMapper.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ActionResourcePairMapper.java
new file mode 100755
index 0000000..ff97b85
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ActionResourcePairMapper.java
@@ -0,0 +1,35 @@
+package org.openliberty.openaz.pepapi.std;

+

+

+import org.openliberty.openaz.pepapi.*;

+

+public final class ActionResourcePairMapper implements ObjectMapper {

+

+	private MapperRegistry mapperRegistry;

+

+	private PepConfig pepConfig;

+	

+	@Override

+	public Class<?> getMappedClass() {

+		return ActionResourcePair.class;

+	}

+

+	@Override

+	public void map(Object o, PepRequest pepRequest) {

+		ActionResourcePair actionResource = (ActionResourcePair)o;

+		Object action = actionResource.getAction();

+		Object resource = actionResource.getResource();

+		mapperRegistry.getMapper(action.getClass()).map(action, pepRequest);

+		mapperRegistry.getMapper(resource.getClass()).map(resource, pepRequest);

+	}

+

+	@Override

+	public void setMapperRegistry(MapperRegistry mapperRegistry) {

+		this.mapperRegistry = mapperRegistry;

+	}

+

+	@Override

+	public void setPepConfig(PepConfig pepConfig) {

+		this.pepConfig = pepConfig;

+	}

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ArrayMapper.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ArrayMapper.java
new file mode 100755
index 0000000..b614b15
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ArrayMapper.java
@@ -0,0 +1,46 @@
+package org.openliberty.openaz.pepapi.std;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.openliberty.openaz.pepapi.*;

+

+

+public final class ArrayMapper implements ObjectMapper {

+	

+	private static final Log logger = LogFactory.getLog(ArrayMapper.class);

+

+	private PepConfig pepConfig;

+

+	private MapperRegistry mapperRegistry;

+

+	@Override

+	public Class<Object[]> getMappedClass() {

+		return Object[].class;

+	}

+

+	@Override

+	public void map(Object o, PepRequest pepRequest) {

+		Object[] array = (Object[])o;

+		if(array != null && array.length > 0) {

+			ObjectMapper mapper = mapperRegistry.getMapper(array[0].getClass());

+			if(mapper != null) {

+				for(Object item: array) {

+					mapper.map(item, pepRequest);

+				}

+			}else {

+				logger.error("Can't map an Object of class: " + array[0].getClass().getName());

+				throw new PepException("Can't map an Object of class: " + array[0].getClass().getName());

+			}

+		}

+	}

+

+	@Override

+	public void setMapperRegistry(MapperRegistry mapperRegistry) {

+		this.mapperRegistry = mapperRegistry;

+	}

+

+	@Override

+	public void setPepConfig(PepConfig pepConfig) {

+		this.pepConfig = pepConfig;

+	}

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/CategoryContainerMapper.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/CategoryContainerMapper.java
new file mode 100755
index 0000000..115368f
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/CategoryContainerMapper.java
@@ -0,0 +1,95 @@
+package org.openliberty.openaz.pepapi.std;

+

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.openliberty.openaz.pepapi.*;

+

+import java.net.URI;

+import java.util.Date;

+import java.util.Map;

+import java.util.Map.Entry;

+

+

+public class CategoryContainerMapper implements ObjectMapper {

+

+	private static final Log logger = LogFactory.getLog(CategoryContainerMapper.class);

+

+	private Class<?> mappedClass;

+

+	private MapperRegistry mapperRegistry;

+

+	private PepConfig pepConfig;

+

+	public CategoryContainerMapper(Class<?> mappedClass) {

+		this.mappedClass = mappedClass;

+	}

+

+	@Override

+	public Class<?> getMappedClass() {

+		return this.mappedClass;

+	}

+

+	@Override

+	public void map(Object o, PepRequest pepRequest) {

+		CategoryContainer a = (CategoryContainer)o;

+		PepRequestAttributes pepRequestAttributes = pepRequest.getPepRequestAttributes(a.getCategoryIdentifier());

+		Map<String, Object[]> aMap = a.getAttributeMap();

+		if(aMap != null) {

+			for(Entry<String, Object[]> e: aMap.entrySet()) {

+				String attributeId = resolveAttributeId(e.getKey());

+				Object[] values = e.getValue();

+				if(values != null && values.length > 0) {

+					map(pepRequestAttributes, attributeId, values);

+				} else {

+					logger.error("No value assigned for attribute : " + attributeId);

+					throw new IllegalArgumentException("No or null value for attribute : " + attributeId);

+				}

+			}

+		}

+	}

+

+	@Override

+	public void setMapperRegistry(MapperRegistry mapperRegistry) {

+		this.mapperRegistry = mapperRegistry;

+	}

+

+	@Override

+	public void setPepConfig(PepConfig pepConfig) {

+		this.pepConfig = pepConfig;

+	}

+

+	protected String resolveAttributeId(String attributeId) {

+		return attributeId;

+	}

+

+	private final void map(PepRequestAttributes pepRequestAttributes, String key, Object... values) {

+		Object value = values[0];

+		if (value instanceof String) {

+        	pepRequestAttributes.addAttribute(key, (String[]) values);

+        } else if (value instanceof Long) {

+        	pepRequestAttributes.addAttribute(key, (Long[]) values);

+        } else if (value instanceof Integer) {

+        	pepRequestAttributes.addAttribute(key, (Integer[]) values);

+        } else if (value instanceof Double) {

+        	pepRequestAttributes.addAttribute(key, (Double[]) values);

+        } else if (value instanceof Boolean) {

+        	pepRequestAttributes.addAttribute(key, (Boolean[]) values);

+        } else if (value instanceof URI) {

+        	pepRequestAttributes.addAttribute(key, (URI[]) values);

+        } else if (value instanceof Date) {

+        	pepRequestAttributes.addAttribute(key, (Date[]) values);

+        }else {

+			logger.error("Type: " + value.getClass().getName() + " cannot be mapped for attribute: " + key);

+        	throw new PepException("Can't map an object of class: " + value.getClass().getName());

+        }

+	}

+

+	protected PepConfig getPepConfig() {

+		return this.pepConfig;

+	}

+

+	protected MapperRegistry getMapperRegistry() {

+		return this.mapperRegistry;

+	}

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/CollectionMapper.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/CollectionMapper.java
new file mode 100755
index 0000000..dd6df7b
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/CollectionMapper.java
@@ -0,0 +1,46 @@
+package org.openliberty.openaz.pepapi.std;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.openliberty.openaz.pepapi.*;

+

+import java.util.Collection;

+

+

+public final class CollectionMapper implements ObjectMapper {

+	

+	private static final Log logger = LogFactory.getLog(CollectionMapper.class);

+

+	private MapperRegistry mapperRegistry;

+

+	private PepConfig pepConfig;

+	

+	@Override

+	public Class<?> getMappedClass() {

+		return Collection.class;

+	}

+

+	@Override

+	public void map(Object o, PepRequest pepRequest) {

+		Collection<?> collection = (Collection<?>)o;

+		for(Object item: collection) {

+			ObjectMapper mapper = mapperRegistry.getMapper(item.getClass());

+			if(mapper != null) {

+				mapper.map(item, pepRequest);

+			}else {

+				logger.error("Can't map an Object of class: " + item.getClass().getName());

+				throw new PepException("Can't map an Object of class: " + item.getClass().getName());

+			}

+		}

+	}

+

+	@Override

+	public void setMapperRegistry(MapperRegistry mapperRegistry) {

+		this.mapperRegistry = mapperRegistry;

+	}

+

+	@Override

+	public void setPepConfig(PepConfig pepConfig) {

+		this.pepConfig = pepConfig;

+	}

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/MatchAnyCriterion.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/MatchAnyCriterion.java
new file mode 100755
index 0000000..9c11151
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/MatchAnyCriterion.java
@@ -0,0 +1,13 @@
+package org.openliberty.openaz.pepapi.std;

+

+

+import org.openliberty.openaz.pepapi.Obligation;

+

+public final class MatchAnyCriterion implements ObligationCriterion {

+

+	@Override

+	public boolean match(Obligation obligation) {

+		return true;

+	}

+

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/MultiRequest.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/MultiRequest.java
new file mode 100755
index 0000000..f19836e
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/MultiRequest.java
@@ -0,0 +1,123 @@
+package org.openliberty.openaz.pepapi.std;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.Request;
+import com.att.research.xacml.api.RequestReference;
+import com.att.research.xacml.std.StdMutableRequest;
+import com.att.research.xacml.std.StdMutableRequestReference;
+import com.att.research.xacml.std.StdRequestAttributesReference;
+import org.openliberty.openaz.pepapi.*;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ *
+ */
+final class MultiRequest implements PepRequest {
+
+    private static final String REQUEST_ATTR_ID_PREFIX = "attributes";
+
+    private final Map<Identifier, PepRequestAttributes> pepRequestAttributesMapByCategory;
+
+    private final MapperRegistry mapperRegistry;
+
+    private final PepConfig pepConfig;
+
+    private final Object[] sharedRequestObjects;
+
+    private List<?> associations;
+
+    private final AtomicInteger idCounter;
+
+    private final StdMutableRequest wrappedRequest;
+
+    private StdMutableRequestReference currentRequestReference;
+
+    private RequestReference sharedRequestReference;
+
+    static MultiRequest newInstance(PepConfig pepConfig, MapperRegistry mapperRegistry, List<?> associations, Object[] sharedRequestObjects) {
+        MultiRequest m = new MultiRequest(pepConfig, mapperRegistry, associations, sharedRequestObjects);
+        m.mapSharedRequestObjects();
+        m.mapAssociations();
+        return m;
+    }
+
+    private MultiRequest(PepConfig pepConfig, MapperRegistry mapperRegistry, List<?> associations, Object[] sharedRequestObjects) {
+        this.pepRequestAttributesMapByCategory = new HashMap<Identifier, PepRequestAttributes>();
+        this.sharedRequestObjects = sharedRequestObjects;
+        this.associations = associations;
+        this.mapperRegistry = mapperRegistry;
+        this.pepConfig = pepConfig;
+        this.idCounter = new AtomicInteger(1);
+        this.wrappedRequest = new StdMutableRequest();
+        this.currentRequestReference = new StdMutableRequestReference();
+    }
+
+    private void mapSharedRequestObjects() {
+        if(sharedRequestObjects == null) {
+            throw new IllegalArgumentException("One or more arguments are null");
+        }
+        for(Object o: sharedRequestObjects) {
+            if(o == null) {
+                throw new IllegalArgumentException("One or more arguments are null");
+            }
+            ObjectMapper mapper = mapperRegistry.getMapper(o.getClass());
+            if(mapper == null) {
+                throw new IllegalArgumentException("No mappers found for class: " + o.getClass().getName());
+            }
+            mapper.map(o, this);
+        }
+        //Collect
+        sharedRequestReference = currentRequestReference;
+    }
+
+    private void mapAssociations() {
+        if(associations == null) {
+            throw new IllegalArgumentException("One or more arguments are null");
+        }
+        for(Object association: associations) {
+            if(association == null) {
+                throw new IllegalArgumentException("One or more arguments are null");
+            }
+
+            //Prepare
+            pepRequestAttributesMapByCategory.clear();
+            currentRequestReference = new StdMutableRequestReference(sharedRequestReference.getAttributesReferences());
+            wrappedRequest.add(currentRequestReference);
+
+            //Map
+            ObjectMapper mapper = mapperRegistry.getMapper(association.getClass());
+            if(mapper == null) {
+                throw new IllegalArgumentException("No mappers found for class: " + association.getClass().getName());
+            }
+            mapper.map(association, this);
+        }
+    }
+
+    @Override
+    public PepRequestAttributes getPepRequestAttributes(Identifier categoryIdentifier) {
+        PepRequestAttributes pepRequestAttributes = pepRequestAttributesMapByCategory.get(categoryIdentifier);
+        if(pepRequestAttributes == null) {
+            String xmlId = generateRequestAttributesXmlId();
+            StdPepRequestAttributes p = new StdPepRequestAttributes(xmlId, categoryIdentifier);
+            p.setIssuer(pepConfig.getIssuer());
+            pepRequestAttributes = p;
+            pepRequestAttributesMapByCategory.put(categoryIdentifier, pepRequestAttributes);
+            wrappedRequest.add(pepRequestAttributes.getWrappedRequestAttributes());
+            currentRequestReference.add(new StdRequestAttributesReference(xmlId));
+        }
+        return pepRequestAttributes;
+    }
+
+    private String generateRequestAttributesXmlId() {
+        return REQUEST_ATTR_ID_PREFIX + idCounter.getAndIncrement();
+    }
+
+    @Override
+    public Request getWrappedRequest() {
+        return wrappedRequest;
+    }
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationAttributeCriterion.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationAttributeCriterion.java
new file mode 100755
index 0000000..23f00cb
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationAttributeCriterion.java
@@ -0,0 +1,87 @@
+package org.openliberty.openaz.pepapi.std;

+

+import org.openliberty.openaz.pepapi.Obligation;

+

+import java.util.*;

+

+public final class ObligationAttributeCriterion implements ObligationCriterion {

+	

+	private String id;

+	

+	private Set<String> valueSet;

+	

+	public ObligationAttributeCriterion(String id) {

+		this.id = id;

+		this.valueSet = new HashSet<String>();

+	}

+	

+	ObligationAttributeCriterion(String id, String...values) {

+		this(id);

+		if(values != null && values.length > 0){

+			this.valueSet.addAll(Arrays.asList(values));

+		}

+	}

+	

+	@Override

+	public int hashCode() {

+		final int prime = 31;

+		int result = 1;

+		result = prime * result + ((id == null) ? 0 : id.hashCode());

+		result = prime * result

+				+ ((valueSet == null) ? 0 : valueSet.hashCode());

+		return result;

+	}

+

+	@Override

+	public boolean equals(Object obj) {

+		if (this == obj)

+			return true;

+		if (obj == null)

+			return false;

+		if (getClass() != obj.getClass())

+			return false;

+		ObligationAttributeCriterion other = (ObligationAttributeCriterion) obj;

+		if (id == null) {

+			if (other.id != null)

+				return false;

+		} else if (!id.equals(other.id))

+			return false;

+		if (valueSet == null) {

+			if (other.valueSet != null)

+				return false;

+		} else if (!valueSet.equals(other.valueSet))

+			return false;

+		return true;

+	}

+

+	public String getId() {

+		return id;

+	}

+

+	public Set<String> getValueSet() {

+		return Collections.unmodifiableSet(valueSet);

+	}

+	

+	@Override

+	public boolean match(Obligation obligation) {

+		Map<String, Object[]> obligationAttrMap = obligation.getAttributeMap();

+		if(!obligationAttrMap.containsKey(this.id)) {

+			return false;

+		}

+		//Proceed with value matching, if the AttributeMatch has a defined value set to match.

+		if(!valueSet.isEmpty()) {

+			Object[] attributeValues = obligationAttrMap.get(this.id);

+			boolean valueFound = false;

+			if(attributeValues != null) {

+				for(Object attributeValue: attributeValues) {

+					if(valueSet.contains(attributeValue)) {

+						valueFound = true;

+						break;

+					}

+				}

+			}

+			return valueFound;

+		}

+		return true;

+	}

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationCriteria.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationCriteria.java
new file mode 100755
index 0000000..8a32271
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationCriteria.java
@@ -0,0 +1,28 @@
+package org.openliberty.openaz.pepapi.std;

+

+import org.openliberty.openaz.pepapi.Obligation;

+import org.openliberty.openaz.pepapi.Matchable;

+

+import java.util.Collection;

+import java.util.HashSet;

+import java.util.Set;

+

+public final class ObligationCriteria implements Matchable<Obligation> {

+	

+	private Set<ObligationCriterion> criteria;

+	

+	ObligationCriteria(Collection<ObligationCriterion> criteria){

+		this.criteria = new HashSet<ObligationCriterion>();

+		this.criteria.addAll(criteria);

+	}

+

+	@Override

+	public boolean match(Obligation obligation) {

+		for(ObligationCriterion criterion: criteria){

+			if(!criterion.match(obligation)){

+				return false;

+			}

+		}

+		return true;

+	}

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationCriteriaBuilder.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationCriteriaBuilder.java
new file mode 100755
index 0000000..3572bec
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationCriteriaBuilder.java
@@ -0,0 +1,37 @@
+package org.openliberty.openaz.pepapi.std;

+

+

+

+import java.util.HashSet;

+import java.util.Set;

+

+

+public final class ObligationCriteriaBuilder {

+

+	private Set<ObligationCriterion> criteria = new HashSet<ObligationCriterion>();

+

+	public ObligationCriteriaBuilder matchAttribute(String attributeId) {

+		criteria.add(new ObligationAttributeCriterion(attributeId));

+		return this;

+	}

+

+	public ObligationCriteriaBuilder matchAttributeWithAnyGivenValue(String attributeId,

+			String... values) {

+		criteria.add(new ObligationAttributeCriterion(attributeId, values));

+		return this;

+	}

+	

+	public ObligationCriteriaBuilder matchAnyObligationId(String... obligationIds) {

+		criteria.add(new ObligationIdCriterion(obligationIds));

+		return this;

+	}

+	

+	public ObligationCriteriaBuilder matchAnyObligation() {

+		criteria.add(new MatchAnyCriterion());

+		return this;

+	}

+	

+	public final ObligationCriteria build() {

+		return new ObligationCriteria(criteria);

+	}

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationCriterion.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationCriterion.java
new file mode 100755
index 0000000..82d8af1
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationCriterion.java
@@ -0,0 +1,10 @@
+package org.openliberty.openaz.pepapi.std;

+

+

+import org.openliberty.openaz.pepapi.Obligation;

+

+public interface ObligationCriterion {

+	

+	public boolean match(Obligation obligation);

+	

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationIdCriterion.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationIdCriterion.java
new file mode 100755
index 0000000..3763b87
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationIdCriterion.java
@@ -0,0 +1,25 @@
+package org.openliberty.openaz.pepapi.std;

+

+import org.openliberty.openaz.pepapi.Obligation;

+

+import java.util.Arrays;

+import java.util.HashSet;

+import java.util.Set;

+

+public final class ObligationIdCriterion implements ObligationCriterion {

+	

+	private Set<String> obligationIdSet;

+	

+	public ObligationIdCriterion(String... obligationIds){

+		this.obligationIdSet = new HashSet<String>();

+		if(obligationIds != null) {

+			this.obligationIdSet.addAll(Arrays.asList(obligationIds));

+		}

+	}

+	

+	@Override

+	public boolean match(Obligation obligation) {

+		return this.obligationIdSet.contains(obligation.getId());

+	}

+

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/PepUtils.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/PepUtils.java
new file mode 100755
index 0000000..983a811
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/PepUtils.java
@@ -0,0 +1,84 @@
+package org.openliberty.openaz.pepapi.std;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.io.*;
+import java.util.Properties;
+
+/**
+ *
+ */
+public class PepUtils {
+
+    private static final Log logger = LogFactory.getLog(PepUtils.class);
+
+    public static Class<?> loadClass(String className) {
+        ClassLoader currentClassLoader = PepUtils.class.getClassLoader();
+        Class<?> clazz;
+        try {
+            clazz = currentClassLoader.loadClass(className);
+        } catch (ClassNotFoundException e) {
+            ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
+            try {
+                clazz = contextClassLoader.loadClass(className);
+            } catch (ClassNotFoundException e1) {
+                throw new IllegalArgumentException(e);
+            }
+        }
+        return clazz;
+    }
+
+
+    public static <T> T instantiateClass(Class<T> clazz) {
+        try {
+            return clazz.newInstance();
+        } catch (InstantiationException e) {
+            throw new IllegalArgumentException(e);
+        } catch (IllegalAccessException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+
+    public static Properties loadProperties(String propertyFile) {
+        Properties properties = new Properties();
+
+        //Try the location as a file first.
+        File file = new File(propertyFile);
+        InputStream in;
+        if(file.exists() && file.canRead()) {
+            if (!file.isAbsolute()) {
+                file = file.getAbsoluteFile();
+            }
+            try {
+                in = new FileInputStream(file);
+            } catch (FileNotFoundException e) {
+                logger.info(propertyFile + " is not a file.");
+            }
+        }
+
+        in = PepUtils.class.getResourceAsStream(propertyFile);
+
+        if(in == null) {
+            logger.error("Invalid classpath of file location: " + propertyFile);
+            throw new IllegalArgumentException("Invalid classpath or file location: " + propertyFile);
+        }
+
+        try {
+            properties.load(in);
+        } catch (IOException e) {
+            logger.error(e);
+            throw new IllegalArgumentException(e);
+        } finally {
+            if(in != null) {
+                try {
+                    in.close();
+                } catch (IOException e) {
+                    logger.debug("Error closing stream", e);
+                }
+            }
+        }
+        return properties;
+    }
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ResourceMapper.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ResourceMapper.java
new file mode 100755
index 0000000..113d781
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ResourceMapper.java
@@ -0,0 +1,22 @@
+package org.openliberty.openaz.pepapi.std;
+
+
+import org.openliberty.openaz.pepapi.Resource;
+
+/**
+ * Created by ajith on 12/11/14.
+ */
+public class ResourceMapper extends CategoryContainerMapper {
+
+    public ResourceMapper() {
+        super(Resource.class);
+    }
+
+    @Override
+    protected String resolveAttributeId(String attributeId) {
+        if(attributeId.equals(Resource.RESOURCE_ID_KEY)) {
+            return getPepConfig().getDefaultResourceId();
+        }
+        return attributeId;
+    }
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdAdvice.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdAdvice.java
new file mode 100755
index 0000000..6649bac
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdAdvice.java
@@ -0,0 +1,47 @@
+package org.openliberty.openaz.pepapi.std;
+
+import com.att.research.xacml.api.AttributeAssignment;
+import org.openliberty.openaz.pepapi.Advice;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+final class StdAdvice implements Advice {
+
+    private com.att.research.xacml.api.Advice wrappedAdvice;
+
+    StdAdvice(com.att.research.xacml.api.Advice advice) {
+        this.wrappedAdvice = advice;
+    }
+
+    /**
+     * Return the Id for this Advice.
+     *
+     * @return a string containing the Id of this Advice
+     */
+    public String getId(){
+        return wrappedAdvice.getId().stringValue();
+    }
+
+    @Override
+    public Map<String, Object[]> getAttributeMap() {
+        Map<String, List<Object>> map = new HashMap<String, List<Object>>();
+        for(AttributeAssignment a: wrappedAdvice.getAttributeAssignments()) {
+            String attributeId = a.getAttributeId().stringValue();
+            List<Object> values = map.get(attributeId);
+            if(values == null) {
+                values = new ArrayList<Object>();
+                map.put(attributeId, values);
+            }
+            values.add(a.getAttributeValue().getValue());
+        }
+        Map<String, Object[]> attributeMap = new HashMap<String, Object[]>();
+        for(Map.Entry<String, List<Object>> e: map.entrySet()) {
+            attributeMap.put(e.getKey(), e.getValue().toArray(new Object[1]));
+        }
+        return attributeMap;
+    }
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdMapperRegistry.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdMapperRegistry.java
new file mode 100755
index 0000000..1c05ab3
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdMapperRegistry.java
@@ -0,0 +1,99 @@
+package org.openliberty.openaz.pepapi.std;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.openliberty.openaz.pepapi.*;

+

+import java.util.HashMap;

+import java.util.List;

+import java.util.Map;

+

+

+public final class StdMapperRegistry implements MapperRegistry {

+

+	private static final Log logger = LogFactory.getLog(StdMapperRegistry.class);

+	

+	private final Map<Class<?>, ObjectMapper> map;

+

+	private PepConfig pepConfig;

+

+	private StdMapperRegistry(PepConfig pepConfig) {

+		//Register defaults.

+		this.pepConfig = pepConfig;

+		map = new HashMap<Class<?>, ObjectMapper>();

+		registerMapper(new CollectionMapper());

+		registerMapper(new ArrayMapper());

+		registerMapper(new SubjectMapper());

+		registerMapper(new ActionMapper());

+		registerMapper(new ResourceMapper());

+		registerMapper(new CategoryContainerMapper(Environment.class));

+		registerMapper(new CategoryContainerMapper(CategoryContainer.class));

+		registerMapper(new ActionResourcePairMapper());

+	}

+

+	public static MapperRegistry newInstance(PepConfig pepConfig) {

+		return new StdMapperRegistry(pepConfig);

+	}

+	

+	public static MapperRegistry newInstance(PepConfig pepConfig, List<ObjectMapper> mappers) {

+		MapperRegistry mapperRegistry = newInstance(pepConfig);

+		if(mappers != null) {

+			mapperRegistry.registerMappers(mappers);

+		}

+		return mapperRegistry;

+	}

+	

+	@Override

+	public void registerMapper(ObjectMapper mapper) {

+		mapper.setPepConfig(pepConfig);

+		mapper.setMapperRegistry(this);

+		map.put(mapper.getMappedClass(), mapper);

+	}

+

+	@Override

+	public void registerMappers(Iterable<? extends ObjectMapper> mappers) {

+		for(ObjectMapper mapper: mappers) {

+			registerMapper(mapper);

+		}

+	}

+

+	@Override

+	public ObjectMapper getMapper(Class<?> clazz) {

+		ObjectMapper mapper = null;

+		Class<?> c = clazz;

+		while(mapper == null && !c.equals(Object.class)) {

+			mapper = getClassMapper(c);

+			c = c.getSuperclass();

+		}

+		

+		//Handle Arrays.

+    	if(mapper == null) {

+    		if(clazz.isArray()) {

+    			mapper = getMapper(Object[].class);

+    		}

+    	}

+ 	

+    	if(mapper != null) {

+			logger.debug("Mapper :" + mapper.getClass().getName() + " found for class: " + clazz);

+    		return mapper;

+    	}else {

+    		throw new PepException("No ObjectMapper found for Object of Class: " + clazz);

+    	}

+	}

+	

+	private ObjectMapper getClassMapper(Class<?> clazz) {

+		ObjectMapper mapper = map.get(clazz);

+		if(mapper == null) {

+			Class<?>[] interfaces = clazz.getInterfaces();

+			if(interfaces != null && interfaces.length > 0) {

+				for(Class<?> inf: interfaces) {

+					mapper = map.get(inf);

+					if(mapper != null) {

+						break;

+					}

+				}

+			}

+		}

+		return mapper;

+	}

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdObligation.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdObligation.java
new file mode 100755
index 0000000..d2fd1ca
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdObligation.java
@@ -0,0 +1,48 @@
+package org.openliberty.openaz.pepapi.std;

+

+import com.att.research.xacml.api.AttributeAssignment;

+import org.openliberty.openaz.pepapi.Obligation;

+

+import java.util.ArrayList;

+import java.util.HashMap;

+import java.util.List;

+import java.util.Map;

+

+

+final class StdObligation implements Obligation {

+

+	private com.att.research.xacml.api.Obligation wrappedObligation;

+

+	StdObligation(com.att.research.xacml.api.Obligation obligation) {

+		this.wrappedObligation = obligation;

+	}

+

+	/**

+     * Return the Id for this Obligation.

+     *

+     * @return a string containing the Id of this Obligation

+     */

+    public String getId(){

+		return wrappedObligation.getId().stringValue();

+    }

+

+	@Override

+	public Map<String, Object[]> getAttributeMap() {

+		Map<String, List<Object>> map = new HashMap<String, List<Object>>();

+		for(AttributeAssignment a: wrappedObligation.getAttributeAssignments()) {

+			String attributeId = a.getAttributeId().stringValue();

+			List<Object> values = map.get(attributeId);

+			if(values == null) {

+				values = new ArrayList<Object>();

+				map.put(attributeId, values);

+			}

+			values.add(a.getAttributeValue().getValue());

+		}

+

+		Map<String, Object[]> attributeMap = new HashMap<String, Object[]>();

+		for(Map.Entry<String, List<Object>> e: map.entrySet()) {

+			attributeMap.put(e.getKey(), e.getValue().toArray(new Object[1]));

+		}

+		return attributeMap;

+	}

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdObligationHandlerRegistry.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdObligationHandlerRegistry.java
new file mode 100755
index 0000000..488ce5b
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdObligationHandlerRegistry.java
@@ -0,0 +1,106 @@
+package org.openliberty.openaz.pepapi.std;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.openliberty.openaz.pepapi.Obligation;

+import org.openliberty.openaz.pepapi.ObligationHandler;

+import org.openliberty.openaz.pepapi.ObligationHandlerRegistry;

+import org.openliberty.openaz.pepapi.Attribute;

+import org.openliberty.openaz.pepapi.MatchAllObligationAttributes;

+import org.openliberty.openaz.pepapi.MatchAnyObligation;

+import org.openliberty.openaz.pepapi.Matchable;

+

+import java.lang.annotation.Annotation;

+import java.util.HashMap;

+import java.util.List;

+import java.util.Map;

+

+/**

+ * An <code>ObligationHandlerRegistry</code> implementation that accept handler classes that are either ObligationHandler instances 

+ * or contain any of the following annotations - <code> @MatchAnyObligation, @MatchAllObligationAttributes</code> 

+ * that represents Obligation criteria for registration.

+ * 

+ * @author Ajith Nair

+ *

+ */

+public class StdObligationHandlerRegistry implements ObligationHandlerRegistry {

+

+	private static final Log logger = LogFactory.getLog(StdObligationHandlerRegistry.class);

+

+	private final Map<Class<?>, Matchable<Obligation>> oHandlerCriteriaMap;

+

+	private StdObligationHandlerRegistry(List<?> oHandlers) {

+		oHandlerCriteriaMap = new HashMap<Class<?>, Matchable<Obligation>>();

+		for (Object oHandler : oHandlers) {

+			Class<?> oHandlerClass = oHandler.getClass();

+			Matchable<Obligation> matchable = null;

+			if(oHandler instanceof ObligationHandler) {

+				matchable = (ObligationHandler)oHandler;

+			}else {

+				matchable = processAnnotation(oHandlerClass);

+			}

+			

+			if (matchable != null) {

+				oHandlerCriteriaMap.put(oHandlerClass, matchable);

+			}else {

+				logger.error("Obligation Handler Class: " + oHandlerClass

+						+ " is not an instance of ObligationHandler or doesn't contain a valid Annotation");

+				throw new IllegalArgumentException("Obligation Handler Class: " + oHandlerClass

+						+ " is not an instance of ObligationHandler or doesn't contain a valid Annotation");

+			}

+		}

+	}

+	

+	/**

+	 * Process Annotations in the classes provided and translate those into <code>ObligationCriteria</code>.

+	 * 

+	 * @param oHandlerClass

+	 * @return an ObligationCriteria instance.

+	 */

+	private ObligationCriteria processAnnotation(Class<?> oHandlerClass) {

+		ObligationCriteria criteria = null;

+		for (Annotation a : oHandlerClass.getAnnotations()) {

+			if (a.annotationType().equals(MatchAnyObligation.class)) {

+				String[] obligationIds = ((MatchAnyObligation) a).value();

+				ObligationCriteriaBuilder criteriaBuilder = new ObligationCriteriaBuilder();

+				if (obligationIds != null && obligationIds.length > 0) {

+					criteriaBuilder.matchAnyObligationId(obligationIds);

+				} else {

+					criteriaBuilder.matchAnyObligation();

+				}

+				criteria = criteriaBuilder.build();

+			} else if (a.annotationType().equals(MatchAllObligationAttributes.class)) {

+				ObligationCriteriaBuilder criteriaBuilder = new ObligationCriteriaBuilder();

+				MatchAllObligationAttributes attributeObligationAnnotation = 

+						(MatchAllObligationAttributes) a;

+				for (Attribute attribute : attributeObligationAnnotation.value()) {

+					String attributeId = attribute.id();

+					String[] anyValue = attribute.anyValue();

+					if (anyValue != null && anyValue.length > 0) {

+						criteriaBuilder.matchAttributeWithAnyGivenValue(

+								attributeId, anyValue);

+					} else {

+						criteriaBuilder.matchAttribute(attributeId);

+					}

+				}

+				criteria = criteriaBuilder.build();

+			}

+		}

+		return criteria;

+	}

+	

+	/**

+	 * Returns a new instance of <code>StdObligationHandlerRegistry</code>.

+	 * 

+	 * @param oHandlers

+	 * @return

+	 */

+	public static ObligationHandlerRegistry newInstance(List<?> oHandlers) {

+		return new StdObligationHandlerRegistry(oHandlers);

+	}

+

+	@Override

+	public Map<Class<?>, Matchable<Obligation>> getRegisteredHandlerMap() {

+		return this.oHandlerCriteriaMap;

+	}

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdObligationRouter.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdObligationRouter.java
new file mode 100755
index 0000000..6cf3b2c
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdObligationRouter.java
@@ -0,0 +1,87 @@
+package org.openliberty.openaz.pepapi.std;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.openliberty.openaz.pepapi.Obligation;

+import org.openliberty.openaz.pepapi.ObligationHandlerRegistry;

+import org.openliberty.openaz.pepapi.ObligationRouter;

+import org.openliberty.openaz.pepapi.UnhandleableObligationException;

+import org.openliberty.openaz.pepapi.Matchable;

+

+import java.util.HashMap;

+import java.util.HashSet;

+import java.util.Map;

+import java.util.Map.Entry;

+import java.util.Set;

+

+/**

+ * Entity that routes obligations at runtime.

+ * 

+ * @see org.openliberty.openaz.pepapi.Obligation

+ * @author Ajith Nair

+ */

+public final class StdObligationRouter implements ObligationRouter {

+	

+	private static final Log logger = LogFactory.getLog(StdObligationRouter.class);

+	

+	private final ObligationHandlerRegistry registrationHandler;

+	

+	private final ThreadLocalObligationStore obligationStore;

+	

+	StdObligationRouter(ObligationHandlerRegistry registrationHandler,

+						ThreadLocalObligationStore threadLocalOStore) {

+		this.registrationHandler = registrationHandler;

+		this.obligationStore = threadLocalOStore;

+	}

+

+	public static StdObligationRouter newInstance(

+			ObligationHandlerRegistry registrationHandler,

+			ThreadLocalObligationStore threadLocalOStore) {

+		return new StdObligationRouter(registrationHandler,

+				threadLocalOStore);

+	}

+	

+	/**

+	 * Handles runtime obligations and routes to appropriate policy enforcement points as required.

+	 * 

+	 * @param obligationMap	a <code>Map</code> of <code>Obligation</code>s keyed by Obligation ID.

+	 * @throws org.openliberty.openaz.pepapi.UnhandleableObligationException	if an Obligation cannot be handled/routed.

+	 */

+	@Override

+	public void routeObligations(Map<String, Obligation> obligationMap) {

+		//Clear any stale Obligations on the current thread.

+		obligationStore.clear();

+		if(obligationMap != null) {

+			Map<Class<?>, Set<Obligation>> obligationMapByHandlerClass 

+									= new HashMap<Class<?>, Set<Obligation>>();

+			for(Entry<String, Obligation> oe: obligationMap.entrySet()) {

+				boolean isObligationHandleable = false;

+				String obligationId = oe.getKey();

+				Obligation obligation = oe.getValue();

+				for(Entry<Class<?>, Matchable<Obligation>> pe :

+								this.registrationHandler.getRegisteredHandlerMap().entrySet()) {

+					Class<?> handlerClass = pe.getKey();

+					Matchable<Obligation> matchable = pe.getValue();

+					if(matchable.match(obligation)) {

+						Set<Obligation> handlerObligationSet = obligationMapByHandlerClass.get(handlerClass);

+						if(handlerObligationSet == null){

+							handlerObligationSet = new HashSet<Obligation>();

+							obligationMapByHandlerClass.put(handlerClass, handlerObligationSet);

+						}

+						handlerObligationSet.add(obligation);

+						isObligationHandleable = true;

+						if(logger.isDebugEnabled()) {

+							logger.debug("Obligation - " + obligationId + " matched by Handler - " + handlerClass);

+						}

+					}

+				}

+				if(!isObligationHandleable) {

+					throw new UnhandleableObligationException(

+							"No ObligationHandlers available for handling Obligation: "

+									+ oe.getKey());

+				}

+			}

+			obligationStore.setObligations(obligationMapByHandlerClass);

+		}

+	}

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepAgent.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepAgent.java
new file mode 100755
index 0000000..519eefb
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepAgent.java
@@ -0,0 +1,192 @@
+package org.openliberty.openaz.pepapi.std;

+

+import com.att.research.xacml.api.Request;

+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.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 org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.openliberty.openaz.pepapi.*;

+

+import java.io.ByteArrayOutputStream;

+import java.io.IOException;

+import java.util.ArrayList;

+import java.util.List;

+import java.util.Properties;

+

+

+final class StdPepAgent implements PepAgent {

+	

+	@SuppressWarnings("unused")

+	private static final Log logger = LogFactory.getLog(StdPepAgent.class);

+

+	private Properties xacmlProperties;

+

+	private PepConfig pepConfig;

+

+	private PDPEngine pdpEngine;

+

+	private PDPEngineFactory pdpEngineFactory;

+

+	private List<ObligationStoreAware> obligationHandlers;

+	

+	private PepRequestFactory pepRequestFactory;

+	

+	private PepResponseFactory pepResponseFactory;

+	

+	StdPepAgent() {

+		obligationHandlers = new ArrayList<ObligationStoreAware>();

+	}

+	

+	final void initialize() {

+		assert(pdpEngineFactory != null);

+

+		//Instantiate PDPEngine

+		if(pdpEngine == null) {

+			try {

+				pdpEngine = pdpEngineFactory.newEngine(xacmlProperties);

+			} catch (FactoryException e) {

+				throw new PepException(e);

+			}

+		}

+

+		List<ObjectMapper> objectMappers = new ArrayList<ObjectMapper>();

+		for(String mapperClassName: pepConfig.getMapperClassNames()) {

+			Class<? extends ObjectMapper> clazz = (Class<? extends ObjectMapper>)PepUtils.loadClass(mapperClassName);

+			objectMappers.add(PepUtils.instantiateClass(clazz));

+		}

+		MapperRegistry mapperRegistry = StdMapperRegistry.newInstance(pepConfig, objectMappers);

+

+		ObligationRouter oRouter = null;

+		if(!obligationHandlers.isEmpty()) {

+			ObligationHandlerRegistry oHandlerRegistry = StdObligationHandlerRegistry.newInstance(obligationHandlers);

+			ThreadLocalObligationStore oStore = ThreadLocalObligationStore.newInstance();

+			for(ObligationStoreAware oHandler: obligationHandlers) {

+				oHandler.setObligationStore(oStore);

+			}

+            oRouter = StdObligationRouter.newInstance(oHandlerRegistry, oStore);

+		}

+		

+		//Instantiate PepRequestFactory

+		pepRequestFactory = new StdPepRequestFactory(pepConfig, mapperRegistry);

+		//Instantiate PepResponseFactory

+		pepResponseFactory = new StdPepResponseFactory(pepConfig, oRouter);

+	}

+	

+	@Override

+	public PepResponse decide(Object... objects) {

+		return decide(pepRequestFactory.newPepRequest(objects)).get(0);

+	}

+	

+	@Override

+	public PepResponse simpleDecide(String subjectId, String actionId,

+			String resourceId) {

+		return decide(Subject.newInstance(subjectId), Action.newInstance(actionId), Resource.newInstance(resourceId));

+	}

+	

+	@Override

+	public List<PepResponse> bulkDecide(List<?> actionResourcePairs, Object... objects) {

+		return decide(pepRequestFactory.newBulkPepRequest(actionResourcePairs, objects));

+	}

+		

+	private List<PepResponse> decide(PepRequest pepRequest) {

+		List<PepResponse> pepResponses = new ArrayList<PepResponse>();

+		Request request = pepRequest.getWrappedRequest();

+

+		//Log request

+		if(logger.isDebugEnabled()) {

+			logRequest(request);

+		}

+

+		Response response;

+		try {

+			response = pdpEngine.decide(request);

+		} catch (PDPException e) {

+			logger.error(e);

+			throw new PepException(e);

+		}

+

+		//Log the response

+		if(logger.isDebugEnabled()) {

+			logResponse(response);

+		}

+

+		for(Result result: response.getResults()) {

+			pepResponses.add(pepResponseFactory.newPepResponse(result));

+		}

+		return pepResponses;

+    }

+

+	private void logRequest(Request request) {

+		ByteArrayOutputStream out = new ByteArrayOutputStream();

+		try {

+			JSONRequest.convert(request, out);

+			logger.debug(out.toString("UTF-8"));

+		} catch (IOException e) {

+			logger.debug("Error printing XACML request in JSON", e);

+		} catch (JSONStructureException e) {

+			logger.debug("Error printing XACML request in JSON", e);

+		}finally {

+			if(out != null) {

+				try {

+					out.close();

+				} catch (IOException e) {

+					logger.debug("Error closing stream");

+				}

+			}

+		}

+	}

+

+	private void logResponse(Response response) {

+		ByteArrayOutputStream out = new ByteArrayOutputStream();

+		try {

+			JSONResponse.convert(response, out);

+			logger.debug(out.toString("UTF-8"));

+		} catch (IOException e) {

+			logger.debug("Error printing XACML response in JSON", e);

+		} catch (JSONStructureException e) {

+			logger.debug("Error printing XACML response in JSON", e);

+		}finally {

+			if(out != null) {

+				try {

+					out.close();

+				} catch (IOException e) {

+					logger.debug("Error closing stream");

+				}

+			}

+		}

+	}

+

+	public PDPEngine getPdpEngine() {

+		return pdpEngine;

+	}

+

+	public PepConfig getPepConfig() {

+		return pepConfig;

+	}

+

+	void setPdpEngineFactory(PDPEngineFactory pdpEngineFactory) {

+		this.pdpEngineFactory = pdpEngineFactory;

+	}

+

+	void setPepConfig(PepConfig pepConfig) {

+		this.pepConfig = pepConfig;

+	}

+

+	void setXacmlProperties(Properties properties) {

+		this.xacmlProperties = properties;

+	}

+

+	void setObligationHandlers(List<ObligationStoreAware> obligationHandlers) {

+		if(obligationHandlers != null) {

+			this.obligationHandlers = new ArrayList<ObligationStoreAware>();

+			this.obligationHandlers.addAll(obligationHandlers);

+		}

+	}

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepAgentFactory.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepAgentFactory.java
new file mode 100755
index 0000000..bcff6fd
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepAgentFactory.java
@@ -0,0 +1,59 @@
+package org.openliberty.openaz.pepapi.std;

+

+import com.att.research.xacml.api.pdp.PDPEngineFactory;

+import com.att.research.xacml.util.FactoryException;

+import org.openliberty.openaz.pepapi.*;

+

+import java.util.List;

+import java.util.Properties;

+

+

+public class StdPepAgentFactory implements PepAgentFactory {

+	

+	private volatile PepAgent pepAgent;

+

+	private PDPEngineFactory pdpEngineFactory;

+

+	private Properties xacmlProperties;

+

+	private PepConfig pepConfig;

+

+	private List<ObligationStoreAware> obligationHandlers;

+

+	public StdPepAgentFactory(String propertyFile) {

+		this(PepUtils.loadProperties(propertyFile));

+	}

+

+	public StdPepAgentFactory(Properties properties) {

+		this.xacmlProperties = properties;

+		this.pepConfig = new StdPepConfig(properties);

+		try {

+			//FIXME: Error when invoking newInstance() with properties.

+			pdpEngineFactory = PDPEngineFactory.newInstance();

+		} catch (FactoryException e) {

+			throw new PepException(e);

+		}

+	}

+

+	@Override

+	public PepAgent getPepAgent() {

+		if(pepAgent == null) {

+			synchronized(this) {

+				if(this.pepAgent == null) {

+					StdPepAgent pa = new StdPepAgent();

+					pa.setPepConfig(pepConfig);

+					pa.setXacmlProperties(xacmlProperties);

+					pa.setPdpEngineFactory(pdpEngineFactory);

+					pa.setObligationHandlers(obligationHandlers);

+					pa.initialize();

+					pepAgent = pa;

+				}

+			}

+		}

+		return pepAgent;

+	}

+

+	public void setObligationHandlers(List<ObligationStoreAware> obligationHandlers) {

+		this.obligationHandlers = obligationHandlers;

+	}

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepConfig.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepConfig.java
new file mode 100755
index 0000000..7aee915
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepConfig.java
@@ -0,0 +1,144 @@
+package org.openliberty.openaz.pepapi.std;

+

+import com.att.research.xacml.api.XACML3;

+import com.google.common.base.Splitter;

+import org.apache.commons.lang3.StringUtils;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.openliberty.openaz.pepapi.PepConfig;

+import org.openliberty.openaz.pepapi.PepResponseBehavior;

+

+import java.util.ArrayList;

+import java.util.Collections;

+import java.util.List;

+import java.util.Properties;

+

+

+public final class StdPepConfig implements PepConfig {

+

+	private static final Log logger = LogFactory.getLog(StdPepConfig.class);

+

+	private static final String PEP_ISSUER = "pep.issuer";

+

+	private static final String PEP_DEFAULT_SUBJECT_ID = "pep.subject.id";

+

+	private static final String PEP_DEFAULT_ACTION_ID = "pep.action.id";

+

+	private static final String PEP_DEFAULT_RESOURCE_ID = "pep.resource.id";

+

+	private static final String PEP_INDETERMINATE_BEHAVIOR = "pep.indeterminate.behavior";

+

+	private static final String PEP_NOTAPPLICABLE_BEHAVIOR = "pep.notapplicable.behavior";

+

+	private static final String PEP_MAPPER_CLASSES = "pep.mapper.classes";

+

+	private String issuer;

+

+	private String subjectIdURI;

+

+	private String actionIdURI;

+

+	private String resourceIdURI;

+

+	private PepResponseBehavior indeterminateBehavior;

+

+	private PepResponseBehavior notApplicableBehavior;

+

+	private List<String> mapperClassNames;

+

+	public StdPepConfig() {

+		//Defaults

+		subjectIdURI = XACML3.ID_SUBJECT_SUBJECT_ID.stringValue();

+		actionIdURI = XACML3.ID_ACTION_ACTION_ID.stringValue();

+		resourceIdURI = XACML3.ID_RESOURCE_RESOURCE_ID.stringValue();

+		indeterminateBehavior = PepResponseBehavior.THROW_EXCEPTION;

+		notApplicableBehavior = PepResponseBehavior.RETURN_NO;

+		mapperClassNames = Collections.EMPTY_LIST;

+	}

+

+	public StdPepConfig(Properties properties) {

+		this();

+		issuer = properties.getProperty(PEP_ISSUER);

+

+		String subjectIdURI = properties.getProperty(PEP_DEFAULT_SUBJECT_ID);

+		if(!StringUtils.isEmpty(subjectIdURI)){

+			this.subjectIdURI = subjectIdURI;

+		}

+

+		String actionIdURI = properties.getProperty(PEP_DEFAULT_ACTION_ID);

+		if(!StringUtils.isEmpty(actionIdURI)) {

+			this.actionIdURI = actionIdURI;

+		}

+

+		String resourceIdURI = properties.getProperty(PEP_DEFAULT_RESOURCE_ID);

+		if(!StringUtils.isEmpty(resourceIdURI)) {

+			this.resourceIdURI = resourceIdURI;

+		}

+

+		String indeterminateString = properties.getProperty(PEP_INDETERMINATE_BEHAVIOR);

+		if(!StringUtils.isEmpty(indeterminateString)) {

+			PepResponseBehavior indeterminateBehavior = PepResponseBehavior.valueOf(indeterminateString);

+			if(indeterminateBehavior == null) {

+				logger.error("Invalid indeterminate behavior found in configuration.");

+				//TODO: Throw exception ?

+			}

+			this.indeterminateBehavior = indeterminateBehavior;

+		}

+

+		String notapplicableString = properties.getProperty(PEP_NOTAPPLICABLE_BEHAVIOR);

+		if(!StringUtils.isEmpty(notapplicableString)) {

+			PepResponseBehavior notApplicableBehavior = PepResponseBehavior.valueOf(notapplicableString);

+			if(notApplicableBehavior == null) {

+				logger.error("Invalid notapplicable behavior found in configuration.");

+				//TODO: Throw exception ?

+			}

+			this.notApplicableBehavior = notApplicableBehavior;

+		}

+

+

+		String mapperClassNameString = properties.getProperty(PEP_MAPPER_CLASSES);

+		if(!StringUtils.isEmpty(mapperClassNameString)) {

+			List mapperClassNames = new ArrayList<String>();

+			for(String className: Splitter.on(",").omitEmptyStrings().trimResults().split(mapperClassNameString)) {

+				mapperClassNames.add(className);

+			}

+			this.mapperClassNames = Collections.unmodifiableList(mapperClassNames);

+		}

+

+	}

+

+	@Override

+	public String getIssuer() {

+		return issuer;

+	}

+

+	@Override

+	public String getDefaultSubjectId() {

+		return subjectIdURI;

+	}

+

+	@Override

+	public String getDefaultResourceId() {

+		return resourceIdURI;

+	}

+

+	@Override

+	public String getDefaultActionId() {

+		return actionIdURI;

+	}

+

+	@Override

+	public PepResponseBehavior getIndeterminateBehavior() {

+		return indeterminateBehavior;

+	}

+

+	@Override

+	public PepResponseBehavior getNotApplicableBehavior() {

+		return notApplicableBehavior;

+	}

+

+	@Override

+	public List<String> getMapperClassNames() {

+		return mapperClassNames;

+	}

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepRequest.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepRequest.java
new file mode 100755
index 0000000..3b08374
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepRequest.java
@@ -0,0 +1,91 @@
+package org.openliberty.openaz.pepapi.std;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.Request;
+import com.att.research.xacml.std.StdMutableRequest;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.openliberty.openaz.pepapi.*;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+
+final class StdPepRequest implements PepRequest {
+
+    private static final String REQUEST_ATTR_ID_PREFIX = "attributes";
+
+    private static final Log logger = LogFactory.getLog(StdPepRequest.class);
+
+    private final StdMutableRequest wrappedRequest;
+
+    private final Map<Identifier, PepRequestAttributes> pepRequestAttributesMapByCategory;
+
+    private final MapperRegistry mapperRegistry;
+
+    private final PepConfig pepConfig;
+
+    private final Object[] requestObjects;
+
+    private final AtomicInteger idCounter;
+
+    static StdPepRequest newInstance(PepConfig pepConfig, MapperRegistry mapperRegistry, Object[] requestObjects) {
+        StdPepRequest stdPepRequest = new StdPepRequest(pepConfig, mapperRegistry, requestObjects);
+        stdPepRequest.map();
+        return stdPepRequest;
+    }
+
+    /**
+     *
+     * @return
+     */
+    private String generateRequestAttributesXmlId() {
+        return REQUEST_ATTR_ID_PREFIX + idCounter.getAndIncrement();
+    }
+
+    private StdPepRequest(PepConfig pepConfig, MapperRegistry mapperRegistry, Object[] requestObjects) {
+        this.pepConfig = pepConfig;
+        this.mapperRegistry = mapperRegistry;
+        this.requestObjects = requestObjects;
+        this.pepRequestAttributesMapByCategory = new HashMap<Identifier, PepRequestAttributes>();
+        this.idCounter = new AtomicInteger(1);
+        this.wrappedRequest = new StdMutableRequest();
+    }
+
+    @Override
+    public PepRequestAttributes getPepRequestAttributes(Identifier categoryIdentifier) {
+        PepRequestAttributes pepRequestAttributes = pepRequestAttributesMapByCategory.get(categoryIdentifier);
+        if(pepRequestAttributes == null) {
+            String xmlId = generateRequestAttributesXmlId();
+            StdPepRequestAttributes p = new StdPepRequestAttributes(xmlId, categoryIdentifier);
+            p.setIssuer(pepConfig.getIssuer());
+            pepRequestAttributes = p;
+            pepRequestAttributesMapByCategory.put(categoryIdentifier, pepRequestAttributes);
+            wrappedRequest.add(pepRequestAttributes.getWrappedRequestAttributes());
+        }
+        return pepRequestAttributes;
+    }
+
+    private void map() {
+        if(requestObjects == null) {
+            throw new IllegalArgumentException("One or more arguments are null");
+        }
+        for(Object o: requestObjects) {
+            if(o == null) {
+                throw new IllegalArgumentException("One or more arguments are null");
+            }
+            ObjectMapper mapper = mapperRegistry.getMapper(o.getClass());
+            if(mapper == null) {
+                throw new IllegalArgumentException("No mappers found for class: " + o.getClass().getName());
+            }
+            mapper.map(o, this);
+        }
+    }
+
+    @Override
+    public Request getWrappedRequest() {
+        return wrappedRequest;
+    }
+
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepRequestAttributes.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepRequestAttributes.java
new file mode 100755
index 0000000..40a0409
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepRequestAttributes.java
@@ -0,0 +1,125 @@
+package org.openliberty.openaz.pepapi.std;

+

+import com.att.research.xacml.api.Identifier;

+import com.att.research.xacml.api.RequestAttributes;

+import com.att.research.xacml.api.XACML3;

+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.StdMutableRequestAttributes;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.openliberty.openaz.pepapi.PepRequestAttributes;

+

+import java.net.URI;

+import java.util.Date;

+import java.util.HashMap;

+import java.util.Map;

+

+

+final class StdPepRequestAttributes implements PepRequestAttributes {

+	

+	private static final Log log = LogFactory.getLog(StdPepRequestAttributes.class);

+

+	private final String id;

+

+	private final Identifier categoryIdentifier;

+

+	private String issuer;

+

+	private StdMutableRequestAttributes wrappedRequestAttributes;

+

+	//Internal map to hold mutable attributes as StdMutableRequestAttributes

+	// does not return a mutable view of Attributes.

+	private Map<Identifier, StdMutableAttribute> attributeMapById;

+

+	StdPepRequestAttributes(String id, Identifier categoryIdentifier) {

+		this.id = id;

+		this.categoryIdentifier = categoryIdentifier;

+		this.attributeMapById = new HashMap<Identifier, StdMutableAttribute>();

+		this.wrappedRequestAttributes =  new StdMutableRequestAttributes();

+		this.wrappedRequestAttributes.setCategory(categoryIdentifier);

+		this.wrappedRequestAttributes.setXmlId(id);

+	}

+

+	@Override

+	public Identifier getCategory() {

+		return categoryIdentifier;

+	}

+

+	@Override

+	public void addAttribute(String name, Date... values) {

+		addAttribute(name, values, XACML3.ID_DATATYPE_DATE);

+	}

+

+	@Override

+	public void addAttribute(String name, String... values) {

+		addAttribute(name, values, XACML3.ID_DATATYPE_STRING);

+	}

+

+	@Override

+	public void addAttribute(String name, Integer... values) {

+		addAttribute(name, values, XACML3.ID_DATATYPE_INTEGER);

+	}

+

+	@Override

+	public void addAttribute(String name, Boolean... values) {

+		addAttribute(name, values, XACML3.ID_DATATYPE_BOOLEAN);

+	}

+

+	@Override

+	public void addAttribute(String name, Long... values) {

+		addAttribute(name, values, XACML3.ID_DATATYPE_INTEGER);

+	}

+

+	@Override

+	public void addAttribute(String name, Double... values) {

+		addAttribute(name, values, XACML3.ID_DATATYPE_DOUBLE);

+	}

+

+	@Override

+	public void addAttribute(String name, URI... values) {

+		addAttribute(name, values, XACML3.ID_DATATYPE_ANYURI);

+	}

+

+	private <T> void addAttribute(String name, T[] values, Identifier dataTypeId) {

+		if(values == null) {

+			throw new IllegalArgumentException("Null attribute value provided for attribute: " + name);

+		}

+		Identifier attributeId = new IdentifierImpl(name);

+		StdMutableAttribute mutableAttribute = attributeMapById.get(attributeId);

+		if(mutableAttribute == null) {

+			mutableAttribute = new StdMutableAttribute();

+			mutableAttribute.setAttributeId(new IdentifierImpl(name));

+			mutableAttribute.setCategory(categoryIdentifier);

+			mutableAttribute.setIncludeInResults(false);

+			mutableAttribute.setIssuer(issuer == null?"":issuer);

+			attributeMapById.put(attributeId, mutableAttribute);

+			wrappedRequestAttributes.add(mutableAttribute);

+		}

+		for(T value: values) {

+			if(value != null) {

+				mutableAttribute.addValue(new StdAttributeValue<T>(dataTypeId, value));

+			}

+		}

+	}

+

+	@Override

+	public RequestAttributes getWrappedRequestAttributes() {

+		return wrappedRequestAttributes;

+	}

+

+	@Override

+	public String getId() {

+		return id;

+	}

+

+	public String getIssuer() {

+		return issuer;

+	}

+

+	public void setIssuer(String issuer) {

+		this.issuer = issuer;

+	}

+

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepRequestFactory.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepRequestFactory.java
new file mode 100755
index 0000000..a6a81b9
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepRequestFactory.java
@@ -0,0 +1,40 @@
+package org.openliberty.openaz.pepapi.std;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.openliberty.openaz.pepapi.MapperRegistry;

+import org.openliberty.openaz.pepapi.PepConfig;

+import org.openliberty.openaz.pepapi.PepRequest;

+import org.openliberty.openaz.pepapi.PepRequestFactory;

+

+import java.util.List;

+

+

+final class StdPepRequestFactory implements PepRequestFactory {

+	

+	private static final Log logger = LogFactory.getLog(StdPepRequestFactory.class);

+

+	private final PepConfig pepConfig;

+

+	private final MapperRegistry mapperRegistry;

+

+	/**

+	 *

+	 * @param pepConfig

+	 */

+	StdPepRequestFactory(PepConfig pepConfig, MapperRegistry mapperRegistry) {

+		this.pepConfig = pepConfig;

+		this.mapperRegistry = mapperRegistry;

+	}

+

+	@Override

+	public PepRequest newPepRequest(Object[] objects) {

+		return StdPepRequest.newInstance(pepConfig, mapperRegistry, objects);

+	}

+

+	@Override

+	public PepRequest newBulkPepRequest(List<?> associations, Object[] objects) {

+		return MultiRequest.newInstance(pepConfig, mapperRegistry, associations, objects);

+	}

+

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepResponse.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepResponse.java
new file mode 100755
index 0000000..2a19d30
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepResponse.java
@@ -0,0 +1,127 @@
+package org.openliberty.openaz.pepapi.std;

+

+import com.att.research.xacml.api.*;

+import com.att.research.xacml.api.Attribute;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.openliberty.openaz.pepapi.Advice;

+import org.openliberty.openaz.pepapi.Obligation;

+import org.openliberty.openaz.pepapi.*;

+

+import java.util.ArrayList;

+import java.util.Collection;

+import java.util.HashMap;

+import java.util.Map;

+

+

+final class StdPepResponse implements PepResponse {

+	

+	private static final Log logger = LogFactory.getLog(StdPepResponse.class);

+	

+	private final Result wrappedResult;

+

+	private final PepConfig pepConfig;

+

+	private final ObligationRouter obligationRouter;

+

+	static PepResponse newInstance(PepConfig pepConfig, ObligationRouter obligationRouter, Result result) {

+		return new StdPepResponse(pepConfig, obligationRouter, result);

+	}

+

+	private StdPepResponse(PepConfig pepConfig, ObligationRouter obligationRouter, Result result) {

+		this.pepConfig = pepConfig;

+		this.wrappedResult = result;

+		this.obligationRouter = obligationRouter;

+	}

+

+	@Override

+	public boolean allowed() throws PepException {

+		if(obligationRouter != null) {

+			obligationRouter.routeObligations(getObligations());

+		}

+		switch(wrappedResult.getDecision()) {

+			case PERMIT:

+				return true;

+			case DENY:

+				return false;

+			case NOTAPPLICABLE:

+				return enforceBehavior(pepConfig.getNotApplicableBehavior(), "Not Applicable");

+			//TODO: Handle various indeterminate status codes.

+			case INDETERMINATE:

+			case INDETERMINATE_DENY:

+			case INDETERMINATE_DENYPERMIT:

+			case INDETERMINATE_PERMIT:

+				Status status = wrappedResult.getStatus();

+				String formatted = String.format("Decision: Indeterminate, Status Code: %s, Status Message: %s",

+						status.getStatusCode(), status.getStatusMessage());

+				logger.error(formatted);

+				throw new PepException(formatted);

+			default:

+				throw new PepException("Invalid response from PDP");

+		}

+	}

+	

+	@Override

+	public Map<String, Obligation> getObligations() throws PepException {

+		Map<String, Obligation> obligationMap = new HashMap<String, Obligation>();

+		for(com.att.research.xacml.api.Obligation wrappedObligation: wrappedResult.getObligations()) {

+			Obligation obligation = new StdObligation(wrappedObligation);

+			obligationMap.put(obligation.getId(), obligation);

+		}

+		return obligationMap;

+	}

+

+	@Override

+	public Map<String, Advice> getAdvices() throws PepException {

+		Map<String, Advice> adviceMap = new HashMap<String, Advice>();

+		for(com.att.research.xacml.api.Advice wrappedAdvice: wrappedResult.getAssociatedAdvice()) {

+			Advice advice = new StdAdvice(wrappedAdvice);

+			adviceMap.put(advice.getId(), advice);

+		}

+		return adviceMap;

+	}

+

+	@Override

+	public Object getAssociation() throws PepException {

+		return null;

+	}

+

+	@Override

+	public Collection<Attribute> getAttributes() {

+		Collection<Attribute> attributes = new ArrayList<Attribute>();

+		for(AttributeCategory category: wrappedResult.getAttributes()) {

+			attributes.addAll(category.getAttributes());

+		}

+		return attributes;

+	}

+

+	@Override

+	public Map<Identifier, Collection<Attribute>> getAttributesByCategory() {

+		Map<Identifier, Collection<Attribute>> attributesByCategory = new HashMap<Identifier, Collection<Attribute>>();

+		for(AttributeCategory category: wrappedResult.getAttributes()) {

+			attributesByCategory.put(category.getCategory(), category.getAttributes());

+		}

+		return attributesByCategory;

+	}

+

+	@Override

+	public Result getWrappedResult() {

+		return wrappedResult;

+	}

+

+	private boolean enforceBehavior(

+			PepResponseBehavior pepResponseBehavior, String decision) throws PepException {

+		switch (pepResponseBehavior) {

+			case RETURN_YES:

+				return true;

+			case RETURN_NO:

+				return false;

+			case THROW_EXCEPTION:

+				logger.info("Throwing an exception as per configured behavior for decision: " + decision);

+				throw new PepException("Exception being thrown based on configured " +

+		        		"behavior for decision: " + decision);

+			default:

+				throw new PepException("Invalid PepResponseBehavior");

+		}

+	}

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepResponseFactory.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepResponseFactory.java
new file mode 100755
index 0000000..627f80e
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepResponseFactory.java
@@ -0,0 +1,29 @@
+package org.openliberty.openaz.pepapi.std;

+

+import com.att.research.xacml.api.Result;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.openliberty.openaz.pepapi.ObligationRouter;

+import org.openliberty.openaz.pepapi.PepConfig;

+import org.openliberty.openaz.pepapi.PepResponse;

+import org.openliberty.openaz.pepapi.PepResponseFactory;

+

+

+final class StdPepResponseFactory implements PepResponseFactory {

+    

+	private static final Log logger = LogFactory.getLog(StdPepResponseFactory.class);

+

+	private PepConfig pepConfig;

+	

+	private ObligationRouter obligationRouter;

+

+	StdPepResponseFactory(PepConfig pepConfig, ObligationRouter obligationRouter) {

+		this.pepConfig = pepConfig;

+		this.obligationRouter = obligationRouter;

+	}

+	

+	@Override

+	public PepResponse newPepResponse(Result result) {

+		return StdPepResponse.newInstance(pepConfig, obligationRouter, result);

+	}

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/SubjectMapper.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/SubjectMapper.java
new file mode 100755
index 0000000..82c4bee
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/SubjectMapper.java
@@ -0,0 +1,22 @@
+package org.openliberty.openaz.pepapi.std;
+
+
+import org.openliberty.openaz.pepapi.Subject;
+
+/**
+ * Created by ajith on 12/11/14.
+ */
+public class SubjectMapper extends CategoryContainerMapper {
+
+    public SubjectMapper() {
+        super(Subject.class);
+    }
+
+    @Override
+    protected String resolveAttributeId(String attributeId) {
+        if(attributeId.equals(Subject.SUBJECT_ID_KEY)) {
+            return getPepConfig().getDefaultSubjectId();
+        }
+        return attributeId;
+    }
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ThreadLocalObligationStore.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ThreadLocalObligationStore.java
new file mode 100755
index 0000000..2c1d981
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ThreadLocalObligationStore.java
@@ -0,0 +1,96 @@
+package org.openliberty.openaz.pepapi.std;

+

+

+import org.openliberty.openaz.pepapi.Obligation;

+import org.openliberty.openaz.pepapi.ObligationStore;

+

+import java.util.Collections;

+import java.util.HashSet;

+import java.util.Map;

+import java.util.Map.Entry;

+import java.util.Set;

+

+/**

+ * Acts as a store for Obligation instances in the current thread of execution.

+ * 

+ * @author Ajith Nair, David Laurance, Darshak Kothari

+ * 

+ */

+public final class ThreadLocalObligationStore implements ObligationStore {

+	

+	private static final ThreadLocal<Map<Class<?>, Set<Obligation>>> obligationMapContainer =

+			new ThreadLocal<Map<Class<?>, Set<Obligation>>>();

+	

+	private ThreadLocalObligationStore(){}

+	

+	public static ThreadLocalObligationStore newInstance() {

+		return new ThreadLocalObligationStore();

+	}

+	

+	/**

+	 * Set Obligations for the current thread of execution.

+	 * 

+	 * @param obligationMap	a <code>Map</code> containing <code>Obligation</code> instances keyed by ObligationHandler Class.

+	 */

+	void setObligations(Map<Class<?>, Set<Obligation>> obligationMap) {

+		if(obligationMap != null && !obligationMap.isEmpty()) {

+			obligationMapContainer.set(Collections.unmodifiableMap(obligationMap));

+		}else {

+			obligationMapContainer.set(null);

+		}

+	}

+	

+	/**

+	 * Returns all obligations in the current thread of execution. 

+	 * 

+	 * @return	a <code>Set</code> of <code>Obligation</code> instances.

+	 */

+	public Set<Obligation> getAllObligations() {

+		Set<Obligation> allObligations = new HashSet<Obligation>();

+		Map<Class<?>, Set<Obligation>> obligationMap = obligationMapContainer.get();

+		if(obligationMap != null){

+			for(Entry<Class<?>, Set<Obligation>> e: obligationMap.entrySet()){

+				allObligations.addAll(e.getValue());

+			}

+		}

+		return allObligations;

+	}

+	

+	/**

+	 * Returns all obligations that the given ObligationHandler can handle, in the current thread of execution.

+	 * 

+	 * @param oHandlerClass

+	 * @return a <code>Set</code> of <code>Obligation</code> instances.

+	 */

+	@Override

+	public Set<Obligation> getHandlerObligations(Class<?> oHandlerClass) {

+		Set<Obligation> obligations = new HashSet<Obligation>();

+		Map<Class<?>, Set<Obligation>> obligationMap = obligationMapContainer.get();

+		if(obligationMap != null && obligationMap.get(oHandlerClass) != null){

+			obligations.addAll(obligationMap.get(oHandlerClass));

+		}

+		return obligations;

+	}

+	

+

+	@Override

+	public Obligation getHandlerObligationById(Class<?> oHandlerClass,

+			String obligationId) {

+		Set<Obligation> obligations = getHandlerObligations(oHandlerClass);

+		if(obligations != null){

+			for(Obligation obligation: obligations){

+				if(obligation.getId().equals(obligationId)){

+					return obligation;

+				}

+			}

+		}

+		return null;

+	}

+	

+	/**

+	 * Clear all obligations in the current thread.

+	 */

+	void clear() {

+		obligationMapContainer.remove();

+	}

+}

diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/package.html b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/package.html
new file mode 100755
index 0000000..a9013f8
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/package.html
@@ -0,0 +1,1058 @@
+<html>

+<body>

+This package is the 

+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/pep/package-summary.html"

+>OpenAz reference "implementation"</a>

+of the OpenAz 

+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/azapi/pep/package-summary.html"

+>"PepApi interface package"</a>,

+and therefore generally contains implementation classes

+and only implementation-specific interfaces, also included is a

+<a href="#tutorial">PepApi tutorial</a> that describes the approach

+to building a PepApi implementation for a specific authorization

+provider, as well as a 2nd <a href="#tutorialmappers">Mapper tutorial</a>

+that describes the overall approach to writing mappers.

+<p>

+The goal of this package is twofold:

+<ul>

+<li>The primary goal is to provide a reference implementation of PepApi

+that uses an AzApi-based authorization provider, which in this case is the

+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/pdp/provider/SimpleConcreteSunXacmlService.html"

+>SimpleConcreteSunXacmlService</a>, 

+which is the SunXacml PDP wrapped in an

+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/pdp/package-summary.html"

+>implementation of the AzApi interface</a>.

+<li>The secondary goal is to provide a reference framework, which other

+providers can use as a model for implementation strategy of both AzApi

+and non-AzApi based authorization providers.

+</ul>

+

+In order to support the 2nd objective, the following is a high level

+"tutorial" about the PepApi and this implementation of it. At present,

+this tutorial is in preliminary form, however, even in the current

+state, the information may prove useful to anyone who is interested in

+developing an implementation of PepApi.

+

+<a name="tutorial"><H2>OpenAz PepApi Implementation Tutorial (v113)</H2></a>

+<H3>Contents</H3>

+<ul>

+<li><a href="#highleveloverview">High Level Overview</a>

+<li><a href="#sixlayerlist">List of Six OpenAz Layers</a>

+<li><a href="#separationapispi">Separation of PepApi to application API 

+and provider SPI</a>

+<li><a href="#highlevelsepapispi">High Level Overview API/SPI Separation</a>

+<li><a href="#detailsepapispi">Detail list of API/SPI separated methods</a>

+<li><a href="#pepapilayer">Appl client PepApi "API LAYER"</a>

+<li><a href="#suggestedspiapproaches">Suggested approaches for XyzApi provider SPI implementation</a>

+<li><a href="#pepapiseqmodel">PepApi Object Sequence Model</a>

+<li><a href="#somediscussion">Some discussion items</a>

+<ul>

+<li><a href="#basicpattern">Basic Processing Pattern</a>

+<li><a href="#highlowinterfacHigh Level and Low Level Interface Layers</a>

+<li><a href="#basicpurpose">Basic Purpose of PepApi</a>

+<li><a href="#standardpdps">Standard PDPs</a>

+<li><a href="#xacmlreps">Representations of XACML</a>

+<li><a href="#openazreleases">OpenAz Release Philosophy</a>

+<li><a href="#thesixlayersdisc">The Six Layers</a>

+<li><a href="#layer5disc">Layer 5: AzApi Impl</a>

+<li><a href="#azapivssunxacml">AzApi vs SunXacml</a>

+<li><a href="#canonicalform">Canonical Form</a>

+</ul>

+<li><a href="#tutorialmappers">Part II: Mappers Tutorial</a>

+</ul>

+

+<a name="highleveloverview">

+<H3>High Level Overview: Appl, PepApi, AzApi, AzProvider</H3></a>

+<p>

+To understand the "top level" picture of what is currently provided

+for implementations in the OpenAz project, we can identify six layers

+of operational modules (including "interfaces" as a layer). Each layer

+description starts with the identifier of a jar file in the OpenAz project

+that contains an implementation of the functionality described in the layer.

+<p>

+In addition, experience with OpenAz has shown, the PepApi is best represented

+as having 2 portions: an application-oriented API, and a provider-oriented SPI,

+which will be noted in the following list and explained further below.

+<p>

+The PepApi provider is primarily concerned with implementing Layer 3 in the

+list below. The other layers are generally provided either from the OpenAz site

+(layers 2,4 for interfaces, layer 1 for test code, layers 5,6 for sample

+AzApi impl and PDP), or from customer application environments (layer 1,

+when customer is ready to implement PepApi client), or from PDP vendors

+(layers 5 and 6). 

+<p>

+<a name="sixlayerlist"><H4>List of the Six OpenAz Module Layers</H4></a>

+<ul>

+<li><b>Layer 1:</b> 

+"<top-of-project>\openaz\test\build\openliberty-openaz-test.jar"

+<br>

+This layer is implemented by a package that contains sample test programs,

+and may be thought of as the "application layer", and generally only

+uses the "API" portion of PepApi. 

+For example, test.TestStyles, demonstrates various usage scenarios

+of PepApi. 

+ 

+<li><b>Layer 2:</b> "<top-of-project>

+"<top-of-project>\openaz\azapi\build\openliberty-openaz-azapi.jar"

+<br>

+This layer is implemented by a package that contains the actual 

+"PepApi interfaces" (API and SPI), and may be considered to be the second layer 

+of "modules", which, while not having any executable code, do control 

+what code can be compiled that is purported to "implement" the interface.

+(Note: Even though the jar file contains "azapi" in the name, 

+it also contains the "pepapi".)

+

+<li><b>Layer 3:</b>  

+"<top-of-project>\openaz\pep\build\openliberty-openaz-pep.jar"

+<br>

+This package contains an example implementation of the PepApi,

+and may be considered to be the "third layer" of OpenAz. 

+It also contains an implementation of an "AzApi client", i.e. a

+module that uses AzApi directly to make authorization decisions.

+As such, this layer may be considered to both implement a PepApi

+provider, as well as, in this case, an AzApi client, or in the more

+general, case a client to any request-response oriented 

+authorization provider.

+<br>

+In addition, this layer generally uses its own implementation of

+the SPI portion of PepApi, which facilitates its implementation 

+of the API portion.

+ 

+<li><b>Layer 4:</b> 

+"<top-of-project>\openaz\azapi\build\openliberty-openaz-azapi.jar"

+<br>

+This package contains the actual "interfaces" that comprise the AzApi, 

+and, in the same sense as the layer 2 PepApi above, may be considered

+to be a layer of modules that control compatibility with other

+modules, esp in layer 5. (Note: this is the same jar file as used

+by layer 2, i.e. it contains both sets of interfaces.)

+ 

+<li><b>Layer 5:</b> 

+"<top-of-project>\openaz\pdp\build\openliberty-openaz-pdp.jar"

+<br>

+This package contains an example implementation of AzApi, and may be 

+considered to be the "fifth layer" of OpenAz. Similarly to Layer 3,

+this package also contains a client implementation, where the client

+in this case is to the SunXacml PDP provider.

+ 

+<li><b>Layer 6:</b> 

+"<top-of-project>/pdp/lib/sunxacml.jar" 

+<br>

+This jar file contains the SunXacml PDP impl, which may be considered 

+as the sixth layer of modules in OpenAz.

+</ul>

+

+

+<a name="separationapispi">

+<H3>Separation of PepApi into API and SPI parts.</H3></a>

+This section first describes the approach at a high level, then

+provides a detailed review of the complete PepApi interface to

+designate the API and SPI parts of each PepApi interface.

+

+<a name="highlevelsepapispi">

+<H4>High level view of API/SPI separation</H4></a>

+The first thing that is probably useful to recognize is that the PepApi

+really consists of an application facing API plus an implementer's SPI

+(Service Provider Interface).

+If there is sufficient demand for a more formal separation, that will be

+considered in the future.

+<p>

+The following is a high level view of the API/SPI separation:

+<pre>

+      Consider the following functionality as being the main

+      part of each portion of the PepApi:

+

+      APPL API LAYER:

+

+	Use newPepRequest methods to build request

+	Use decide() method to make decision

+	Use allowed and next methods to look at results

+	Use getObligations, getObligationId, getStringValues to

+	     look at obligations within each result

+

+      PROVIDER SPI LAYER:

+

+	Take Appl Api Request and 

+	  submit as Authorization Provider Request

+

+	Take Authorization Provider Response objects and 

+	  process and return them as Appl Api Response objects

+

+

+      Summary of architecture:

+

+	Appl Client Impl

+	  PepApi Appl Client API 

+	  PepApi Provider SPI 

+	PepApi Provider Impl

+	  &lt;AzProvider&gt;API  {AzProvider = Az | Xyz}

+	&lt;AzProvider&gt; Impl

+

+

+	Current AzApi strategy:

+

+	        +--------------------+

+	        | Appl client (impl) |          <b><i>Layer 1</i></b>

+	        +--------------------+

+	              |       ^

+	              v       |

+	+-----------------------------------+

+	|   PepApi appl client api (intf)   |   <b><i>Layer 2</i></b>

+	| - - - - - - - - - - - - - - - - - |

+	|  PepApi provider api/spi (impl)   |   <b><i>Layer 3</i></b>

+	|   includes use of PepApi spi      |	

+	|         plus AzApi Client         |

+	+-----------------------------------+

+	           |             ^

+	           v             |

+	+-----------------------------------+

+	|      AzApi client api (intf)      |   <b><i>Layer 4</i></b>

+	| - - - - - - - - - - - - - - - - - |

+	|        AzApi provider (impl)      |   <b><i>Layer 5</i></b>

+	|        plus SunXacml client       |

+	+-----------------------------------+

+	           |             ^

+	           v             |

+	   +----------------------------+

+	   |  SunXacml provider (impl)  |       <b><i>Layer 6</i></b>

+	   +----------------------------+

+

+

+

+	Suggested strategy for an Xyz provider:

+

+	        +--------------------+

+	        | Appl client (impl) |          <b><i>Layer 1</i></b>

+	        +--------------------+

+	              |       ^

+	              v       |

+	+-----------------------------------+

+	|   PepApi appl client api (intf)   |   <b><i>Layer 2</i></b>

+	| - - - - - - - - - - - - - - - - - |

+	|  PepApi provider api/spi (impl)   |   <b><i>Layer 3</i></b>

+	| includes use of custom PepApi spi |	

+	|        plus XyzApi Client         |

+	+-----------------------------------+

+	           |             ^

+	           v             |

+	+-----------------------------------+

+	|     <i>XyzApi client api</i> (intf)      |   <b><i>Layer 4</i></b>

+	| - - - - - - - - - - - - - - - - - |

+	|       XyzApi provider (impl)      |   <b><i>Layers 5,6</i></b>

+	+-----------------------------------+

+

+

+</pre>

+Note: because in the XyzApi provider case, the "standard" api is effectively

+the XyzApi, itself, there is no need for the impl to act as a client to a

+different interface, and so layers 5 and 6 are effectively consolidated to

+a single logical layer.

+

+<a name="detailsepapispi">

+<H4>Detail list of API/SPI separated methods</H4></a>

+The following list of interfaces and methods describe the API/SPI

+separation. 

+<p>Note 

+<ul>

+<li>There are only a few interfaces and methods involved with

+the application-facing API, namely: 

+<ul>

+<li>PepRequestFactory

+<li>PepRequest

+<li>PepResponse

+<li>Obligation

+</ul>

+<li>All the PepApi interfaces are used and/or include methods that appear

+in the SPI portion.

+<li>Methods marked with "**" have AzApi-specific items in the interface

+that need to be addressed by non-AzApi implementations. In most cases,

+simply making the item null will satisfactorily address the situation for

+a non-AzApi implementation, however, it is likely that a corresponding

+element of the implementation will need to be used instead to fulfill

+the functional capability. For example, a non-AzApi impl will have no

+use for an AzRequestContext, however, it will likely have its own

+RequestContext that will need to be considered as an alternative which

+can be included in an extension class that has an additional provider-specific

+method.

+Note: items marked with "**" are followed by comment at end of line

+with number referring to the suggested approaches for these issues

+described at the end of the SPI detail section.

+</ul>

+

+<pre>

+   -------------------------------------------------------------------

+</pre>

+<a name="pepapilayer"><H4>   APPL CLIENT PepApi "API LAYER":</H4></a>

+<pre>

+<a name="apipepreqfact"><H5>Interface PepRequestFactory</H5></a>

+ 	PepRequest newPepRequest(

+		Object subjectObj, Object actionObj, 

+		Object resourceObj, Object environmentObj) 

+ 	PepRequest newPepRequest(

+		Object subjectObj, Object actionResourceObject,

+		Object environmentObj) 

+ 	PepRequest newPepRequest(

+		String subjectName, String actionId, 

+		String resourceId) 

+

+ 	PepRequest newBulkPepRequest(

+		Object subjectObj, List actionObjects, 

+		List resourceObjects, Object environmentObj) 

+ 	PepRequest newBulkPepRequest(

+		Object subjectObj, List actionResourceObjects, 

+		Object environmentObj) 

+

+ 	PepRequest newQueryPepRequest(

+		Object subjectObj, Object environmentObj, 

+		String scope, PepRequestQueryType queryType) 

+

+<a name="apipepreq"><H5>Interface PepRequest</H5></a>

+ 	PepResponse decide() 

+

+<a name="apipeprsp"><H5>Interface PepResponse</H5></a>

+	boolean allowed() 

+	Object getAction()

+	Object getResource()

+	Map&lt;String,Obligation&gt; getObligations() 

+	boolean next()

+

+<a name="apiobligation"><H5>Interface Obligation</H5></a>

+	String getObligationId() 

+	Map&lt;String,String&gt; getStringValues() 

+

+   -------------------------------------------------------------------

+</pre>

+<a name="pepspilayer"><H4>  PROVIDER PepApi "SPI LAYER":</H4></a>

+<pre>

+<a name="spipepreqfact"><H5>Interface PepRequestFactory</H5></a>

+   ** 	AzService getAzService() 	       // (#1) return null for non-AzApi

+

+	String getContainerName() 

+	String getProviderClassName() 

+

+	RequestAttributesFactory&lt;T&gt; getRequestAttributesFactory(T t)

+		&lt;T extends Enum&lt;T&gt; & AzCategoryId&gt;  

+	PepResponseFactory getResponseFactory() 

+ 

+ 	DecisionHandler getDecisionHandler() 

+	List&lt;PostDecisionHandler&gt; getPostDecisionHandlers() 

+	List&lt;PreDecisionHandler&gt; getPreDecisionHandlers() 

+

+<a name="spipepreq"><H5>Interface PepRequest</H5></a>

+   ** 	AzRequestContext getAzRequestContext()	// return null for non-AzApi

+

+	PepRequestFactory getPepRequestFactory() 

+

+	void setAccessSubject(Object subjectObject) 

+	void setResourceAction(Object resource, Object action) 

+	void setEnvironment(Object envObject) 

+	void setBulkResourceActions(List resourceObjects, List actionObjects) 

+

+ 	PepRequestOperation getOperation() 

+   ** 	Object getActionObject(AzResourceActionAssociation azRaa) 	// (#3)

+   **	Object getResourceObject(AzResourceActionAssociation azRaa) // (#3)

+

+ 	void setScope(String scope) 

+	String getScope() 

+

+ 	void setQueryReturnAllowed(boolean queryReturnAllowed) 

+ 	boolean isQueryForAllowedResults() 

+

+<a name="spijavaobjmap"><H5>Interface JavaObjectMapper:</H5></a>

+	Set&lt;Class&gt; getSupportedClasses() 

+

+	boolean canMapObject(Object obj) 

+

+	&lt;T extends Enum&lt;T&gt; & AzCategoryId&gt; 

+	RequestAttributes&lt;T&gt; map(

+		Object javaObject, 

+		RequestAttributes&lt;T&gt; azWrapperObject) 

+

+<a name="spireqattrfact">

+<H5>Interface RequestAttributesFactory&lt;T extends Enum&lt;T&gt; & AzCategoryId&gt;</H5></a>

+	RequestAttributes&lt;T&gt; createObject(PepRequest ctx) 

+ 	void setMappers(List&lt;JavaObjectMapper&gt; mappers) 

+	List&lt;JavaObjectMapper&gt; getMappers() 

+	Set&lt;Class&gt; getSupportedClasses() 

+ 

+<a name="spiattr">

+<H5>Interface Attributes&lt;T extends Enum&lt;T&gt; & AzCategoryId&gt;</H5></a>

+   **	AzEntity&lt;T&gt; getAzEntity()  // (#1) return null for non-AzApi

+

+<a name="spireqattr">

+<H5>Interface RequestAttributes&lt;T extends Enum&lt;T&gt; & AzCategoryId&gt;

+		extends Attributes&lt;T&gt;</H5></a>

+ 	PepRequest getPepRequest() 

+

+ 	void setAttribute(String name, Boolean value) 

+ 	void setAttribute(String name, Date date) 

+ 	void setAttribute(String name, Integer value) 

+ 	void setAttribute(String name, String value) 

+

+<a name="spidechnd"><H5>Interface DecisionHandler</H5></a>

+ 	PepResponse decide(PepRequest request) 

+<a name="spipredechnd"><H5>Interface PreDecisionHandler</H5></a>

+	void preDecide(PepRequest request)

+<a name="spipostdechnd"><H5>Interface PostDecisionHandler</H5></a>

+ 	void postDecide(PepRequest request, PepResponse response) 

+

+<a name="spipepreqrspfact"><H5>Interface PepResponseFactory:</H5></a>

+   **	PepResponse createPepResponse(

+		AzResponseContext responseContext, 	// (#1) pass null for non-AzApi

+		PepRequest pepRequest, 

+		PepRequestOperation operation) 

+

+   **	PepResponse createPepResponse(

+		Set&lt;AzResourceActionAssociation&gt; actionResourceAssociations, // (#3) 

+		PepRequest pepRequest, 

+		boolean queryAllowed) 

+ 

+ 	ObligationFactory   getObligationFactory() 

+

+	PepResponseBehavior getMissingAttributeBehavior() 

+	PepResponseBehavior getNotApplicableBehavior() 

+ 	PepResponseBehavior getProcessingErrorBehavior() 

+ 	PepResponseBehavior getSyntaxErrorBehavior() 

+

+ 	void setMissingAttributeBehavior(

+		PepResponseBehavior missingAttributeBehavior) 

+ 	void setNotApplicableBehavior(   

+		PepResponseBehavior notApplicableBehavior) 

+ 	void setProcessingErrorBehavior( 

+		PepResponseBehavior processingErrorBehavior) 

+ 	void setSyntaxErrorBehavior(     

+		PepResponseBehavior syntaxErrorBehavior)  

+

+<a name="spipeprsp"><H5>Interface PepResponse</H5></a>

+   **	AzResponseContext getAzResponseContext()  // (#1) return null for non-AzApi

+

+<a name="spioblfact"><H5>Interface ObligationFactory</H5></a>

+   **	Obligation createObject(AzEntity&lt;AzCategoryIdObligation&gt; entity) // (#2) pass null for non-AzApi 

+

+<a name="spiobl"><H5>Interface Obligation

+		extends ResponseAttributes&lt;AzCategoryIdObligation&gt;</H5></a>

+

+<a name="spirspattrfact">

+<H5>Interface ResponseAttributesFactory&lt;T extends Enum&lt;T&gt; & AzCategoryId&gt;</H5></a>

+   **	ResponseAttributes&lt;T&gt; createObject(AzEntity&lt;T&gt; entity) // (#2) pass null for non-AzApi

+

+<a name="spirspattr">

+<H5>Interface ResponseAttributes&lt;T extends Enum&lt;T&gt; & AzCategoryId&gt;

+		extends Attributes&lt;T&gt;</H5></a>

+

+   -------------------------------------------------------------------

+</pre>

+<a name="suggestedspiapproaches">

+<H4>Suggested approaches for XyzApi provider SPI implementation</H4></a>

+<pre>

+Note: these suggestions presume the Xyz provider is following the

+code structure in the org.openliberty.openaz.pep impl package

+and that the approach is to substitute Xyz request and response objects,

+and Xyz entity attribute collections for those provided by AzApi.

+The basic idea would be to have a parallel impl, for example: 

+org.openliberty.openaz.xyz, with basically the same set of classes,

+but with some of the following modifications considered.

+

+	1. return null for getAz&lt;object&gt;() in:

+		PepRequestFactory.getAzService()

+		PepRequest.getAzRequestContext()

+		Attributes&lt;T&gt;.getAzEntity()

+		PepResponse.getAzResponseContext()

+

+	2. Pass null for az&lt;object&gt; parameter in:

+		PepResponseFactory.createPepResponse(azResponseContext, ...)

+		ResponseAttributesFactory.createObject(azEntity)

+		ObligationFactory.createObject(azEntity)

+

+	3. Consider extending AzResourceActionAssociation as

+	   XyzResourceActionAssociation and use in the following:

+

+		PepRequest.getActionObject(AzResourceActionAssociation azRaa) 

+		PepRequest.getResourceObject(AzResourceActionAssociation azRaa) 

+

+		PepResponseFactory.createPepResponse(

+			Set&lt;AzResourceActionAssociation&gt; azRaas, 

+			PepRequest pepRequest, 

+			boolean queryAllowed) 

+

+	   AzResourceActionAssociation javadoc is here:

+	     http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/azapi/AzResourceActionAssociation.html

+

+	   Within XyzResourceActionAssociation extension return null for the 

+	   following AzApi-dependent methods:

+

+ 		AzResourceActionAssociation.getAzAction() 

+		AzResourceActionAssociation.getAzResource() 

+		AzResourceActionAssociation.getAzResourceActionAssociationId() 

+ 

+	   Add new XyzResourceActionAssociation method to return

+	   action and resource objects:

+

+		XyzObject getXyzAction()

+		XyzObject getXyzResource()

+

+	   Then the XyzResourceActionAssociation object can be used

+	   for correlation based on the XyzObject references for

+	   action and resource in the XyzPepRequestImpl that

+	   implement PepRequest, i.e.

+

+		PepRequest.getActionObject(XyzResourceActionAssociation xyzRaa) 

+		PepRequest.getResourceObject(XyzResourceActionAssociation xyzRaa) 

+

+	   Similarly for creating a collection of return objects

+	   in response to a query, the XyzPepResponseFactoryImpl

+	   should be able to pass:

+

+		PepResponseFactory.createPepResponse(

+			Set&lt;XyzResourceActionAssociation&gt; xyzRaas, 

+			PepRequest pepRequest, 

+			boolean queryAllowed) 

+

+	   although one needs to check if generics will allow this pass

+	   of a Set of subclasses of the class for which the interface

+	   is defined.

+

+</pre>

+<a name="pepapiseqmodel"><H3>PepApi Object sequence model</H3></a>

+The following section contains a quasi-sequence diagram that shows the

+relations between the components of the PepApi in approximate order of

+their invocation at runtime.

+<pre>

+

+	+------------------------------------------+

+	| PepRequestFactory                        |

+	|  PepReqFactImpl(azSvc) // impl azSvc set |

+	|  pr = newPepRequest                      |

+	|   |   (sObj,aObj,rObj,eObj)              |

+	|   | newPEPRequest(op)                    |

+	|   |   azReqCtx = azSvc.createAzReqCtx()  |

+	|   |   new PepReqImpl(azReqCtx, this, op) |

+	|   | setAccessSubject(sObj)               |

+	+---|--------------------------------------+

+	    |

+	    V 

+	+---------------------------------------------------------------+

+	| PepRequest                                                    |

+	|      PepReqImpl(azReqCtx, this, op) // set values from params |

+	|      setAccessSubject(subjObj)                                |

+	|       createAccessSubject(subjObj) //'Subject' implies &lt;T&gt;    |

+	|         subjFact = getPepReqFact.getReqAttrFact(catId&lt;T&gt;)     |

+	|    +<-- subjInit = subjFact.createObj(this)                   |

+	|    |    subjMapd = mapJavObject(subjObj, subjInit, subjFact)  |

+	|    |  mapJavaObject(subjObj, subjInit, subjFact)              |

+	|  +<---- mapper = subjFact.getMappers().next()                 |

+	|  | |    mapper.map(subjObj, subjInit)                         |

+	|+<--- decide()                                                 |

+	+|-|-|----------------------------------------------------------+

+	 | | |

+	 | | V

+	 | | +-----------------------------------------------------------+

+	 | | | SubjectFactory                                            |

+	 | | |   createObject(pr)                                        |

+	 | | |     azReqCtx = pr.getAzReqCtx()                           |

+	 | | |     azSubjInit = azReqCtx.createAzEntity(catIdSubj)       |

+	 | | |     azReqCtx.addAzEntity(azSubjInit)                      |

+	 | | | +<- return new Subject(azSubjInit, pr, this)              |

+	 | | +-|---------------------------------------------------------+

+	 | |   |

+	 | |   V

+	 | | +-----------------------------------------------------------+

+	 | | | Subject                                                   |

+	 | | |   Subject(azSubjInit, pr, subjFact)                       |

+	 | | | +<- super[RequestAttributes](azSubjInit, pr, subjFact)    |

+	 | | +-|---------------------------------------------------------+

+	 | |   |

+	 | |   V

+	 | | +-----------------------------------------------------------+

+	 | | | RequestAttributes                                         |

+	 | | |   RequestAttributes(azSubjInit, pr, subjFact)             |

+	 | | |     set this.pr, this.subjFact                            |

+	 | | | +<- super[Attributes](azSubjInit)                         |

+	 | | +-|---------------------------------------------------------+

+	 | |   |

+	 | |   V

+	 | | +-----------------------------------------------------------+

+	 | | | Attributes                                                |

+	 | | |   Attributes(azSubjInit)                                  |

+	 | | |     this.azEntity = azSubjInit                            |

+	 | | +-----------------------------------------------------------+

+	 | | 

+	 | V 

+	 | +-----------------------------------------------------------+

+	 | | JavaObjectMapper                                          |

+	 | |   map(subjObj, reqAttrSubjInit)                           |

+	 | |     convertObj(subjObj, reqAttrSubjInit)                  |

+	 | |       attrId = getVocab(subjObj)                          |

+	 | |   +<- reqAttrSubjInit.setAttribute(attrId, subjObj)       |

+	 | +---|-------------------------------------------------------+

+	 |     |

+	 |     V 

+	 | +-----------------------------------------------------------+

+	 | | RequestAttributes                                         |

+	 | |   setAttribute(attrId, subjObj)                           |

+	 | |     azEntity.createAzAttribute(issuer, attrId,            |

+	 | |       azEntity.createAzAttributeValue(azDataTyp, subjObj) |

+	 | +-----------------------------------------------------------+

+	 | 

+	 V 

+	+----------------------------------------------------------+

+	| DecisionHandler                                          |

+	|   decide(pepReq)                                         |

+	|     azRspCtx = azSvc.decide(pepReq.getAzReqCtx()         |

+	| +<- pepRspFact = pepReq.getPepReqFact.getRspFact()       |

+	| |   pepRsp = pepRspFact.createPepRsp(azRspCtx,pepReq,op) |                        |

+	| |   return pepRsp                                        |

+	+-|--------------------------------------------------------+

+	  |

+	  V

+	+----------------------------------------------------------+

+	| PepResponseFactory                                       |

+	|   createPepRsp(azRspCtx,pepReq,op)                       |

+	| +<- pepRsp = new PepRspImpl(azRspCtx, pepReq, this, op)  |

+	| |   return pepRsp                                        |

+	+-|--------------------------------------------------------+

+	  |

+	  V

+	+----------------------------------------------------------+

+	| PepResponse                                              |

+	|   PepRspImpl(azRspCtx,pepReq,pepRspFact,op)              |

+	|    set this.azRspCtx,this.pepReq,this.pepRspFact,this.op |

+	|    this.azResultIterator = azRspCtx.getRslts.iterator()  |

+	|   allowed()                                              |

+	|   next()  // point to next azResult                      |

+	|     curAzResult = azResultIterator.next()                |

+	|   getResource(), getAction()                             |

+	|     azRaa = this.getAzResourceActionAssociation()        |

+	|     resObj = this.getPepReq.getResourceObject(azRaa)     |

+	|     return resObj                                        |

+	|   getObligations()                                       |

+	|     curAzObls = curAzResult.getAzObligations()           |

+	|     curAzObl = curAzObls.next()                          |

+	|     oblFact = this.getRspFact.getOblFact()               |

+	|     Obligation pepObl = oblFact.createObject(curAzObl)   |

+	+-|--------------------------------------------------------+

+	  |

+	  V

+	+----------------------------------------------------------+

+	| ObligationFactory                                        |

+	|   createObject(azObligation)                             |

+	| +<- return new Obligation(azObligation)                  |

+	+----------------------------------------------------------+

+	  |

+	  V

+	+-----------------------------------------------------------+

+	| Obligation                                                |

+	|   Obligation(azObligaion)                                 |

+	| +<- super[ResponseAttributes](azObligation)               |

+	+-|---------------------------------------------------------+

+	  |

+	  V

+	+-----------------------------------------------------------+

+	| ResponseAttributes                                        |

+	|   ResponseAttributes(azObligation)                        |

+	| +<- super[Attributes](azObligation)                       |

+	+-|---------------------------------------------------------+

+	  |

+	  V

+	+-----------------------------------------------------------+

+	| Attributes                                                |

+	|   Attributes(azObligation)                                |

+	|     this.azEntity = azObligation                          |

+	+-----------------------------------------------------------+

+

+

+</pre>

+

+<a name="somediscussion"><h3>Some discussion items</h3></a>

+

+<a name="basicpattern"><h4>Basic Processing Pattern</h4></a>

+The basic pattern is that the "container" of applications provides

+both checking requests before the application receives them, and

+checking requests in the process of application execution, where

+it is necessary to determine if the current user has sufficient

+authorization established to continue the current operation.

+<p>

+

+<a name="highlowinterfaces">

+<h4>High Level and Low Level Interface Layers</h4></a>

+PepApi is a "high level interface" intended to be totally flexible

+in terms of the applications and containers that can use it, and

+to also be "easy to use", comparable to existing platform-specific

+authorization models, such as J2SE checkPermission and WebLogic

+isAccessAllowed.

+<p>

+By contrast, AzApi is a "low level interface" intended to provide

+a Java binding to the more general platform independent XACML

+authorization model, which provides a general interface consisting

+of a collection of collections of "canonical" Attributes that contain

+both Attribute metadata and AttributeValues.

+<p>

+

+<a name="basicpurpose"><h4>Basic Purpose of PepApi</h4></a>

+Therefore, the intended purpose of a PepApi Impl, for example,

+this package ({@link org.openliberty.openaz.pep}), is

+to provide a "mapping" from the simple, application-friendly, PepApi

+that the applications (and containers) use, to the more complex

+AzApi, that the container would then typically use

+to submit requests to standard XACML PDPs.

+<p>

+

+<a name="standardpdps"><h4>Standard PDPs</h4></a>

+"Standard XACML PDPs" are accessed using the XACML 

+Request/Response protocol, which is described in the XACML 

+specifications using XML to represent the details. However, 

+implementations are not required to use XML, but they are

+required to maintain the semantics of XACML, which are normatively

+defined in the specifications using the XML representation.

+<p>

+

+<a name="xacmlreps"><h4>Representations of XACML</h4></a>

+Furthermore, the XACML specifications do not specify what

+representation is required in the PEP-PDP connection, so it is

+possible that one end is expecting to use XML and the other

+end is expecting to use some other serialization format of the

+same information. Therefore, interoperability is somewhat

+dependent on the "bindings" that XACML PEP and XACML PDPs have

+provided for support. In the absence of a match, it would be

+up to the vendors and/or enterprise system developers to either

+provide a translation module or to simply select another 

+product that would be compatible.

+<p>

+It is not a goal of either the XACML Technical Committee nor

+of the OpenAz project to attempt to resolve this issue, except

+on an as-needed basis to serve the purposes of implementations

+that are used within or want to integrate with the OpenAz Project.

+<p>

+So, for example, the initial release of OpenAz has, effectively,

+two "providers" for AzApi, the top level classes of which are:

+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/pdp/provider/SimpleConcreteDummyService.html">

+<b>SimpleConcreteDummyService</b></a> and 

+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/pdp/provider/SimpleConcreteSunXacmlService.html">

+<b>SimpleConcreteSunXacmlService</b></a>. 

+The former, the "dummy service",

+simply gives canned responses, and should be regarded as no more than

+a test tool, however, its existence as an independent "provider" may

+be useful for some types of demos.

+<p>

+

+<a name="openazreleases"><h4>OpenAz Release Philosophy</h4></a>

+To understand the working example in the "initial release of OpenAz"

+(which is the current release, which should be considered to be

+using the interfaces, i.e. AzApi and PepApi, in their "final form".

+The "final form" is "final" in the sense that until there is a critical

+mass (for example 3 implementations, including the current ref impl),

+fixes to "bugs" found in either API should be considered fair game.

+However, any "functionality" above and beyond what is currently

+represented as the functionality of those interfaces, should be

+considered candidates for a "second" or "next" release.)

+ 

+<a name="thesixlayersdisc"><H4>The Six Layers</H4></a>

+One may think of the 6 layers as kind of a "stepladder" of mapping

+the Objects from the local form within the application (Layer 1) to the 

+canonical form within AzApi (Layer 5).

+<p>

+

+<a name="layer5disc"><H5>Layer 5: AzApi Impl</H5></a>

+Then, from the AzApi impl (layer 5) the canonical form objects may

+be mapped a 2nd time into the local object form required by the 

+XACML PDP.

+

+From the perspective of the six layers, we can examine some of the

+possible "usage scenarios" for OpenAz. It turns out that there

+really are two major pieces of standardization that OpenAz facilitates:

+

+<ul>

+<li> First is the upper level "PepApi" (layer two), which provides

+a standard Java interface to application environments, regardless

+of the specific Objects the applications pass to PepApi. 

+

+<ul>

+<li>Note: It is "standard" in the sense that 

+applications do not have to be aware that

+what is done with the Objects when they are passed to PepApi.

+is that the Objects are "mapped" by the 

+layer 3 PepApi Impl to be used as input to the layer 4 AzApi

+interface.

+</ul>

+

+<li> Second is the lower level "AzApi" (layer four), which provides

+a standard Java interface to XACML PDPs.

+

+<ul>

+<li>Note: Again that the layer 5 AzApi Impl needs to generally

+"map" the AzApi objects to those of the XACML Impl.

+</ul> 

+</ul>

+

+The reason that layer 5 may need to do mapping is the existing

+XACML implementations, in general, will not yet be using AzApi,

+and so the most effective path to use AzApi is to implement a

+mapping to the current objects used by the XACML PDP.

+<ul>

+<li> In fact, this is exactly what is done in the OpenAz layer five, 

+where the AzApi top level impl,

+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/pdp/provider/SimpleConcreteSunXacmlService.html">

+<b>SimpleConcreteSunXacmlService</b></a>, 

+wraps the SunXacml PDP, which has its own interface, 

+<ul>

+<li> <a href="http://sunxacml.sourceforge.net/javadoc/com/sun/xacml/PDP.html#evaluate(com.sun.xacml.ctx.RequestCtx)">

+ResponseCtx response = PDP.evaluate(RequestCtx request)</a>

+</ul>

+</ul>

+

+<a name="azapivssunxacml"><H4>AzApi vs SunXacml</H4></a>

+

+<p>

+While the SunXacml interface is "similar" to the AzApi interface, 

+particularly the AzApi "decide()" call 

+<p>

+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/azapi/AzService.html#decide(org.openliberty.openaz.azapi.AzRequestContext)">

+<b>AzService.decide</b></a>

+(

+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/azapi/AzRequestContext.html">

+<b>AzRequestContext</b></a>

+};

+

+<ul>

+<li> AzResponseContext azRspCtx = AzService.decide(AzRequestContext azReqCtx)

+</ul>

+

+<p>

+there is still a "mapping" required to go from the AzApi implementation

+objects to the SunXacml implementation objects. i.e. one must map the

+AzApi 

+<a href="http://sunxacml.sourceforge.net/javadoc/com/sun/xacml/ctx/RequestCtx.html">

+<b>RequestCtx</b></a>

+to the SunXacml and on the return, map the SunXacml 

+<a href="http://sunxacml.sourceforge.net/javadoc/com/sun/xacml/ctx/ResponseCtx.html">

+<b>ResponseCtx</b></a> to the AzApi 

+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/azapi/AzResponseContext.html">

+<b>AzResponseContext</b></a>

+

+

+<a name="canonicalform"><H4>Canonical Form</H4></a>

+Given the above description, one may ask why map to the canonical form

+at all? Why not have layer 3 map directly to the local form of the 

+PDP, and therefore skip layers 4 and 5?

+

+<ul>

+<li>In fact, the architecture is designed so that is a perfectly

+legitimate strategy to take. However, the major drawback to this strategy

+is that if the enterprise has a mix of PDPs from multiple vendors,

+then configuration may begin to become complex, as one must keep track

+of which vendor's PDP is servicing which application, so as to ensure

+that the proper mappers are in place to map from the application

+objects to the specific PDP vendor objects.

+

+<li>From a purely technical engineering for performance perspective,

+it may appear that the benefit of an intermediate canonical form in

+the runtime path, as kind of a standard "clearinghouse" is not 

+compelling enough on its own to justify the effort to achieve it.

+

+<li>However, there are additional considerations. Security Policy

+is an all-encompassing concern for an enterprise that generally 

+applies to every activity conducted by the enterprise, whether

+for concern of privacy, risk-avoidance, compliance, integrity, etc.,

+there needs to be a way to integrate security Policy to any activity.

+

+<li>In order to effectively manage security Policy, there needs to

+be standard representations of the information in those Policies,

+as well as a method to relate that information to the corresponding

+representation of information in the enterprise that is collected

+and assembled to a Request to be evaluated by Policy.

+</ul>

+

+<a name="tutorialmappers"><H2>OpenAz Mappers Writing Tutorial (v114)</H2></a>

+<H3>Contents</H3>

+<ul>

+<li><a href="#highleveloverviewmappers">High Level Overview: Mappers</a>

+<li><a href="#structuremappers">Mapper structure</a>

+<li><a href="#methodimplmappers">Mapper method implementation</a>

+<li><a href="#permissionmappers">Permission Mapper</a>

+

+</ul>

+</ul>

+

+<a name="highleveloverviewmappers">

+<H3>High Level Overview: Mappers</H3></a>

+At the most fundamental level, the philosophy of OpenAz and PepApi/AzApi

+that the process of authorization can be abstracted as Policy defined in

+terms of "entities" represented as collections of "attributes", where the

+entities and attributes can be represented by a common standard such

+as XACML. Therefore, in theory, all that is required at runtime when an

+authorization check is required is to look at the entities involved and

+evaluate the Policy to determine if the attributes of the entities meet

+the Policy criteria for granting access.

+<p>

+The "entities" involved in a typical access check include:

+<ul>

+<li>A User Entity, or "Subject", where the Subject is the entity that

+is requesting access.

+<li>A Resource Entity, where the Resource is the entity to which the

+User Entity is requesting access.

+<li>An Action Entity, where the action specifies the explicit operations

+that the User Entity is requesting to apply to the Resource Entity.

+<li>An optional Environment Entity, where the "environment" is generally

+to be considered system conditions, such as time of day, that may factor

+into the decision making process. All such attributes are generally 

+collected in an Environment Entity collection of Attributes.

+</li>

+</ul>

+In the XACML Specification, all attributes are of a specific XACML

+DataType, which means, as described in XACML Specification Section A.2:

+<pre>

+  A.2. Data-types

+  

+    Although XML instances represent all data-types as strings,

+    an XACML PDP must reason about types of data that, while they

+    have string representations, are not just strings. 

+    

+    Types such as Boolean, integer and double MUST be converted:

+    

+        - from their XML string representations

+        - to values that can be compared with values in their domain

+          of discourse, such as numbers.

+</pre>

+(Note: the XACML Specification uses both the term "data-type" and the

+term "DataType", where the former refers to a generic notion of a

+"data type", but within the XACML context, thus also implicitly

+referring to the latter term, "DataType", which is the name of the

+"XML attribute" used to specify the specific instance of XACML 

+data-type to be used in conjunction with the XACML Attribute element

+that contains both the DataType attribute and AttributeValue element.

+OpenAz will not make such a distinction and simply use the term "DataType"

+or "datatype" interchangeably to in any of these contexts.)

+<p>

+In OpenAz, the "lower level" AzApi contains a separate interface for each

+of the Xacml DataTypes and a specific Java Object Type is also associated

+with each Xacml DataType. The collection of 

+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/azapi/AzAttributeValue.html"

+>AzAttributeValue subinterfaces</a>

+along with the associated list of "Known Implementing Classes" that reference

+the reference impl implementations of these interfaces, effectively can

+be considered the specification of the "AzApi Java Language Binding".

+<p>

+As such, in order to make an AzRequest to a XACML PDP, one needs to

+collect the attributes associated with each entity (where the entities

+are distinguished by 

+<a href ="">AzCategoryId</a> and submit the Java objects containing the

+attribute values thru these standard interfaces.

+<p>

+The purpose of the lower level AzApi interface is to provide a

+well-structured framework that has a standard representation of all

+information that may ultimately prove necessary to submit a complete

+authorization request.

+<p>

+However, in general, information in the runtime environment is not

+in any particular standard form, so, in order to enable minimal impact

+on existing runtime development practices, the PepApi was developed to

+enable applications to submit whatever information objects are preferred

+to be used in a particular application environment. 

+<p>

+In order to make this strategy work the PepApi implementation needs to

+"map" the information in the objects supplied by the application from

+that environment-specific form to the AzApi standard form, which will

+then enable seamless submission to a XACML PDP.

+<p>

+However, as described in the first tutorial above, the same strategy 

+will work with almost any PDP. This second tutorial will explain how

+the reference impl mappers are designed, and it is expected that the

+same design strategy can be applied to mapping to other PDP APIs,

+as well, where instead of mapping application objects to azapi objects,

+the mapping would be to the non-Xacml-PDP-specific objects.

+<H3>How to build a Mapper</H3>

+Probably the most straight-forward way to explain how to build a mapper

+is to explain how the existing mappers provided in PepApi work.

+<a name="structuremappers"><h4>Mapper structure</h4></a>

+Looking at the javadoc for 

+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/pep/SimpleJavaObjectMapper.html"

+>org.openliberty.openaz.pep.SimpleJavaObjectMapper</a> as a

+typical example, we can make the following observations about its structure:

+<ul>

+<li>It implements the 

+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/azapi/pep/JavaObjectMapper.html"

+>org.openliberty.openaz.azapi.pep.JavaObjectMapper</a>

+interface.

+<li>The javadoc says that it supports 3 objects: String, Date, and HashMap,

+and that it maps those objects into RequestAttributes.

+<li>The 3 JavaObjectMapper interface methods: canMapObject(), map(), and

+getSupportedObjects() appear in the Method Summary for the 

+SimpleJavaObjectMapper.

+<li>There are additional methods used within the implementation: 

+convertDate, convertString, convertMap. These methods do the actual

+conversion of the application input object to the AzAttribute structures.

+</ul>

+<a name="methodimplmappers"><h4>Mapper method implementation</h4></a>

+<h5>getSupportedObjects</h5>

+Implementation of getSupportedObjects() in SimpleJavaObjectMapper is

+to simply create a set containing a class object for each class that

+the mapper supports. This is simply a hard-coded set which can be used

+when configuring mappers to preliminarily determine object types supported.

+<p>

+For the SimpleJavaObjectMapper, this consists of a list of 3 class types:

+String, Date, HashMap.

+<h5>canMapObject</h5>

+Implementation of canMapObject(Object obj) should be straight-forward.

+In SimpleJavaObjectMapper there is simply a sequence of "if statements"

+that use "instanceof" to test whether the obj parameter is an "instanceof"

+one of the supported object classes. If there is a match then true

+is returned, otherwise false is returned.

+<h5>map</h5>

+Implementation of the 

+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/azapi/pep/JavaObjectMapper.html#map(java.lang.Object,%20org.openliberty.openaz.azapi.pep.RequestAttributes)"

+>map(Object obj, RequestAttributes<T> reqAttrs)</a> method is the

+only place where there might be some non-trivial complexity to work thru.

+<p>

+In SimpleJavaObjectMapper, map(obj,reqAttrs) dispatches to a conversion

+method for one of the supported object types by going thru a similar

+sequence of "if instanceof" test and dispatching when a matching object

+class is found.

+<p>

+Within the conversion methods, the first thing considered is the AzCategoryId

+of the RequestAttributes target object, which for AzApi is an AzEntity

+AzAttribute collection. When the Mapper.map method is invoked, the caller

+needs to determine which AzCategoryId to pass to the method as the 

+generic parameter T of the RequestAttributes<T> object being passed.

+<p>

+Generally, this will be implicitly determined by the entity for which

+the object being converted is intended. In the 

+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/azapi/pep/PepRequestFactory.html"

+>PepApi PepRequestFactory.newPepRequest(*) methods</a>,

+the objects passed are in an order that determines whether the object is

+to be considered a Subject, Action, Resource, or Environment as

+described in the signature to the newPepRequest methods. 

+<p>

+One can get a rough idea of how this is implemented by following the 

+<a href="#pepapiseqmodel">PepApi sequence model</a> in the first tutorial

+above. In particular, starting with PepRequestFactoryImpl call to

+setAccessSubject(sObj), one can follow the diagram logic down to

+the RequestAttributes.setAttribute(attrId, subjObj) method where the

+Mapper has been invoked and the convertObject method within the Mapper

+is setting the attribute on the AzEntity.

+<a name="permissionmappers"><H4>Permission Mapper</H4></a>

+A slightly more interesting case is the 

+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/pep/SimpleJavaPermissionMapper.html">SimpleJavaPermissionMapper</a>

+<p>

+As described in the javadoc for

+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/pep/SimpleJavaPermissionMapper.html#map(java.lang.Object,%20org.openliberty.openaz.azapi.pep.RequestAttributes)"

+>SimpleJavaPermissionMapper.map()</a>

+a Permission or any subclass of Permission can be processed and effectively

+serialized into 3 String parameters, where the Permission subclass is assumed

+to be a "resource-type", the name parameter is assumed to be the "resource-id",

+and the action is assumed to be the "action-id", where resource-id and action-id

+are as defined in Xacml, and resource-type is an OpenAz identifier used to

+name a resource type.

+<p>

+Therefore these 3 parameters can be passed to the Xacml PDP and generally

+policies will contain regular expression conditions on resource name in order

+to create scopes of resources and actions subject to the policy. Some examples

+demonstrating this technique are included in the test program

+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/test/TestStyles.html"

+>TestStyles</a>

+where the code and javadoc of the testStyle* methods describe some of 

+the test cases, and the 

+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/src/test/"

+>code from the project</a>

+ may be examined.

+</body>

+</html>
\ No newline at end of file
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestAPI.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestAPI.java
new file mode 100755
index 0000000..f2173a8
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestAPI.java
@@ -0,0 +1,81 @@
+package org.openliberty.openaz.pepapi.std.test;

+

+import org.junit.Assert;

+import org.junit.Before;

+import org.junit.Test;

+import org.openliberty.openaz.pepapi.*;

+import org.openliberty.openaz.pepapi.std.StdPepAgentFactory;

+

+import java.util.ArrayList;

+import java.util.List;

+

+

+public class TestAPI {

+

+	private PepAgentFactory pepAgentFactory;

+

+	@Before

+	public void setup() {

+		pepAgentFactory = new StdPepAgentFactory("/properties/testapi.xacml.properties");

+	}

+	

+	

+	/**

+	 * 

+	 */

+	@Test

+	public void testPepAgent() {

+		Assert.assertNotNull(getPepAgent());

+	}

+

+	

+	/**

+	 * 

+	 */

+	@Test

+	public void testPermit(){

+		PepResponse response = getPepAgent().simpleDecide("Julius Hibbert",

+				"read", "http://medico.com/record/patient/BartSimpson");

+		Assert.assertNotNull(response);

+		Assert.assertEquals(true, response.allowed());

+	}

+

+	

+	/**

+	 * 

+	 */

+	@Test

+	public void testNotApplicable(){

+		PepResponse response = getPepAgent().simpleDecide("Julius Hibbert",

+				"read","http://medico.com/record/patient/JohnSmith");

+		Assert.assertNotNull(response);

+		Assert.assertEquals(false, response.allowed());

+	}

+

+	

+	/**

+	 * 

+	 */

+	@Test

+	public void testMultiRequest() {

+		List<Action> actions = new ArrayList<Action>();

+		actions.add(Action.newInstance("read"));

+		actions.add(Action.newInstance("write"));

+		actions.add(Action.newInstance("update"));

+		actions.add(Action.newInstance("delete"));

+

+		List<PepResponse> responses = getPepAgent().bulkDecide(actions,

+				Subject.newInstance("Julius Hibbert"),

+				Resource.newInstance("http://medico.com/record/patient/BartSimpson"));

+		Assert.assertNotNull(responses);

+		Assert.assertEquals(true, responses.get(0).allowed());

+		Assert.assertEquals(true, responses.get(1).allowed());

+		Assert.assertEquals(false, responses.get(2).allowed());

+		Assert.assertEquals(false, responses.get(3).allowed());

+

+	}

+

+	public PepAgent getPepAgent() {

+		return pepAgentFactory.getPepAgent();

+	}

+}

diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestAPIWithPIP.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestAPIWithPIP.java
new file mode 100755
index 0000000..90cef8e
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestAPIWithPIP.java
@@ -0,0 +1,98 @@
+package org.openliberty.openaz.pepapi.std.test;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.junit.Assert;

+import org.junit.Before;

+import org.junit.Ignore;

+import org.junit.Test;

+import org.openliberty.openaz.pepapi.*;

+import org.openliberty.openaz.pepapi.std.StdPepAgentFactory;

+

+import java.util.ArrayList;

+import java.util.List;

+

+

+public class TestAPIWithPIP {

+	

+	private static final Log log = LogFactory.getLog(TestAPIWithPIP.class);

+

+	private PepAgentFactory pepAgentFactory;

+

+	@Before

+	public void setup() {

+		pepAgentFactory = new StdPepAgentFactory("xacml.properties");

+	}

+	

+

+	/**

+	 * 

+	 */

+	@Ignore

+	@Test

+	public void testPepAgent() {

+		Assert.assertNotNull(getPepAgent());

+	}

+

+	

+	/**

+	 * 

+	 */

+	@Ignore

+	@Test

+	public void testPermit() {

+		PepResponse response = getPepAgent()

+				.simpleDecide("John Doe",

+						"read",

+						"http://medico.com/record/patient/BartSimpson");

+		Assert.assertNotNull(response);

+		Assert.assertEquals(true, response.allowed());

+	}

+

+	

+	/**

+	 * 

+	 */

+	@Ignore

+	@Test

+	public void testNotApplicable() {

+		PepResponse response = getPepAgent()

+				.simpleDecide("John Smith",

+						"read",

+						"http://medico.com/record/patient/BartSimpson");

+		Assert.assertNotNull(response);

+		Assert.assertEquals(false, response.allowed());

+	}

+

+	

+	/**

+	 * 

+	 */

+	@Ignore

+	@Test

+	public void testMultiRequest() {

+		List<Action> actions = new ArrayList<Action>();

+		actions.add(Action.newInstance("read"));

+		actions.add(Action.newInstance("update"));

+		actions.add(Action.newInstance("write"));

+		actions.add(Action.newInstance("modify"));

+

+		Resource resource = Resource.newInstance("http://medico.com/record/patient/BartSimpson");

+		Subject subject = Subject.newInstance("John Doe");

+

+		List<PepResponse> responses = getPepAgent().bulkDecide(actions, resource, subject);

+		Assert.assertNotNull(responses);

+		Assert.assertEquals(actions.size(), responses.size());

+		Assert.assertEquals(true, responses.get(0).allowed());

+		Assert.assertEquals(false, responses.get(1).allowed());

+		Assert.assertEquals(true, responses.get(2).allowed());

+		Assert.assertEquals(false, responses.get(3).allowed());

+		for(PepResponse response: responses) {

+			log.debug(response.getAssociation());

+		}

+	}

+	

+	public PepAgent getPepAgent() {

+		return pepAgentFactory.getPepAgent();

+	}

+}

diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestAnnotatedHandlerRegistration.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestAnnotatedHandlerRegistration.java
new file mode 100755
index 0000000..830d28e
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestAnnotatedHandlerRegistration.java
@@ -0,0 +1,72 @@
+package org.openliberty.openaz.pepapi.std.test;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.junit.Assert;

+import org.junit.Before;

+import org.junit.Ignore;

+import org.junit.Test;

+import org.openliberty.openaz.pepapi.*;

+import org.openliberty.openaz.pepapi.std.StdPepAgentFactory;

+import org.openliberty.openaz.pepapi.std.test.obligation.AnnotatedCatchAllObligationHandler;

+import org.openliberty.openaz.pepapi.std.test.obligation.AnnotatedFilteringObligationHandler;

+import org.openliberty.openaz.pepapi.std.test.obligation.AnnotatedRedactionObligationHandler;

+

+

+public class TestAnnotatedHandlerRegistration {

+	

+	@SuppressWarnings("unused")

+	private static Log log = LogFactory.getLog(TestAnnotatedHandlerRegistration.class);

+

+	private PepAgentFactory pepAgentFactory;

+

+	//TODO: Need to wire

+	private AnnotatedFilteringObligationHandler filterHandler;

+

+	//TODO: Need to wire

+	private AnnotatedRedactionObligationHandler redactionHandler;

+

+	//TODO: Need to wire

+	private AnnotatedCatchAllObligationHandler catchAllHandler;

+

+

+	@Before

+	public void setup() {

+		pepAgentFactory = new StdPepAgentFactory("xacml.properties");

+	}

+	

+

+	

+	/**

+	 * 

+	 */

+	@Ignore

+	@Test

+	public void testPepAgent() {

+		Assert.assertNotNull(getPepAgent());

+	}

+	

+	

+	

+	/**

+	 * 

+	 */

+	@Ignore

+	@Test

+	public void testRegistration() {

+		Subject subject = Subject.newInstance("John Smith");

+		subject.addAttribute("urn:oasis:names:tc:xacml:1.0:subject:age", "45");

+		PepResponse response = getPepAgent().decide(subject, Action.newInstance("view"),

+				Resource.newInstance("resource1"));

+		Assert.assertNotNull(response);

+		Assert.assertEquals(true, response.allowed());

+		filterHandler.enforce();

+		redactionHandler.enforce();

+		catchAllHandler.enforce();

+	}

+

+	public PepAgent getPepAgent() {

+		return pepAgentFactory.getPepAgent();

+	}

+

+}

diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestDataTypes.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestDataTypes.java
new file mode 100755
index 0000000..40a39da
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestDataTypes.java
@@ -0,0 +1,85 @@
+package org.openliberty.openaz.pepapi.std.test;

+

+import org.junit.Assert;

+import org.junit.Before;

+import org.junit.Test;

+import org.openliberty.openaz.pepapi.*;

+import org.openliberty.openaz.pepapi.std.StdPepAgentFactory;

+

+import java.net.URI;

+import java.util.ArrayList;

+import java.util.List;

+

+

+public class TestDataTypes {

+

+	private PepAgentFactory pepAgentFactory;

+

+	@Before

+	public void setup() {

+		/*System.setProperty("xacml.properties" ,

+				getClass().getClassLoader().getResource("properties/testdatatypes.xacml.properties").getPath());*/

+		pepAgentFactory = new StdPepAgentFactory("/properties/testdatatypes.xacml.properties");

+	}

+	

+	

+	/**

+	 * 

+	 */

+	@Test

+	public void testPepAgent() {

+		Assert.assertNotNull(getPepAgent());

+	}

+

+	

+	/**

+	 * 

+	 */

+	@Test

+	public void testPermitWithURIResource() {

+		Subject subject = Subject.newInstance("John Smith");

+		Action action = Action.newInstance("view");

+		Resource resource = Resource.newInstance(URI.create("file://repository/classified/abc"));

+		PepResponse response = getPepAgent().decide(subject, action, resource);

+		Assert.assertNotNull(response);

+		Assert.assertEquals(true, response.allowed());

+	}

+	

+

+	/**

+	 * 

+	 */

+	@Test

+	public void testPermitWithIntegerResource() {

+		Subject subject = Subject.newInstance("John Smith");

+		Action action = Action.newInstance("view");

+		Resource resource = Resource.newInstance(101L);

+		PepResponse response = getPepAgent().decide(subject, action, resource);

+		Assert.assertNotNull(response);

+		Assert.assertEquals(true, response.allowed());

+	}

+

+	

+	/**

+	 * 

+	 */

+	@Test

+	public void testMultiRequestWithURI() {

+		List<Resource> resources = new ArrayList<Resource>();

+		resources.add(Resource.newInstance(URI.create("file://repository/classified/abc")));

+		resources.add(Resource.newInstance(URI.create("file://repository/classified/xyz")));

+

+		Subject subject = Subject.newInstance("John Smith");

+		Action action = Action.newInstance("view");

+

+		List<PepResponse> responses = getPepAgent().bulkDecide(resources, action, subject);

+		Assert.assertNotNull(responses);

+		for(PepResponse response: responses) {

+			Assert.assertEquals(true, response.allowed());

+		}

+	}

+

+	public PepAgent getPepAgent() {

+		return pepAgentFactory.getPepAgent();

+	}

+}

diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestMapper.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestMapper.java
new file mode 100755
index 0000000..0c4c50e
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestMapper.java
@@ -0,0 +1,123 @@
+package org.openliberty.openaz.pepapi.std.test;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.junit.Assert;

+import org.junit.Before;

+import org.junit.Test;

+import org.openliberty.openaz.pepapi.*;

+import org.openliberty.openaz.pepapi.std.StdPepAgentFactory;

+import org.openliberty.openaz.pepapi.std.test.mapper.BusinessRequestContext;

+import org.openliberty.openaz.pepapi.std.test.mapper.Client;

+import org.openliberty.openaz.pepapi.std.test.mapper.Document;

+

+import java.util.ArrayList;

+import java.util.List;

+

+

+public class TestMapper {

+	

+	@SuppressWarnings("unused")

+	private static Log logger = LogFactory.getLog(TestMapper.class);

+

+	private PepAgentFactory pepAgentFactory;

+

+	@Before

+	public void setup() {

+		this.pepAgentFactory = new StdPepAgentFactory("/properties/testmapper.xacml.properties");

+	}

+	

+	/**

+	 * 

+	 */

+	@Test

+	public void testPepAgent() {

+		Assert.assertNotNull(getPepAgent());

+	}

+	

+	/**

+	 * 

+	 */

+	@Test

+	public void testPermit() {

+		Subject subject = Subject.newInstance("John Smith");

+		subject.addAttribute("urn:oasis:names:tc:xacml:1.0:subject:role-id", "ROLE_DOCUMENT_WRITER");

+

+		Action action = Action.newInstance("write");

+

+		Document doc = new Document(1, "OnBoarding Document", "ABC Corporation", "John Smith");

+		PepResponse response = getPepAgent().decide(subject, action, doc);

+		Assert.assertNotNull(response);

+		Assert.assertEquals(true, response.allowed());

+	}

+	

+	/**

+	 * 

+	 */

+	@Test

+	public void testNotApplicable(){

+		Subject subject = Subject.newInstance("John Smith");

+		subject.addAttribute("urn:oasis:names:tc:xacml:1.0:subject:role-id", "ROLE_DOCUMENT_WRITER");

+

+		Action action = Action.newInstance("write");

+		Document doc = new Document(2, "OnBoarding Document", "XYZ Corporation", "Jim Doe");

+		PepResponse response = getPepAgent().decide(subject,  action, doc);

+		Assert.assertNotNull(response);

+		Assert.assertEquals(false, response.allowed());

+	}

+	

+	@Test(expected=PepException.class)

+	public void testMix(){

+		Subject subject = Subject.newInstance("John Smith");

+		subject.addAttribute("urn:oasis:names:tc:xacml:1.0:subject:role-id", "ROLE_DOCUMENT_WRITER");

+

+		Action action = Action.newInstance("write");

+

+		Document doc1 = new Document(1, "OnBoarding Document", "ABC Corporation", "John Smith");

+		Document doc2 = new Document(2, "OnBoarding Document", "XYZ Corporation", "Jim Doe");

+		List<Object> resourceList = new ArrayList<Object>();

+		resourceList.add(doc1);

+		resourceList.add(doc2);

+		

+		PepResponse response = getPepAgent().decide(subject, action, resourceList);

+		Assert.assertNotNull(response);

+		response.allowed();

+	}

+	

+	@Test

+	public void testVarArgsPermit(){

+		Subject subject = Subject.newInstance("John Smith");

+		subject.addAttribute("urn:oasis:names:tc:xacml:1.0:subject:role-id", "ROLE_DOCUMENT_READER");

+		BusinessRequestContext bc = new BusinessRequestContext("USA", "05:00 EST");

+

+		Action action = Action.newInstance("read");

+		List<Object> resources = new ArrayList<Object>();

+		resources.add(new Document(1, "OnBoarding Document", "XYZ Corporation", "Jim Doe"));

+		resources.add(new Client("XYZ Corporation", "USA"));

+		

+		PepResponse response = getPepAgent().decide(subject, action, resources, bc);

+		Assert.assertNotNull(response);

+		Assert.assertEquals(true, response.allowed());

+	}

+	

+	@Test

+	public void testVarArgsDeny(){

+		Subject subject = Subject.newInstance("John Smith");

+		subject.addAttribute("urn:oasis:names:tc:xacml:1.0:subject:role-id", "ROLE_DOCUMENT_READER");

+		BusinessRequestContext bc = new BusinessRequestContext("INDIA", "05:00 IST");

+		

+		List<Object> resources = new ArrayList<Object>();

+		resources.add(new Document(2, "OnBoarding Document", "XYZ Corporation", "Jim Doe"));

+		resources.add(new Client("XYZ Corporation", "USA"));

+

+		Action action = Action.newInstance("write");

+

+		PepResponse response = getPepAgent().decide(subject, action, resources, bc);

+		Assert.assertNotNull(response);

+		Assert.assertEquals(false, response.allowed());

+	}

+

+	public PepAgent getPepAgent() {

+		return pepAgentFactory.getPepAgent();

+	}

+}

diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContext.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContext.java
new file mode 100755
index 0000000..1820428
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContext.java
@@ -0,0 +1,21 @@
+package org.openliberty.openaz.pepapi.std.test.mapper;

+

+public class BusinessRequestContext {

+	

+	private final String requestCountry;

+	

+	private final String requestTime;

+

+	public BusinessRequestContext(String country, String time){

+		this.requestCountry = country;

+		this.requestTime = time;

+	}

+	

+	public String getRequestCountry() {

+		return requestCountry;

+	}

+

+	public String getRequestTime() {

+		return requestTime;

+	}

+}

diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContextMapper.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContextMapper.java
new file mode 100755
index 0000000..3b1c93a
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContextMapper.java
@@ -0,0 +1,34 @@
+package org.openliberty.openaz.pepapi.std.test.mapper;

+

+import com.att.research.xacml.api.XACML3;

+import org.openliberty.openaz.pepapi.*;

+

+public class BusinessRequestContextMapper implements ObjectMapper {

+

+	private MapperRegistry mapperRegistry;

+

+	private PepConfig pepConfig;

+

+	@Override

+	public Class<?> getMappedClass() {

+		return BusinessRequestContext.class;

+	}

+

+	@Override

+	public void map(Object o, PepRequest pepRequest) {

+		BusinessRequestContext bc = (BusinessRequestContext)o;

+		PepRequestAttributes envAttributes = pepRequest.getPepRequestAttributes(XACML3.ID_ATTRIBUTE_CATEGORY_ENVIRONMENT);

+		envAttributes.addAttribute("jpmc:request-context:country", bc.getRequestCountry());

+		envAttributes.addAttribute("jpmc:request-context:time", bc.getRequestTime());

+	}

+

+	@Override

+	public void setMapperRegistry(MapperRegistry mapperRegistry) {

+		this.mapperRegistry = mapperRegistry;

+	}

+

+	@Override

+	public void setPepConfig(PepConfig pepConfig) {

+		this.pepConfig = pepConfig;

+	}

+}

diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/Client.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/Client.java
new file mode 100755
index 0000000..9c2ca08
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/Client.java
@@ -0,0 +1,20 @@
+package org.openliberty.openaz.pepapi.std.test.mapper;

+

+public class Client {

+	

+	private final String name;

+	

+	private final String countryOfDomicile;

+	

+	public Client(String name, String countryOfDomicile){

+		this.name = name;

+		this.countryOfDomicile = countryOfDomicile;

+	}

+

+	public String getName() {

+		return name;

+	}

+	public String getCountryOfDomicile() {

+		return countryOfDomicile;

+	}

+}

diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/ClientMapper.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/ClientMapper.java
new file mode 100755
index 0000000..b482a44
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/ClientMapper.java
@@ -0,0 +1,34 @@
+package org.openliberty.openaz.pepapi.std.test.mapper;

+

+import com.att.research.xacml.api.XACML3;

+import org.openliberty.openaz.pepapi.*;

+

+public class ClientMapper implements ObjectMapper {

+

+	private MapperRegistry mapperRegistry;

+

+	private PepConfig pepConfig;

+	

+	@Override

+	public Class<?> getMappedClass() {

+		return Client.class;

+	}

+

+	@Override

+	public void map(Object o, PepRequest pepRequest) {

+		Client c = (Client)o;

+		PepRequestAttributes resAttributes = pepRequest.getPepRequestAttributes(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE);

+		resAttributes.addAttribute("jpmc:client:name", c.getName());

+		resAttributes.addAttribute("jpmc:client:country-of-domicile", c.getCountryOfDomicile());

+	}

+

+	@Override

+	public void setMapperRegistry(MapperRegistry mapperRegistry) {

+		this.mapperRegistry = mapperRegistry;

+	}

+

+	@Override

+	public void setPepConfig(PepConfig pepConfig) {

+		this.pepConfig = pepConfig;

+	}

+}

diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/Document.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/Document.java
new file mode 100755
index 0000000..cd36245
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/Document.java
@@ -0,0 +1,32 @@
+package org.openliberty.openaz.pepapi.std.test.mapper;

+

+public class Document {

+	

+	private final Integer documentId;

+	private final String documentName;

+	private final String clientName;

+	private final String documentOwner;

+	

+	public Document(Integer documentId, String documentName, String clientName, String documentOwner){

+		this.documentId = documentId;

+		this.documentName = documentName;

+		this.clientName = clientName;

+		this.documentOwner = documentOwner;

+	}

+	

+	public Integer getDocumentId() {

+		return documentId;

+	}

+	

+	public String getDocumentName() {

+		return documentName;

+	}

+	

+	public String getDocumentOwner() {

+		return documentOwner;

+	}

+

+	public String getClientName() {

+		return clientName;

+	}

+}

diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/DocumentMapper.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/DocumentMapper.java
new file mode 100755
index 0000000..498d3ee
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/DocumentMapper.java
@@ -0,0 +1,37 @@
+package org.openliberty.openaz.pepapi.std.test.mapper;

+

+import com.att.research.xacml.api.XACML3;

+import org.openliberty.openaz.pepapi.*;

+

+public class DocumentMapper implements ObjectMapper {

+

+	private MapperRegistry mapperRegistry;

+

+	private PepConfig pepConfig;

+	

+	@Override

+	public Class<?> getMappedClass() {

+		return Document.class;

+	}

+

+	@Override

+	public void map(Object o, PepRequest pepRequest) {

+		Document d = (Document)o;

+		PepRequestAttributes resourceAttributes = pepRequest.getPepRequestAttributes(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE);

+		resourceAttributes.addAttribute("urn:oasis:names:tc:xacml:1.0:resource:resource-id", d.getDocumentId());

+		resourceAttributes.addAttribute("urn:oasis:names:tc:xacml:1.0:resource:resource-type", "Document");

+		resourceAttributes.addAttribute("jpmc:document:document-name", d.getDocumentName());

+		resourceAttributes.addAttribute("jpmc:document:client-name", d.getClientName());

+		resourceAttributes.addAttribute("jpmc:document:document-owner", d.getDocumentOwner());

+	}

+

+	@Override

+	public void setMapperRegistry(MapperRegistry mapperRegistry) {

+		this.mapperRegistry = mapperRegistry;

+	}

+

+	@Override

+	public void setPepConfig(PepConfig pepConfig) {

+		this.pepConfig = pepConfig;

+	}

+}
\ No newline at end of file
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecord.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecord.java
new file mode 100755
index 0000000..6a7b317
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecord.java
@@ -0,0 +1,37 @@
+package org.openliberty.openaz.pepapi.std.test.mapper;

+

+import java.util.ArrayList;

+import java.util.List;

+

+public class MedicalRecord {

+	

+	private String id;

+	

+	private List<String> accessUserGroup;

+	

+	public MedicalRecord(String id){

+		this.id = id;

+		accessUserGroup = new ArrayList<String>();

+	}

+

+	public String getId() {

+		return id;

+	}

+

+	public void setId(String id) {

+		this.id = id;

+	}

+

+	public List<String> getAccessUserGroup() {

+		return accessUserGroup;

+	}

+

+	public void setAccessUserGroup(List<String> accessUserGroup) {

+		this.accessUserGroup = accessUserGroup;

+	}

+	

+	public void addUserToAccessGroup(String user) {

+		this.accessUserGroup.add(user);

+	}

+	

+}

diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecordMapper.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecordMapper.java
new file mode 100755
index 0000000..9882d30
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecordMapper.java
@@ -0,0 +1,36 @@
+package org.openliberty.openaz.pepapi.std.test.mapper;

+

+import com.att.research.xacml.api.XACML3;

+import org.openliberty.openaz.pepapi.*;

+

+public class MedicalRecordMapper implements ObjectMapper {

+

+	private MapperRegistry mapperRegistry;

+

+	private PepConfig pepConfig;

+

+	@Override

+	public Class<?> getMappedClass() {

+		return MedicalRecord.class;

+	}

+

+	@Override

+	public void map(Object o, PepRequest pepRequest) {

+		MedicalRecord md = (MedicalRecord) o;

+		PepRequestAttributes resourceAttributes = pepRequest.getPepRequestAttributes(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE);

+		resourceAttributes.addAttribute("urn:oasis:names:tc:xacml:1.0:resource:resource-type", "PatientMedicalRecord");

+		resourceAttributes.addAttribute("urn:oasis:names:tc:xacml:1.0:resource:resource-id", md.getId());

+		for(String accessUser: md.getAccessUserGroup()) {

+			resourceAttributes.addAttribute("urn:oasis:names:tc:xacml:1.0:resource:resource-access-group", accessUser);

+		}

+	}

+	@Override

+	public void setMapperRegistry(MapperRegistry mapperRegistry) {

+		this.mapperRegistry = mapperRegistry;

+	}

+

+	@Override

+	public void setPepConfig(PepConfig pepConfig) {

+		this.pepConfig = pepConfig;

+	}

+}

diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AccessRestrictionObligationHandler.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AccessRestrictionObligationHandler.java
new file mode 100755
index 0000000..2fd5b9a
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AccessRestrictionObligationHandler.java
@@ -0,0 +1,56 @@
+package org.openliberty.openaz.pepapi.std.test.obligation;

+

+import junit.framework.Assert;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.openliberty.openaz.pepapi.Obligation;

+import org.openliberty.openaz.pepapi.ObligationHandler;

+import org.openliberty.openaz.pepapi.ObligationStore;

+

+import java.util.Map;

+import java.util.Map.Entry;

+import java.util.Set;

+

+

+public class AccessRestrictionObligationHandler implements ObligationHandler {

+	

+	private static Log log = LogFactory.getLog(AccessRestrictionObligationHandler.class);

+	

+	private ObligationStore obligationStore;

+	

+	public void enforce() {

+		Set<Obligation> accessOblgSet = obligationStore.getHandlerObligations(this.getClass());

+		Assert.assertEquals(true, accessOblgSet.size() == 1);

+		for(Obligation oblg: accessOblgSet) {

+			Map<String, Object[]> attributeMap = oblg.getAttributeMap();

+			Assert.assertNotNull(attributeMap);

+			for(Entry<String, Object[]> e: attributeMap.entrySet()){

+				if(e.getKey().equals("urn:oasis:names:tc:xacml:1.0:subject:subject-id")){

+					Assert.assertNotNull(e.getValue());

+				}

+				if(e.getKey().equals("urn:oasis:names:tc:xacml:1.0:resource:resource-access-group")){

+					Object[] values = e.getValue();

+					Assert.assertNotNull(values);

+					Assert.assertEquals(3, values.length);

+				}

+			}

+		}

+		Obligation accessGroupOblg = obligationStore.getHandlerObligationById(

+				this.getClass(),

+				"urn:oasis:names:tc:xacml:2.0:obligation:access-restriction");

+		Assert.assertNotNull(accessGroupOblg);

+		log.info(accessGroupOblg.getId());

+	}

+	

+	@Override

+	public boolean match(Obligation obligation) {

+		return obligation.getId().

+				equals("urn:oasis:names:tc:xacml:2.0:obligation:access-restriction");

+	}

+

+	@Override

+	public void setObligationStore(ObligationStore oStore) {

+		this.obligationStore = oStore;

+	}

+

+}

diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AgeRestrictionObligationHandler.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AgeRestrictionObligationHandler.java
new file mode 100755
index 0000000..6239412
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AgeRestrictionObligationHandler.java
@@ -0,0 +1,52 @@
+package org.openliberty.openaz.pepapi.std.test.obligation;

+

+import junit.framework.Assert;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.openliberty.openaz.pepapi.Obligation;

+import org.openliberty.openaz.pepapi.ObligationHandler;

+import org.openliberty.openaz.pepapi.ObligationStore;

+import org.openliberty.openaz.pepapi.std.test.util.HasResult;

+

+import java.util.Map;

+import java.util.Set;

+

+public class AgeRestrictionObligationHandler implements ObligationHandler, HasResult {

+	

+	private static Log log = LogFactory.getLog(AgeRestrictionObligationHandler.class);

+	

+	private ObligationStore obligationStore;

+	

+	public String enforce() {

+		Set<Obligation> ageOblgSet = obligationStore.getHandlerObligations(this.getClass());

+		Assert.assertEquals(true, ageOblgSet.size() == 1);

+		Obligation ageOblg = obligationStore.getHandlerObligationById(this.getClass(),

+				"urn:oasis:names:tc:xacml:2.0:obligation:age-restriction");

+		Assert.assertNotNull(ageOblg);

+		String value = null;

+		log.info(ageOblg.getId());

+		//Enforcement Logic

+		Map<String, Object[]> attributeMap = ageOblg.getAttributeMap();

+		Object[] values = attributeMap.get("urn:oasis:names:tc:xacml:1.0:subject:age");

+		if(values != null) {

+			value = (String)values[0];

+		}

+		return value;

+	}

+

+	@Override

+	public boolean match(Obligation obligation) {

+		return obligation.getId().

+				equals("urn:oasis:names:tc:xacml:2.0:obligation:age-restriction");

+	}

+

+	@Override

+	public void setObligationStore(ObligationStore obligationStore) {

+		this.obligationStore = obligationStore;

+	}

+

+	@Override

+	public String getResult() {

+		return enforce();

+	}

+}
\ No newline at end of file
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAccessRestrictionObligationHandler.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAccessRestrictionObligationHandler.java
new file mode 100755
index 0000000..d717acb
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAccessRestrictionObligationHandler.java
@@ -0,0 +1,44 @@
+package org.openliberty.openaz.pepapi.std.test.obligation;

+

+import junit.framework.Assert;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.openliberty.openaz.pepapi.Obligation;

+import org.openliberty.openaz.pepapi.ObligationStore;

+import org.openliberty.openaz.pepapi.ObligationStoreAware;

+import org.openliberty.openaz.pepapi.MatchAnyObligation;

+

+import java.util.Map.Entry;

+

+@MatchAnyObligation("urn:oasis:names:tc:xacml:2.0:obligation:access-restriction")

+public class AnnotatedAccessRestrictionObligationHandler implements ObligationStoreAware {

+	

+	private static Log log = LogFactory.getLog(AnnotatedAccessRestrictionObligationHandler.class);

+	

+	private ObligationStore obligationStore;

+	

+	public void enforce() {

+		Obligation accessGroupOblg = obligationStore.getHandlerObligationById(

+				this.getClass(),

+				"urn:oasis:names:tc:xacml:2.0:obligation:access-restriction");

+		Assert.assertEquals("urn:oasis:names:tc:xacml:2.0:obligation:access-restriction", 

+				accessGroupOblg.getId());

+		log.info(accessGroupOblg.getId());

+		for(Entry<String, Object[]> e: accessGroupOblg.getAttributeMap().entrySet()){

+			if(e.getKey().equals("urn:oasis:names:tc:xacml:1.0:subject:subject-id")){

+				Assert.assertNotNull(e.getValue());

+			}

+			if(e.getKey().equals("urn:oasis:names:tc:xacml:1.0:resource:resource-access-group")){

+				Object[] values = e.getValue();

+				Assert.assertNotNull(values);

+				Assert.assertEquals(3, values.length);

+			}

+		}

+		//Enforcement Logic

+	}

+

+	@Override

+	public void setObligationStore(ObligationStore obligationStore) {

+		this.obligationStore = obligationStore;

+	}

+}

diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAgeRestrictionObligationHandler.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAgeRestrictionObligationHandler.java
new file mode 100755
index 0000000..9a10cfc
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAgeRestrictionObligationHandler.java
@@ -0,0 +1,46 @@
+package org.openliberty.openaz.pepapi.std.test.obligation;

+

+import junit.framework.Assert;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.openliberty.openaz.pepapi.Obligation;

+import org.openliberty.openaz.pepapi.ObligationStore;

+import org.openliberty.openaz.pepapi.ObligationStoreAware;

+import org.openliberty.openaz.pepapi.MatchAnyObligation;

+import org.openliberty.openaz.pepapi.std.test.util.HasResult;

+

+import java.util.Map;

+

+@MatchAnyObligation("urn:oasis:names:tc:xacml:2.0:obligation:age-restriction")

+public class AnnotatedAgeRestrictionObligationHandler implements ObligationStoreAware, HasResult {

+	

+	private static Log log = LogFactory.getLog(AnnotatedAgeRestrictionObligationHandler.class);

+	

+	private ObligationStore obligationStore;

+	

+	public String enforce() {

+		Obligation ageOblg = obligationStore.getHandlerObligationById(

+				this.getClass(),

+				"urn:oasis:names:tc:xacml:2.0:obligation:age-restriction");

+		String value = null;

+		Assert.assertEquals("urn:oasis:names:tc:xacml:2.0:obligation:age-restriction", ageOblg.getId());

+		log.info(ageOblg.getId());

+		//Enforcement Logic

+		Map<String, Object[]> attributeMap = ageOblg.getAttributeMap();

+		Object[] values = attributeMap.get("urn:oasis:names:tc:xacml:1.0:subject:age");

+		if(values != null) {

+			value = (String)values[0];

+		}

+		return value;

+	}

+

+	@Override

+	public void setObligationStore(ObligationStore obligationStore) {

+		this.obligationStore = obligationStore;

+	}

+

+	@Override

+	public String getResult() {

+		return enforce();

+	}

+}
\ No newline at end of file
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAuditObligationHandler.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAuditObligationHandler.java
new file mode 100755
index 0000000..c7a6780
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAuditObligationHandler.java
@@ -0,0 +1,36 @@
+package org.openliberty.openaz.pepapi.std.test.obligation;

+

+import junit.framework.Assert;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.openliberty.openaz.pepapi.Obligation;

+import org.openliberty.openaz.pepapi.ObligationStore;

+import org.openliberty.openaz.pepapi.ObligationStoreAware;

+import org.openliberty.openaz.pepapi.MatchAnyObligation;

+

+import java.util.Set;

+

+@MatchAnyObligation("urn:oasis:names:tc:xacml:2.0:obligation:audit")

+public class AnnotatedAuditObligationHandler implements ObligationStoreAware {

+	

+	private static Log log = LogFactory.getLog(AnnotatedAuditObligationHandler.class);

+	

+	private ObligationStore obligationStore;

+	

+	public void enforce() {

+		Set<Obligation> obligationSet = obligationStore.getHandlerObligations(this.getClass());

+		if(obligationSet.size() == 1) {

+			for(Obligation obligation: obligationSet) {

+				Assert.assertEquals("urn:oasis:names:tc:xacml:2.0:obligation:audit", obligation.getId());

+				log.info(obligation.getId());

+			}

+		}else {

+			Assert.assertFalse(true);

+		}

+	}

+

+	@Override

+	public void setObligationStore(ObligationStore obligationStore) {

+		this.obligationStore = obligationStore;

+	}

+}

diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedCatchAllObligationHandler.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedCatchAllObligationHandler.java
new file mode 100755
index 0000000..0e74d8d
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedCatchAllObligationHandler.java
@@ -0,0 +1,36 @@
+package org.openliberty.openaz.pepapi.std.test.obligation;

+

+import junit.framework.Assert;

+import org.openliberty.openaz.pepapi.Obligation;

+import org.openliberty.openaz.pepapi.ObligationStore;

+import org.openliberty.openaz.pepapi.ObligationStoreAware;

+import org.openliberty.openaz.pepapi.MatchAnyObligation;

+

+import java.util.HashSet;

+import java.util.Set;

+

+@MatchAnyObligation

+public class AnnotatedCatchAllObligationHandler implements ObligationStoreAware {

+	

+	private ObligationStore obligationStore;

+	

+	public void enforce() {

+		Set<Obligation> obligationSet = obligationStore.getHandlerObligations(this.getClass());

+		if(obligationSet.size() == 2) {

+			Set<String> obligationIds = new HashSet<String>();

+			for(Obligation oblg: obligationSet){

+				obligationIds.add(oblg.getId());

+			}

+			Assert.assertTrue(obligationIds.contains("urn:oasis:names:tc:xacml:2.0:obligation:obligation-1"));

+			Assert.assertTrue(obligationIds.contains("urn:oasis:names:tc:xacml:2.0:obligation:obligation-2"));

+		}else {

+			Assert.assertFalse(true);

+		}

+		

+	}

+

+	@Override

+	public void setObligationStore(ObligationStore obligationStore) {

+		this.obligationStore = obligationStore;

+	}

+}

diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedFilteringObligationHandler.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedFilteringObligationHandler.java
new file mode 100755
index 0000000..29f49a0
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedFilteringObligationHandler.java
@@ -0,0 +1,36 @@
+package org.openliberty.openaz.pepapi.std.test.obligation;

+

+import junit.framework.Assert;

+import org.openliberty.openaz.pepapi.Obligation;

+import org.openliberty.openaz.pepapi.ObligationStore;

+import org.openliberty.openaz.pepapi.ObligationStoreAware;

+import org.openliberty.openaz.pepapi.Attribute;

+import org.openliberty.openaz.pepapi.MatchAllObligationAttributes;

+

+import java.util.Set;

+

+@MatchAllObligationAttributes({

+		@Attribute(id="jpmc:obligation:obligation-type", anyValue="Filtering"),

+		@Attribute(id="urn:oasis:names:tc:xacml:1.0:subject:subject-id")

+})

+public class AnnotatedFilteringObligationHandler implements ObligationStoreAware {

+	

+	private ObligationStore obligationStore;

+	

+	public void enforce() {

+		Set<Obligation> obligationSet = obligationStore.getHandlerObligations(this.getClass());

+		if(obligationSet.size() == 1) {

+			for(Obligation obligation: obligationSet) {

+				Assert.assertEquals("urn:oasis:names:tc:xacml:2.0:obligation:obligation-1", 

+						obligation.getId());

+			}

+		}else {

+			Assert.assertFalse(true);

+		}

+	}

+

+	@Override

+	public void setObligationStore(ObligationStore obligationStore) {

+		this.obligationStore = obligationStore;

+	}

+}

diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedObligationHandler.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedObligationHandler.java
new file mode 100755
index 0000000..57d5adf
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedObligationHandler.java
@@ -0,0 +1,19 @@
+package org.openliberty.openaz.pepapi.std.test.obligation;

+

+import org.openliberty.openaz.pepapi.Attribute;

+import org.openliberty.openaz.pepapi.MatchAllObligationAttributes;

+import org.openliberty.openaz.pepapi.MatchAnyObligation;

+

+@MatchAnyObligation({"jpmc:obligation:one","jpmc:obligation:two","jpmc:obligation:three"})

+@MatchAllObligationAttributes({

+	@Attribute(id="jpmc:obligation:obligation-type", anyValue={"FILTERING","REDACTION"}),

+	@Attribute(id="jpmc:resource:attribute:resource-type", anyValue={"Card"}),

+	@Attribute(id="jpmc:obligation:attribute:attribute-1")

+})

+public class AnnotatedObligationHandler {

+	

+	public void enforce() {

+		

+	}

+	

+}

diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedRedactionObligationHandler.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedRedactionObligationHandler.java
new file mode 100755
index 0000000..780a69e
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedRedactionObligationHandler.java
@@ -0,0 +1,35 @@
+package org.openliberty.openaz.pepapi.std.test.obligation;

+

+import junit.framework.Assert;

+import org.openliberty.openaz.pepapi.Obligation;

+import org.openliberty.openaz.pepapi.ObligationStore;

+import org.openliberty.openaz.pepapi.ObligationStoreAware;

+import org.openliberty.openaz.pepapi.Attribute;

+import org.openliberty.openaz.pepapi.MatchAllObligationAttributes;

+

+import java.util.Set;

+

+@MatchAllObligationAttributes(

+		@Attribute(id="urn:oasis:names:tc:xacml:1.0:subject:age")

+)

+public class AnnotatedRedactionObligationHandler implements ObligationStoreAware {

+	

+	private ObligationStore obligationStore;

+	

+	public void enforce() {

+		Set<Obligation> obligationSet = obligationStore.getHandlerObligations(this.getClass());

+		if(obligationSet.size() == 1) {

+			for(Obligation obligation: obligationSet) {

+				Assert.assertEquals("urn:oasis:names:tc:xacml:2.0:obligation:obligation-2", 

+						obligation.getId());

+			}

+		}else {

+			Assert.assertFalse(true);

+		}

+	}

+

+	@Override

+	public void setObligationStore(ObligationStore obligationStore) {

+		this.obligationStore = obligationStore;

+	}

+}

diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AuditObligationHandler.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AuditObligationHandler.java
new file mode 100755
index 0000000..64c6c41
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AuditObligationHandler.java
@@ -0,0 +1,37 @@
+package org.openliberty.openaz.pepapi.std.test.obligation;

+

+import junit.framework.Assert;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.openliberty.openaz.pepapi.Obligation;

+import org.openliberty.openaz.pepapi.ObligationHandler;

+import org.openliberty.openaz.pepapi.ObligationStore;

+

+import java.util.Set;

+

+public class AuditObligationHandler implements ObligationHandler {

+	

+	private static Log log = LogFactory.getLog(AuditObligationHandler.class);

+	

+	private ObligationStore obligationStore;

+	

+	public void enforce() {

+		Set<Obligation> auditOblgSet = obligationStore.getHandlerObligations(this.getClass());

+		Assert.assertEquals(true, auditOblgSet.size() == 1);

+		Obligation auditOblg = obligationStore.getHandlerObligationById(

+				this.getClass(),

+				"urn:oasis:names:tc:xacml:2.0:obligation:audit");

+		Assert.assertNotNull(auditOblg);

+		log.info(auditOblg.getId());

+	}

+

+	@Override

+	public boolean match(Obligation t) {

+		return t.getId().equals("urn:oasis:names:tc:xacml:2.0:obligation:audit");

+	}

+

+	@Override

+	public void setObligationStore(ObligationStore obligationStore) {

+		this.obligationStore = obligationStore;

+	}

+}

diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/CatchAllObligationHandler.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/CatchAllObligationHandler.java
new file mode 100755
index 0000000..68732f3
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/CatchAllObligationHandler.java
@@ -0,0 +1,41 @@
+package org.openliberty.openaz.pepapi.std.test.obligation;

+

+import junit.framework.Assert;

+import org.openliberty.openaz.pepapi.Obligation;

+import org.openliberty.openaz.pepapi.ObligationHandler;

+import org.openliberty.openaz.pepapi.ObligationStore;

+

+import java.util.HashSet;

+import java.util.Set;

+

+

+public class CatchAllObligationHandler implements ObligationHandler {

+	

+	private ObligationStore obligationStore;

+	

+	public void enforce() {

+		Set<Obligation> obligationSet = obligationStore.getHandlerObligations(this.getClass());

+		if(obligationSet.size() == 2) {

+			Set<String> obligationIds = new HashSet<String>();

+			for(Obligation oblg: obligationSet){

+				obligationIds.add(oblg.getId());

+			}

+			Assert.assertTrue(obligationIds.contains("urn:oasis:names:tc:xacml:2.0:obligation:obligation-1"));

+			Assert.assertTrue(obligationIds.contains("urn:oasis:names:tc:xacml:2.0:obligation:obligation-2"));

+		}else {

+			Assert.assertFalse(true);

+		}

+		

+	}

+

+	@Override

+	public boolean match(Obligation obligation) {

+		return true;

+	}

+

+	@Override

+	public void setObligationStore(ObligationStore obligationStore) {

+		this.obligationStore = obligationStore;

+	}

+

+}

diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/FilteringObligationHandler.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/FilteringObligationHandler.java
new file mode 100755
index 0000000..427b1e3
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/FilteringObligationHandler.java
@@ -0,0 +1,45 @@
+package org.openliberty.openaz.pepapi.std.test.obligation;

+

+import junit.framework.Assert;

+import org.openliberty.openaz.pepapi.Obligation;

+import org.openliberty.openaz.pepapi.ObligationHandler;

+import org.openliberty.openaz.pepapi.ObligationStore;

+

+import java.util.Map;

+import java.util.Set;

+

+public class FilteringObligationHandler implements ObligationHandler {

+	

+	private ObligationStore obligationStore;

+	

+	public void enforce() {

+		Set<Obligation> obligationSet = obligationStore.getHandlerObligations(this.getClass());

+		if(obligationSet.size() == 1) {

+			for(Obligation obligation: obligationSet) {

+				Assert.assertEquals("urn:oasis:names:tc:xacml:2.0:obligation:obligation-1", 

+						obligation.getId());

+			}

+		}else {

+			Assert.assertFalse(true);

+		}

+	}

+

+	@Override

+	public boolean match(Obligation obligation) {

+		Map<String, Object[]> map = obligation.getAttributeMap();

+		if(map.containsKey("jpmc:obligation:obligation-type")) {

+			Object[] values = map.get("jpmc:obligation:obligation-type");

+			if(values != null && values.length != 0) {

+				for(Object value: values) {

+					return value.equals("Filtering");

+				}

+			}

+		}

+		return false;

+	}

+

+	@Override

+	public void setObligationStore(ObligationStore obligationStore) {

+		this.obligationStore = obligationStore;

+	}

+}

diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/RedactionObligationHandler.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/RedactionObligationHandler.java
new file mode 100755
index 0000000..7a262b0
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/RedactionObligationHandler.java
@@ -0,0 +1,37 @@
+package org.openliberty.openaz.pepapi.std.test.obligation;

+

+import junit.framework.Assert;

+import org.openliberty.openaz.pepapi.Obligation;

+import org.openliberty.openaz.pepapi.ObligationHandler;

+import org.openliberty.openaz.pepapi.ObligationStore;

+

+import java.util.Map;

+import java.util.Set;

+

+public class RedactionObligationHandler implements ObligationHandler {

+	

+	private ObligationStore obligationStore;

+	

+	public void enforce() {

+		Set<Obligation> obligationSet = obligationStore.getHandlerObligations(this.getClass());

+		if(obligationSet.size() == 1) {

+			for(Obligation obligation: obligationSet) {

+				Assert.assertEquals("urn:oasis:names:tc:xacml:2.0:obligation:obligation-2", 

+						obligation.getId());

+			}

+		}else {

+			Assert.assertFalse(true);

+		}

+	}

+

+	@Override

+	public boolean match(Obligation obligation) {

+		Map<String, Object[]> map = obligation.getAttributeMap();

+		return map.containsKey("urn:oasis:names:tc:xacml:1.0:subject:age");

+	}

+

+	@Override

+	public void setObligationStore(ObligationStore obligationStore) {

+		this.obligationStore = obligationStore;

+	}

+}

diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/util/AzInvoker.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/util/AzInvoker.java
new file mode 100755
index 0000000..e6b524a
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/util/AzInvoker.java
@@ -0,0 +1,53 @@
+package org.openliberty.openaz.pepapi.std.test.util;

+

+import org.openliberty.openaz.pepapi.PepAgent;

+import org.openliberty.openaz.pepapi.PepResponse;

+

+import java.util.concurrent.Callable;

+

+

+public class AzInvoker implements Callable<String> {

+	

+	private final PepAgent pepAgent;

+	

+	private final Object subject;

+	

+	private final Object action;

+	

+	private final Object resource;

+	

+	private final long sleepDuration;

+	

+	private final HasResult handler;

+	

+	public AzInvoker(PepAgent pepAgent, Object subject, Object action,

+			Object resource, HasResult handler, long sleepDuration) {

+		this.pepAgent = pepAgent;

+		this.subject = subject;

+		this.action = action;

+		this.resource = resource;

+		this.handler = handler;

+		this.sleepDuration = sleepDuration;

+	}

+	

+	private String invoke()throws InterruptedException{

+		PepResponse response = pepAgent.decide(subject, action, resource);

+		if(response != null){

+			response.allowed();

+		}

+		Thread.sleep(this.sleepDuration);

+		return handler.getResult();

+	}

+	

+	public String call() throws Exception {

+		return invoke();

+	}

+

+	public long getSleepDuration() {

+		return sleepDuration;

+	}

+

+	public HasResult getPep() {

+		return handler;

+	}

+}

diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/util/HasResult.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/util/HasResult.java
new file mode 100755
index 0000000..c22258f
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/util/HasResult.java
@@ -0,0 +1,7 @@
+package org.openliberty.openaz.pepapi.std.test.util;

+

+public interface HasResult {

+	

+	public String getResult();

+	

+}

diff --git a/openaz-pep/src/test/resources/log4j.xml b/openaz-pep/src/test/resources/log4j.xml
new file mode 100755
index 0000000..ff481f9
--- /dev/null
+++ b/openaz-pep/src/test/resources/log4j.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" ?>

+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

+<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>

+

+   <appender name="consoleAppender" class="org.apache.log4j.ConsoleAppender">

+      <layout class="org.apache.log4j.PatternLayout">

+         <param name="ConversionPattern" value="%d{HH:mm:ss.SSS} [%t] %5p %c{1} - %m%n"/>

+      </layout>

+   </appender>

+

+   <appender name="fileAppender" class="org.apache.log4j.RollingFileAppender">

+      <param name="append" value="false"/>

+      <param name="file" value="target/openaz-junit-tests.log"/>

+      <layout class="org.apache.log4j.PatternLayout">

+         <param name="ConversionPattern" value="%d{HH:mm:ss.SSS} [%t] %5p %c{1} - %m%n"/>

+      </layout>

+   </appender>

+   

+   <logger name="org.openliberty.openaz">

+   		<level value="debug"/>

+   </logger>

+

+   <logger name="org.springframework">

+      <level value="error"/>

+   </logger>

+

+   <root>

+      <level value="debug"/>

+      <appender-ref ref="consoleAppender"/>

+     <!-- <appender-ref ref="fileAppender"/> -->

+   </root>

+

+</log4j:configuration>
\ No newline at end of file
diff --git a/openaz-pep/src/test/resources/policies/TestPolicy001.xml b/openaz-pep/src/test/resources/policies/TestPolicy001.xml
new file mode 100755
index 0000000..4f2a711
--- /dev/null
+++ b/openaz-pep/src/test/resources/policies/TestPolicy001.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>

+<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" PolicyId="urn:oasis:names:tc:xacml:2.0:test001:policy"

+        RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-overrides" Version="1.0" xsi:schemaLocation="urn:oasis:names:tc:xacml:3.0:policy:schema:os access_control-xacml-2.0-policy-schema-os.xsd">

+    <Description></Description>

+    <Target/>

+    <Rule RuleId="urn:oasis:names:tc:xacml:1.0:test001:rule-1" Effect="Permit">

+        <Description>

+            Julius Hibbert can read or write Bart Simpson's medical record.

+        </Description>

+        <Target>

+            <AnyOf>

+                <AllOf>

+                    <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                        <AttributeValue

+                            DataType="http://www.w3.org/2001/XMLSchema#string">Julius Hibbert</AttributeValue>

+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"

+                            AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"

+                            DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>

+                    </Match>

+                </AllOf>

+            </AnyOf>

+            <AnyOf>

+                <AllOf>

+                    <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                        <AttributeValue

+                            DataType="http://www.w3.org/2001/XMLSchema#string">http://medico.com/record/patient/BartSimpson</AttributeValue>

+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"

+                            AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id"

+                            DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>

+                    </Match>

+                </AllOf>

+            </AnyOf>

+            <AnyOf>

+                <AllOf>

+                    <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                        <AttributeValue

+                            DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue>

+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"

+                            AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"

+                            DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>

+                    </Match>

+                </AllOf>

+                <AllOf>

+                    <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                        <AttributeValue

+                            DataType="http://www.w3.org/2001/XMLSchema#string">write</AttributeValue>

+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"

+                            AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"

+                            DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>

+                    </Match>

+                </AllOf>

+            </AnyOf>

+        </Target>

+    </Rule>

+</Policy>

diff --git a/openaz-pep/src/test/resources/policies/TestPolicy002.xml b/openaz-pep/src/test/resources/policies/TestPolicy002.xml
new file mode 100755
index 0000000..d0308c9
--- /dev/null
+++ b/openaz-pep/src/test/resources/policies/TestPolicy002.xml
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<Policy

+      xmlns="urn:oasis:names:tc:xacml:2.0:policy:schema:os"

+      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

+      PolicyId="urn:oasis:names:tc:xacml:1.0:conformance-test:IIA2:policy"

+      RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:deny-overrides">

+    <Description>

+        Policy for Conformance Test IIA001.

+    </Description>

+    <Target/>

+    <Rule

+          RuleId="urn:oasis:names:tc:xacml:1.0:test-2:rule-1"

+          Effect="Permit">

+        <Description>

+            Physicians can read or write Bart Simpson's medical record.

+        </Description>

+        <Target>

+            <Subjects>

+                <Subject>

+                    <SubjectMatch

+                          MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                        <AttributeValue

+                              DataType="http://www.w3.org/2001/XMLSchema#string">Physician</AttributeValue>

+                        <SubjectAttributeDesignator

+                              AttributeId="urn:oasis:names:tc:xacml:1.0:subject:role-id"

+                              DataType="http://www.w3.org/2001/XMLSchema#string"/>

+                    </SubjectMatch>

+                </Subject>

+            </Subjects>

+            <Resources>

+                <Resource>

+                    <ResourceMatch

+                          MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                        <AttributeValue

+                              DataType="http://www.w3.org/2001/XMLSchema#string">http://medico.com/record/patient/BartSimpson</AttributeValue>

+                        <ResourceAttributeDesignator

+                              AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id"

+                              DataType="http://www.w3.org/2001/XMLSchema#string"/>

+                    </ResourceMatch>

+                </Resource>

+            </Resources>

+            <Actions>

+                <Action>

+                    <ActionMatch

+                          MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                        <AttributeValue

+                              DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue>

+                        <ActionAttributeDesignator

+                              AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"

+                              DataType="http://www.w3.org/2001/XMLSchema#string"/>

+                    </ActionMatch>

+                </Action>

+                <Action>

+                    <ActionMatch

+                          MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                        <AttributeValue

+                              DataType="http://www.w3.org/2001/XMLSchema#string">write</AttributeValue>

+                        <ActionAttributeDesignator

+                              AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"

+                              DataType="http://www.w3.org/2001/XMLSchema#string"/>

+                    </ActionMatch>

+                </Action>

+            </Actions>

+        </Target>

+    </Rule>

+    <Rule

+          RuleId="urn:oasis:names:tc:xacml:1.0:test-2:rule-2"

+          Effect="Permit">

+        <Description>

+           Patient is allowed to read his/her medical record.

+        </Description>

+        <Target>

+            <Subjects>

+                <Subject>

+                    <SubjectMatch

+                          MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                        <AttributeValue

+                              DataType="http://www.w3.org/2001/XMLSchema#string">Patient</AttributeValue>

+                        <SubjectAttributeDesignator

+                              AttributeId="urn:oasis:names:tc:xacml:1.0:subject:role-id"

+                              DataType="http://www.w3.org/2001/XMLSchema#string"/>

+                    </SubjectMatch>

+                </Subject>

+            </Subjects>

+            <Resources>

+                <Resource>

+                    <ResourceMatch

+                          MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                        <AttributeValue

+                              DataType="http://www.w3.org/2001/XMLSchema#string">http://medico.com/record/patient/BartSimpson</AttributeValue>

+                        <ResourceAttributeDesignator

+                              AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id"

+                              DataType="http://www.w3.org/2001/XMLSchema#string"/>

+                    </ResourceMatch>

+                </Resource>

+            </Resources>

+            <Actions>

+                <Action>

+                    <ActionMatch

+                          MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                        <AttributeValue

+                              DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue>

+                        <ActionAttributeDesignator

+                              AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"

+                              DataType="http://www.w3.org/2001/XMLSchema#string"/>

+                    </ActionMatch>

+                </Action>

+            </Actions>

+        </Target>

+        <Condition>

+        	<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+        		<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">

+					<ResourceAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-owner" 

+								DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false" />

+				</Apply>

+				<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">

+					<SubjectAttributeDesignator

+						AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"

+						DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"

+						SubjectCategory="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" />

+				</Apply>

+        	</Apply>

+        </Condition>

+    </Rule>

+</Policy>

diff --git a/openaz-pep/src/test/resources/policies/TestPolicy003.xml b/openaz-pep/src/test/resources/policies/TestPolicy003.xml
new file mode 100755
index 0000000..f730e34
--- /dev/null
+++ b/openaz-pep/src/test/resources/policies/TestPolicy003.xml
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" PolicyId="urn:oasis:names:tc:xacml:2.0:test003:policy"

+        RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-overrides" Version="1.0" xsi:schemaLocation="urn:oasis:names:tc:xacml:3.0:policy:schema:os access_control-xacml-2.0-policy-schema-os.xsd">

+    <Description></Description>

+    <Target/>

+    <Rule RuleId="urn:oasis:names:tc:xacml:2.0:test003:rule1" Effect="Permit">

+        <Target>

+            <AnyOf>

+                <AllOf>

+                    <Match

+                          MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                        <AttributeValue

+                              DataType="http://www.w3.org/2001/XMLSchema#string">John Smith</AttributeValue>

+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"

+                              AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"

+                              DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>

+                    </Match>

+                </AllOf>

+            </AnyOf>

+            <AnyOf>

+                <AllOf>

+                    <Match

+                          MatchId="urn:oasis:names:tc:xacml:1.0:function:anyURI-equal">

+                        <AttributeValue

+                              DataType="http://www.w3.org/2001/XMLSchema#anyURI">file://repository/classified/abc</AttributeValue>

+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"

+                              AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id"

+                              DataType="http://www.w3.org/2001/XMLSchema#anyURI" MustBePresent="false"/>

+                    </Match>

+                </AllOf>

+            </AnyOf>

+            <AnyOf>

+                <AllOf>

+                    <Match

+                          MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                        <AttributeValue

+                              DataType="http://www.w3.org/2001/XMLSchema#string">view</AttributeValue>

+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"

+                              AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"

+                              DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>

+                    </Match>

+                </AllOf>

+            </AnyOf>

+        </Target>

+    </Rule>

+     <Rule RuleId="urn:oasis:names:tc:xacml:2.0:test003:rule2" Effect="Permit">

+         <Target>

+             <AnyOf>

+                 <AllOf>

+                     <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                         <AttributeValue

+                            DataType="http://www.w3.org/2001/XMLSchema#string">John Smith</AttributeValue>

+                         <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"

+                            AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"

+                            DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>

+                     </Match>

+                 </AllOf>

+             </AnyOf>

+             <AnyOf>

+                 <AllOf>

+                     <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:anyURI-equal">

+                         <AttributeValue

+                            DataType="http://www.w3.org/2001/XMLSchema#anyURI">file://repository/classified/xyz</AttributeValue>

+                         <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"

+                            AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id"

+                            DataType="http://www.w3.org/2001/XMLSchema#anyURI" MustBePresent="false"/>

+                     </Match>

+                 </AllOf>

+             </AnyOf>

+             <AnyOf>

+                 <AllOf>

+                     <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                         <AttributeValue

+                            DataType="http://www.w3.org/2001/XMLSchema#string">view</AttributeValue>

+                         <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"

+                            AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"

+                            DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>

+                     </Match>

+                 </AllOf>

+             </AnyOf>

+         </Target>

+    </Rule>

+    <Rule RuleId="urn:oasis:names:tc:xacml:1.0:conformance-test:IIA3:rule3" Effect="Permit">

+        <Target>

+            <AnyOf>

+                <AllOf>

+                    <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                        <AttributeValue

+                            DataType="http://www.w3.org/2001/XMLSchema#string">John Smith</AttributeValue>

+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"

+                            AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"

+                            DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>

+                    </Match>

+                </AllOf>

+            </AnyOf>

+            <AnyOf>

+                <AllOf>

+                    <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:integer-equal">

+                        <AttributeValue

+                              DataType="http://www.w3.org/2001/XMLSchema#integer">101</AttributeValue>

+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"

+                              AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id"

+                              DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="false"/>

+                    </Match>

+                </AllOf>

+            </AnyOf>

+            <AnyOf>

+                <AllOf>

+                    <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                        <AttributeValue

+                            DataType="http://www.w3.org/2001/XMLSchema#string">view</AttributeValue>

+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"

+                            AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"

+                            DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>

+                    </Match>

+                </AllOf>

+            </AnyOf>

+        </Target>

+    </Rule>

+</Policy>

diff --git a/openaz-pep/src/test/resources/policies/TestPolicy004.xml b/openaz-pep/src/test/resources/policies/TestPolicy004.xml
new file mode 100755
index 0000000..83ec917
--- /dev/null
+++ b/openaz-pep/src/test/resources/policies/TestPolicy004.xml
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>

+<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" PolicyId="urn:oasis:names:tc:xacml:2.0:test004:policy"

+        RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-overrides" Version="1.0" xsi:schemaLocation="urn:oasis:names:tc:xacml:3.0:policy:schema:os access_control-xacml-2.0-policy-schema-os.xsd">

+    <Description></Description>

+    <Target/>

+    <Rule

+          RuleId="urn:oasis:names:tc:xacml:1.0:mapper-test:rule1"

+          Effect="Permit">

+        <Description></Description>

+        <Target>

+        	<AnyOf>

+                <AllOf>

+                    <Match

+                          MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                        <AttributeValue

+                              DataType="http://www.w3.org/2001/XMLSchema#string">ROLE_DOCUMENT_WRITER</AttributeValue>

+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"

+                              AttributeId="urn:oasis:names:tc:xacml:1.0:subject:role-id"

+                              DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>

+                    </Match>

+                </AllOf>

+            </AnyOf>

+            <AnyOf>

+                <AllOf>

+                    <Match

+                          MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                        <AttributeValue

+                              DataType="http://www.w3.org/2001/XMLSchema#string">Document</AttributeValue>

+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"

+                              AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-type"

+                              DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>

+                    </Match>

+                </AllOf>

+            </AnyOf>

+            <AnyOf>

+                <AllOf>

+                    <Match

+                          MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                        <AttributeValue

+                              DataType="http://www.w3.org/2001/XMLSchema#string">write</AttributeValue>

+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"

+                              AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"

+                              DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>

+                    </Match>

+                </AllOf>

+            </AnyOf>

+        </Target>

+        <Condition>

+        	<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+        		<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">

+					<AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"

+                        AttributeId="jpmc:document:document-owner"

+                        DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false" />

+				</Apply>

+				<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">

+					<AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"

+						AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"

+						DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false" />

+				</Apply>

+        	</Apply>

+        </Condition>

+    </Rule>

+    <Rule

+          RuleId="urn:oasis:names:tc:xacml:1.0:mapper-test:rule2"

+          Effect="Permit">

+        <Description></Description>

+        <Target>

+            <AnyOf>

+                <AllOf>

+                    <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                        <AttributeValue

+                            DataType="http://www.w3.org/2001/XMLSchema#string">ROLE_DOCUMENT_READER</AttributeValue>

+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"

+                            AttributeId="urn:oasis:names:tc:xacml:1.0:subject:role-id"

+                            DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>

+                    </Match>

+                </AllOf>

+            </AnyOf>

+            <AnyOf>

+                <AllOf>

+                    <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Document</AttributeValue>

+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"

+                            AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-type"

+                            DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>

+                    </Match>

+                </AllOf>

+            </AnyOf>

+            <AnyOf>

+                <AllOf>

+                    <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                        <AttributeValue

+                            DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue>

+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"

+                            AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"

+                            DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>

+                    </Match>

+                </AllOf>

+            </AnyOf>

+        </Target>

+        <Condition>

+        	<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+        		<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">

+					<AttributeDesignator AttributeId="jpmc:client:country-of-domicile"

+                        Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"

+                        DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false" />

+				</Apply>

+				<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">

+					<AttributeDesignator AttributeId="jpmc:request-context:country"

+                        Category="urn:oasis:names:tc:xacml:3.0:attribute-category:environment"

+						DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false" />

+				</Apply>

+        	</Apply>

+        </Condition>

+    </Rule>

+</Policy>

diff --git a/openaz-pep/src/test/resources/policies/TestPolicy005.xml b/openaz-pep/src/test/resources/policies/TestPolicy005.xml
new file mode 100755
index 0000000..e8d43b5
--- /dev/null
+++ b/openaz-pep/src/test/resources/policies/TestPolicy005.xml
@@ -0,0 +1,190 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<PolicySet

+      xmlns="urn:oasis:names:tc:xacml:2.0:policy:schema:os"

+      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

+      xsi:schemaLocation="urn:oasis:names:tc:xacml:2.0:policy:schema:os

+        access_control-xacml-2.0-policy-schema-os.xsd"

+      PolicySetId="urn:oasis:names:tc:xacml:2.0:test005:policyset"

+      PolicyCombiningAlgId="urn:oasis:names:tc:xacml:1.0:policy-combining-algorithm:first-applicable">

+    <Description>

+        PolicySet for Test 005.

+    </Description>

+    <Target/>

+    <Policy PolicyId="urn:oasis:names:tc:xacml:2.0:test005:policy1"

+          RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">

+        <Description>

+            Policy for Test 005.

+        </Description>

+        <Target/>

+        <Rule RuleId="urn:oasis:names:tc:xacml:2.0:test005:rule1"

+              Effect="Permit">

+            <Target>

+                <Subjects>

+                    <Subject>

+                        <SubjectMatch

+                              MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                            <AttributeValue

+                                  DataType="http://www.w3.org/2001/XMLSchema#string">Physician</AttributeValue>

+                            <SubjectAttributeDesignator

+                                  AttributeId="urn:oasis:names:tc:xacml:1.0:subject:role-id"

+                                  DataType="http://www.w3.org/2001/XMLSchema#string"/>

+                        </SubjectMatch>

+                    </Subject>

+                </Subjects>

+                <Resources>

+	                <Resource>

+	                    <ResourceMatch

+	                          MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+	                        <AttributeValue

+	                              DataType="http://www.w3.org/2001/XMLSchema#string">PatientMedicalRecord</AttributeValue>

+	                        <ResourceAttributeDesignator

+	                              AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-type"

+	                              DataType="http://www.w3.org/2001/XMLSchema#string"/>

+	                    </ResourceMatch>

+	                </Resource>

+	            </Resources>

+	            <Actions>

+	                <Action>

+	                    <ActionMatch

+	                          MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+	                        <AttributeValue

+	                              DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue>

+	                        <ActionAttributeDesignator

+	                              AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"

+	                              DataType="http://www.w3.org/2001/XMLSchema#string"/>

+	                    </ActionMatch>

+	                </Action>

+	            </Actions>

+            </Target>

+        </Rule>

+	    <Obligations>

+	        <Obligation

+	            ObligationId="urn:oasis:names:tc:xacml:2.0:obligation:simpletest"

+	            FulfillOn="Permit">

+	             <AttributeAssignment

+	                AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"

+	                DataType="http://www.w3.org/2001/XMLSchema#string">EVAL_SUBJECT_ATTRIBUTE</AttributeAssignment>

+	        </Obligation>

+	    </Obligations>

+    </Policy>

+    <Policy PolicyId="urn:oasis:names:tc:xacml:2.0:test005:policy2"

+          RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">

+        <Description>

+            Policy for Test 005.

+        </Description>

+        <Target/>

+        <Rule RuleId="urn:oasis:names:tc:xacml:2.0:test005:rule2"

+              Effect="Permit">

+            <Target>

+                <Subjects>

+                    <Subject>

+                        <SubjectMatch

+                              MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                            <AttributeValue

+                                  DataType="http://www.w3.org/2001/XMLSchema#string">Patient</AttributeValue>

+                            <SubjectAttributeDesignator

+                                  AttributeId="urn:oasis:names:tc:xacml:1.0:subject:role-id"

+                                  DataType="http://www.w3.org/2001/XMLSchema#string"/>

+                        </SubjectMatch>

+                    </Subject>

+                </Subjects>

+	            <Resources>

+	                <Resource>

+	                    <ResourceMatch

+	                          MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+	                        <AttributeValue

+	                              DataType="http://www.w3.org/2001/XMLSchema#string">PatientMedicalRecord</AttributeValue>

+	                        <ResourceAttributeDesignator

+	                              AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-type"

+	                              DataType="http://www.w3.org/2001/XMLSchema#string"/>

+	                    </ResourceMatch>

+	                </Resource>

+	            </Resources>

+	            <Actions>

+	                <Action>

+	                    <ActionMatch

+	                          MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+	                        <AttributeValue

+	                              DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue>

+	                        <ActionAttributeDesignator

+	                              AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"

+	                              DataType="http://www.w3.org/2001/XMLSchema#string"/>

+	                    </ActionMatch>

+	                </Action>

+	            </Actions>

+            </Target>

+        </Rule>

+	    <Obligations>

+	        <Obligation

+	            ObligationId="urn:oasis:names:tc:xacml:2.0:obligation:age-restriction"

+	            FulfillOn="Permit">

+	            <AttributeAssignment

+	                AttributeId="urn:oasis:names:tc:xacml:1.0:subject:age"

+	                DataType="http://www.w3.org/2001/XMLSchema#string">EVAL_SUBJECT_ATTRIBUTE</AttributeAssignment>

+	        </Obligation>

+	        <Obligation

+	            ObligationId="urn:oasis:names:tc:xacml:2.0:obligation:audit"

+	            FulfillOn="Permit"/>

+	    </Obligations>

+    </Policy>

+    <Policy PolicyId="urn:oasis:names:tc:xacml:2.0:test005:policy3"

+          RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">

+        <Description>

+            Policy for Test 005.

+        </Description>

+        <Target/>

+        <Rule RuleId="urn:oasis:names:tc:xacml:2.0:test005:rule3"

+              Effect="Permit">

+            <Target>

+                <Subjects>

+                    <Subject>

+                        <SubjectMatch

+                              MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                            <AttributeValue

+                                  DataType="http://www.w3.org/2001/XMLSchema#string">InsuranceAgent</AttributeValue>

+                            <SubjectAttributeDesignator

+                                  AttributeId="urn:oasis:names:tc:xacml:1.0:subject:role-id"

+                                  DataType="http://www.w3.org/2001/XMLSchema#string"/>

+                        </SubjectMatch>

+                    </Subject>

+                </Subjects>

+                <Resources>

+	                <Resource>

+	                    <ResourceMatch

+	                          MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+	                        <AttributeValue

+	                              DataType="http://www.w3.org/2001/XMLSchema#string">PatientMedicalRecord</AttributeValue>

+	                        <ResourceAttributeDesignator

+	                              AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-type"

+	                              DataType="http://www.w3.org/2001/XMLSchema#string"/>

+	                    </ResourceMatch>

+	                </Resource>

+	            </Resources>

+	            <Actions>

+	                <Action>

+	                    <ActionMatch

+	                          MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+	                        <AttributeValue

+	                              DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue>

+	                        <ActionAttributeDesignator

+	                              AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"

+	                              DataType="http://www.w3.org/2001/XMLSchema#string"/>

+	                    </ActionMatch>

+	                </Action>

+	            </Actions>

+            </Target>

+        </Rule>

+	    <Obligations>

+	        <Obligation

+	            ObligationId="urn:oasis:names:tc:xacml:2.0:obligation:access-restriction"

+	            FulfillOn="Permit">

+	            <AttributeAssignment

+	                AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-access-group"

+	                DataType="http://www.w3.org/2001/XMLSchema#string">EVAL_RESOURCE_ATTRIBUTE</AttributeAssignment>

+	            <AttributeAssignment

+	                AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"

+	                DataType="http://www.w3.org/2001/XMLSchema#string">EVAL_SUBJECT_ATTRIBUTE</AttributeAssignment>

+	        </Obligation>

+	    </Obligations>

+    </Policy>

+</PolicySet>

diff --git a/openaz-pep/src/test/resources/policies/TestPolicy006.xml b/openaz-pep/src/test/resources/policies/TestPolicy006.xml
new file mode 100755
index 0000000..d609e58
--- /dev/null
+++ b/openaz-pep/src/test/resources/policies/TestPolicy006.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<PolicySet

+      xmlns="urn:oasis:names:tc:xacml:2.0:policy:schema:os"

+      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

+      xsi:schemaLocation="urn:oasis:names:tc:xacml:2.0:policy:schema:os

+        access_control-xacml-2.0-policy-schema-os.xsd"

+      PolicySetId="urn:oasis:names:tc:xacml:2.0:test005:policyset"

+      PolicyCombiningAlgId="urn:oasis:names:tc:xacml:1.0:policy-combining-algorithm:first-applicable">

+    <Description>

+        PolicySet for Test 005.

+    </Description>

+    <Target/>

+    <Policy PolicyId="urn:oasis:names:tc:xacml:2.0:test005:policy1"

+          RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">

+        <Description>

+            Policy for Test 005.

+        </Description>

+        <Target/>

+        <Rule RuleId="urn:oasis:names:tc:xacml:2.0:test005:rule1"

+              Effect="Permit">

+            <Target>

+                <Subjects>

+                    <Subject>

+                        <SubjectMatch

+                              MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                            <AttributeValue

+                                  DataType="http://www.w3.org/2001/XMLSchema#string">John Smith</AttributeValue>

+                            <SubjectAttributeDesignator

+                                  AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"

+                                  DataType="http://www.w3.org/2001/XMLSchema#string"/>

+                        </SubjectMatch>

+                    </Subject>

+                </Subjects>

+                <Resources>

+	                <Resource>

+	                    <ResourceMatch

+	                          MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+	                        <AttributeValue

+	                              DataType="http://www.w3.org/2001/XMLSchema#string">resource1</AttributeValue>

+	                        <ResourceAttributeDesignator

+	                              AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id"

+	                              DataType="http://www.w3.org/2001/XMLSchema#string"/>

+	                    </ResourceMatch>

+	                </Resource>

+	            </Resources>

+	            <Actions>

+	                <Action>

+	                    <ActionMatch

+	                          MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+	                        <AttributeValue

+	                              DataType="http://www.w3.org/2001/XMLSchema#string">view</AttributeValue>

+	                        <ActionAttributeDesignator

+	                              AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"

+	                              DataType="http://www.w3.org/2001/XMLSchema#string"/>

+	                    </ActionMatch>

+	                </Action>

+	            </Actions>

+            </Target>

+        </Rule>

+	    <Obligations>

+	        <Obligation

+	            ObligationId="urn:oasis:names:tc:xacml:2.0:obligation:obligation-1"

+	            FulfillOn="Permit">

+	            <AttributeAssignment

+	                AttributeId="jpmc:obligation:obligation-type"

+	                DataType="http://www.w3.org/2001/XMLSchema#string">Filtering</AttributeAssignment>

+	             <AttributeAssignment

+	                AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"

+	                DataType="http://www.w3.org/2001/XMLSchema#string">EVAL_SUBJECT_ATTRIBUTE</AttributeAssignment>

+	        </Obligation>

+	         <Obligation

+	            ObligationId="urn:oasis:names:tc:xacml:2.0:obligation:obligation-2"

+	            FulfillOn="Permit">

+	            <AttributeAssignment

+	                AttributeId="urn:oasis:names:tc:xacml:1.0:subject:age"

+	                DataType="http://www.w3.org/2001/XMLSchema#string">EVAL_SUBJECT_ATTRIBUTE</AttributeAssignment>

+	        </Obligation>

+	    </Obligations>

+    </Policy>

+</PolicySet>

diff --git a/openaz-pep/src/test/resources/properties/testapi.xacml.properties b/openaz-pep/src/test/resources/properties/testapi.xacml.properties
new file mode 100755
index 0000000..b45d2c1
--- /dev/null
+++ b/openaz-pep/src/test/resources/properties/testapi.xacml.properties
@@ -0,0 +1,20 @@
+# Default XACML Properties File
+# Standard API Factories
+#
+xacml.dataTypeFactory=com.att.research.xacml.std.StdDataTypeFactory
+xacml.pdpEngineFactory=com.att.research.xacmlatt.pdp.ATTPDPEngineFactory
+xacml.pepEngineFactory=com.att.research.xacml.std.pep.StdEngineFactory
+xacml.pipFinderFactory=com.att.research.xacml.std.pip.StdPIPFinderFactory
+
+# AT&T PDP Implementation Factories
+#
+xacml.att.evaluationContextFactory=com.att.research.xacmlatt.pdp.std.StdEvaluationContextFactory
+xacml.att.combiningAlgorithmFactory=com.att.research.xacmlatt.pdp.std.StdCombiningAlgorithmFactory
+xacml.att.functionDefinitionFactory=com.att.research.xacmlatt.pdp.std.StdFunctionDefinitionFactory
+xacml.att.policyFinderFactory=com.att.research.xacmlatt.pdp.std.StdPolicyFinderFactory
+
+xacml.rootPolicies=testPolicy
+testPolicy.file=src/test/resources/policies/TestPolicy001.xml
+
+# If there is a standard policy for the engine:
+# xacml.att.stdPolicyFinderFactory.rootPolicyFile=/etc/stdpolicyset.xml
diff --git a/openaz-pep/src/test/resources/properties/testdatatypes.xacml.properties b/openaz-pep/src/test/resources/properties/testdatatypes.xacml.properties
new file mode 100755
index 0000000..cb6d77b
--- /dev/null
+++ b/openaz-pep/src/test/resources/properties/testdatatypes.xacml.properties
@@ -0,0 +1,20 @@
+# Default XACML Properties File
+# Standard API Factories
+#
+xacml.dataTypeFactory=com.att.research.xacml.std.StdDataTypeFactory
+xacml.pdpEngineFactory=com.att.research.xacmlatt.pdp.ATTPDPEngineFactory
+xacml.pepEngineFactory=com.att.research.xacml.std.pep.StdEngineFactory
+xacml.pipFinderFactory=com.att.research.xacml.std.pip.StdPIPFinderFactory
+
+# AT&T PDP Implementation Factories
+#
+xacml.att.evaluationContextFactory=com.att.research.xacmlatt.pdp.std.StdEvaluationContextFactory
+xacml.att.combiningAlgorithmFactory=com.att.research.xacmlatt.pdp.std.StdCombiningAlgorithmFactory
+xacml.att.functionDefinitionFactory=com.att.research.xacmlatt.pdp.std.StdFunctionDefinitionFactory
+xacml.att.policyFinderFactory=com.att.research.xacmlatt.pdp.std.StdPolicyFinderFactory
+
+xacml.rootPolicies=testPolicy
+testPolicy.file=src/test/resources/policies/TestPolicy003.xml
+
+# If there is a standard policy for the engine:
+# xacml.att.stdPolicyFinderFactory.rootPolicyFile=/etc/stdpolicyset.xml
diff --git a/openaz-pep/src/test/resources/properties/testmapper.xacml.properties b/openaz-pep/src/test/resources/properties/testmapper.xacml.properties
new file mode 100755
index 0000000..12e1754
--- /dev/null
+++ b/openaz-pep/src/test/resources/properties/testmapper.xacml.properties
@@ -0,0 +1,24 @@
+# Default XACML Properties File
+# Standard API Factories
+#
+xacml.dataTypeFactory=com.att.research.xacml.std.StdDataTypeFactory
+xacml.pdpEngineFactory=com.att.research.xacmlatt.pdp.ATTPDPEngineFactory
+xacml.pepEngineFactory=com.att.research.xacml.std.pep.StdEngineFactory
+xacml.pipFinderFactory=com.att.research.xacml.std.pip.StdPIPFinderFactory
+
+# AT&T PDP Implementation Factories
+#
+xacml.att.evaluationContextFactory=com.att.research.xacmlatt.pdp.std.StdEvaluationContextFactory
+xacml.att.combiningAlgorithmFactory=com.att.research.xacmlatt.pdp.std.StdCombiningAlgorithmFactory
+xacml.att.functionDefinitionFactory=com.att.research.xacmlatt.pdp.std.StdFunctionDefinitionFactory
+xacml.att.policyFinderFactory=com.att.research.xacmlatt.pdp.std.StdPolicyFinderFactory
+
+xacml.rootPolicies=testPolicy
+testPolicy.file=src/test/resources/policies/TestPolicy004.xml
+
+#pep properties
+pep.issuer=test
+pep.mapper.classes=org.openliberty.openaz.pepapi.std.test.mapper.BusinessRequestContextMapper,\
+  org.openliberty.openaz.pepapi.std.test.mapper.DocumentMapper, \
+  org.openliberty.openaz.pepapi.std.test.mapper.ClientMapper, \
+  org.openliberty.openaz.pepapi.std.test.mapper.MedicalRecordMapper
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Action.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Action.class
new file mode 100644
index 0000000..2337848
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Action.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ActionResourcePair.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ActionResourcePair.class
new file mode 100644
index 0000000..4ed0074
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ActionResourcePair.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Advice.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Advice.class
new file mode 100644
index 0000000..5663013
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Advice.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Attribute.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Attribute.class
new file mode 100644
index 0000000..3ca8211
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Attribute.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/CategoryContainer.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/CategoryContainer.class
new file mode 100644
index 0000000..55f44fa
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/CategoryContainer.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Environment.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Environment.class
new file mode 100644
index 0000000..2c2d853
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Environment.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/InvalidAnnotationException.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/InvalidAnnotationException.class
new file mode 100644
index 0000000..3c8156c
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/InvalidAnnotationException.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/MapperRegistry.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/MapperRegistry.class
new file mode 100644
index 0000000..c90e3dc
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/MapperRegistry.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/MatchAllObligationAttributes.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/MatchAllObligationAttributes.class
new file mode 100644
index 0000000..559631e
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/MatchAllObligationAttributes.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/MatchAnyObligation.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/MatchAnyObligation.class
new file mode 100644
index 0000000..b177a57
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/MatchAnyObligation.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Matchable.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Matchable.class
new file mode 100644
index 0000000..e68def5
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Matchable.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObjectMapper.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObjectMapper.class
new file mode 100644
index 0000000..f734523
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObjectMapper.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Obligation.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Obligation.class
new file mode 100644
index 0000000..58100f3
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Obligation.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObligationHandler.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObligationHandler.class
new file mode 100644
index 0000000..380ef97
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObligationHandler.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObligationHandlerRegistry.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObligationHandlerRegistry.class
new file mode 100644
index 0000000..c00f13b
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObligationHandlerRegistry.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObligationRouter.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObligationRouter.class
new file mode 100644
index 0000000..7f340b4
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObligationRouter.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObligationStore.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObligationStore.class
new file mode 100644
index 0000000..2d7c325
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObligationStore.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObligationStoreAware.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObligationStoreAware.class
new file mode 100644
index 0000000..d028684
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObligationStoreAware.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepAgent.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepAgent.class
new file mode 100644
index 0000000..867d637
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepAgent.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepAgentFactory.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepAgentFactory.class
new file mode 100644
index 0000000..ad8c396
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepAgentFactory.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepConfig.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepConfig.class
new file mode 100644
index 0000000..b99e517
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepConfig.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepException.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepException.class
new file mode 100644
index 0000000..bbf8f9f
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepException.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepRequest.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepRequest.class
new file mode 100644
index 0000000..17b60d9
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepRequest.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepRequestAttributes.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepRequestAttributes.class
new file mode 100644
index 0000000..a883e56
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepRequestAttributes.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepRequestFactory.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepRequestFactory.class
new file mode 100644
index 0000000..528ae1c
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepRequestFactory.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepResponse.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepResponse.class
new file mode 100644
index 0000000..5ca7518
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepResponse.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepResponseBehavior.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepResponseBehavior.class
new file mode 100644
index 0000000..ffae897
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepResponseBehavior.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepResponseFactory.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepResponseFactory.class
new file mode 100644
index 0000000..4e8444f
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepResponseFactory.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepResponseType.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepResponseType.class
new file mode 100644
index 0000000..f29a013
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepResponseType.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PostDecisionHandler.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PostDecisionHandler.class
new file mode 100644
index 0000000..42a8847
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PostDecisionHandler.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PreDecisionHandler.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PreDecisionHandler.class
new file mode 100644
index 0000000..f063d54
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PreDecisionHandler.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Resource.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Resource.class
new file mode 100644
index 0000000..ed02ad2
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Resource.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Subject.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Subject.class
new file mode 100644
index 0000000..4bc1534
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Subject.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/UnhandleableObligationException.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/UnhandleableObligationException.class
new file mode 100644
index 0000000..28d8c6f
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/UnhandleableObligationException.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ActionMapper.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ActionMapper.class
new file mode 100644
index 0000000..289d996
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ActionMapper.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ActionResourcePairMapper.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ActionResourcePairMapper.class
new file mode 100644
index 0000000..137c003
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ActionResourcePairMapper.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ArrayMapper.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ArrayMapper.class
new file mode 100644
index 0000000..e1d5084
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ArrayMapper.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/CategoryContainerMapper.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/CategoryContainerMapper.class
new file mode 100644
index 0000000..bdc1594
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/CategoryContainerMapper.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/CollectionMapper.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/CollectionMapper.class
new file mode 100644
index 0000000..886b01e
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/CollectionMapper.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/MatchAnyCriterion.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/MatchAnyCriterion.class
new file mode 100644
index 0000000..0d05e93
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/MatchAnyCriterion.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/MultiRequest.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/MultiRequest.class
new file mode 100644
index 0000000..c78308b
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/MultiRequest.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ObligationAttributeCriterion.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ObligationAttributeCriterion.class
new file mode 100644
index 0000000..46edec4
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ObligationAttributeCriterion.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ObligationCriteria.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ObligationCriteria.class
new file mode 100644
index 0000000..b43d1d2
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ObligationCriteria.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ObligationCriteriaBuilder.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ObligationCriteriaBuilder.class
new file mode 100644
index 0000000..e36b451
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ObligationCriteriaBuilder.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ObligationCriterion.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ObligationCriterion.class
new file mode 100644
index 0000000..4f89184
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ObligationCriterion.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ObligationIdCriterion.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ObligationIdCriterion.class
new file mode 100644
index 0000000..3bed007
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ObligationIdCriterion.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/PepUtils.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/PepUtils.class
new file mode 100644
index 0000000..25f293f
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/PepUtils.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ResourceMapper.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ResourceMapper.class
new file mode 100644
index 0000000..08ab7f2
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ResourceMapper.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdAdvice.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdAdvice.class
new file mode 100644
index 0000000..5f14c38
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdAdvice.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdMapperRegistry.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdMapperRegistry.class
new file mode 100644
index 0000000..12702eb
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdMapperRegistry.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdObligation.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdObligation.class
new file mode 100644
index 0000000..eae5972
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdObligation.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdObligationHandlerRegistry.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdObligationHandlerRegistry.class
new file mode 100644
index 0000000..992a93c
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdObligationHandlerRegistry.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdObligationRouter.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdObligationRouter.class
new file mode 100644
index 0000000..e4e7054
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdObligationRouter.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepAgent.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepAgent.class
new file mode 100644
index 0000000..835bd43
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepAgent.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepAgentFactory.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepAgentFactory.class
new file mode 100644
index 0000000..8a81c8c
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepAgentFactory.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepConfig.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepConfig.class
new file mode 100644
index 0000000..d3ffc48
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepConfig.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepRequest.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepRequest.class
new file mode 100644
index 0000000..a7d9bbc
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepRequest.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepRequestAttributes.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepRequestAttributes.class
new file mode 100644
index 0000000..465fabf
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepRequestAttributes.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepRequestFactory.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepRequestFactory.class
new file mode 100644
index 0000000..076c058
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepRequestFactory.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepResponse$1.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepResponse$1.class
new file mode 100644
index 0000000..f1db827
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepResponse$1.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepResponse.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepResponse.class
new file mode 100644
index 0000000..e5998e5
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepResponse.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepResponseFactory.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepResponseFactory.class
new file mode 100644
index 0000000..b03a334
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepResponseFactory.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/SubjectMapper.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/SubjectMapper.class
new file mode 100644
index 0000000..f759572
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/SubjectMapper.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ThreadLocalObligationStore.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ThreadLocalObligationStore.class
new file mode 100644
index 0000000..7a718e2
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ThreadLocalObligationStore.class
Binary files differ
diff --git a/openaz-pep/target/maven-archiver/pom.properties b/openaz-pep/target/maven-archiver/pom.properties
new file mode 100644
index 0000000..3c34336
--- /dev/null
+++ b/openaz-pep/target/maven-archiver/pom.properties
@@ -0,0 +1,5 @@
+#Generated by Maven
+#Tue Apr 07 07:45:26 EDT 2015
+version=0.0.1-SNAPSHOT
+groupId=org.openliberty.openaz
+artifactId=openaz-pep
diff --git a/openaz-pep/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/openaz-pep/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
new file mode 100644
index 0000000..7e4a8f3
--- /dev/null
+++ b/openaz-pep/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
@@ -0,0 +1,64 @@
+org/openliberty/openaz/pepapi/ActionResourcePair.class
+org/openliberty/openaz/pepapi/PepConfig.class
+org/openliberty/openaz/pepapi/std/ResourceMapper.class
+org/openliberty/openaz/pepapi/PepResponseType.class
+org/openliberty/openaz/pepapi/std/SubjectMapper.class
+org/openliberty/openaz/pepapi/std/StdObligation.class
+org/openliberty/openaz/pepapi/Subject.class
+org/openliberty/openaz/pepapi/MatchAllObligationAttributes.class
+org/openliberty/openaz/pepapi/std/StdPepConfig.class
+org/openliberty/openaz/pepapi/InvalidAnnotationException.class
+org/openliberty/openaz/pepapi/PepAgent.class
+org/openliberty/openaz/pepapi/PostDecisionHandler.class
+org/openliberty/openaz/pepapi/std/StdObligationRouter.class
+org/openliberty/openaz/pepapi/std/ActionResourcePairMapper.class
+org/openliberty/openaz/pepapi/std/PepUtils.class
+org/openliberty/openaz/pepapi/PreDecisionHandler.class
+org/openliberty/openaz/pepapi/std/StdPepResponseFactory.class
+org/openliberty/openaz/pepapi/PepResponse.class
+org/openliberty/openaz/pepapi/PepAgentFactory.class
+org/openliberty/openaz/pepapi/std/MatchAnyCriterion.class
+org/openliberty/openaz/pepapi/ObligationHandler.class
+org/openliberty/openaz/pepapi/ObligationStore.class
+org/openliberty/openaz/pepapi/std/StdPepAgent.class
+org/openliberty/openaz/pepapi/PepResponseFactory.class
+org/openliberty/openaz/pepapi/UnhandleableObligationException.class
+org/openliberty/openaz/pepapi/PepRequestAttributes.class
+org/openliberty/openaz/pepapi/std/StdPepAgentFactory.class
+org/openliberty/openaz/pepapi/ObligationStoreAware.class
+org/openliberty/openaz/pepapi/PepResponseBehavior.class
+org/openliberty/openaz/pepapi/std/StdPepRequestAttributes.class
+org/openliberty/openaz/pepapi/std/StdPepRequest.class
+org/openliberty/openaz/pepapi/std/StdObligationHandlerRegistry.class
+org/openliberty/openaz/pepapi/Environment.class
+org/openliberty/openaz/pepapi/ObjectMapper.class
+org/openliberty/openaz/pepapi/std/ObligationCriterion.class
+org/openliberty/openaz/pepapi/Resource.class
+org/openliberty/openaz/pepapi/Obligation.class
+org/openliberty/openaz/pepapi/std/StdPepResponse$1.class
+org/openliberty/openaz/pepapi/std/ObligationAttributeCriterion.class
+org/openliberty/openaz/pepapi/MapperRegistry.class
+org/openliberty/openaz/pepapi/std/CollectionMapper.class
+org/openliberty/openaz/pepapi/Matchable.class
+org/openliberty/openaz/pepapi/std/ActionMapper.class
+org/openliberty/openaz/pepapi/Action.class
+org/openliberty/openaz/pepapi/Advice.class
+org/openliberty/openaz/pepapi/std/ObligationCriteriaBuilder.class
+org/openliberty/openaz/pepapi/Attribute.class
+org/openliberty/openaz/pepapi/std/StdPepResponse.class
+org/openliberty/openaz/pepapi/std/ArrayMapper.class
+org/openliberty/openaz/pepapi/std/StdAdvice.class
+org/openliberty/openaz/pepapi/ObligationRouter.class
+org/openliberty/openaz/pepapi/std/ObligationCriteria.class
+org/openliberty/openaz/pepapi/std/ThreadLocalObligationStore.class
+org/openliberty/openaz/pepapi/PepRequest.class
+org/openliberty/openaz/pepapi/std/ObligationIdCriterion.class
+org/openliberty/openaz/pepapi/std/StdMapperRegistry.class
+org/openliberty/openaz/pepapi/std/StdPepRequestFactory.class
+org/openliberty/openaz/pepapi/PepRequestFactory.class
+org/openliberty/openaz/pepapi/PepException.class
+org/openliberty/openaz/pepapi/std/MultiRequest.class
+org/openliberty/openaz/pepapi/std/CategoryContainerMapper.class
+org/openliberty/openaz/pepapi/MatchAnyObligation.class
+org/openliberty/openaz/pepapi/CategoryContainer.class
+org/openliberty/openaz/pepapi/ObligationHandlerRegistry.class
diff --git a/openaz-pep/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/openaz-pep/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
new file mode 100644
index 0000000..dafd73c
--- /dev/null
+++ b/openaz-pep/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
@@ -0,0 +1,63 @@
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Attribute.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdAdvice.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationStoreAware.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationIdCriterion.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepException.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdObligation.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponseBehavior.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationRouter.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepRequestFactory.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepAgentFactory.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/PepUtils.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponseFactory.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ActionResourcePairMapper.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/CategoryContainerMapper.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Advice.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdMapperRegistry.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Environment.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/MapperRegistry.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ThreadLocalObligationStore.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PreDecisionHandler.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ResourceMapper.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Obligation.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationCriterion.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/MultiRequest.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/SubjectMapper.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Matchable.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponseType.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationCriteriaBuilder.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationCriteria.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponse.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepAgent.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Action.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepConfig.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationHandler.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ActionMapper.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationAttributeCriterion.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationHandlerRegistry.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepConfig.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepResponseFactory.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepAgent.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationStore.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepRequest.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/InvalidAnnotationException.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/MatchAnyObligation.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepAgentFactory.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ArrayMapper.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdObligationRouter.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Resource.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepRequestAttributes.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ActionResourcePair.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PostDecisionHandler.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/CollectionMapper.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepRequestFactory.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Subject.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/UnhandleableObligationException.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/CategoryContainer.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/MatchAllObligationAttributes.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepRequest.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdObligationHandlerRegistry.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepResponse.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/MatchAnyCriterion.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepRequestAttributes.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObjectMapper.java
diff --git a/openaz-pep/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst b/openaz-pep/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst
new file mode 100644
index 0000000..25cd122
--- /dev/null
+++ b/openaz-pep/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst
@@ -0,0 +1,28 @@
+org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedObligationHandler.class
+org/openliberty/openaz/pepapi/std/test/util/AzInvoker.class
+org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAccessRestrictionObligationHandler.class
+org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecordMapper.class
+org/openliberty/openaz/pepapi/std/test/obligation/FilteringObligationHandler.class
+org/openliberty/openaz/pepapi/std/test/obligation/AuditObligationHandler.class
+org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAgeRestrictionObligationHandler.class
+org/openliberty/openaz/pepapi/std/test/obligation/AgeRestrictionObligationHandler.class
+org/openliberty/openaz/pepapi/std/test/util/HasResult.class
+org/openliberty/openaz/pepapi/std/test/mapper/Client.class
+org/openliberty/openaz/pepapi/std/test/TestAPIWithPIP.class
+org/openliberty/openaz/pepapi/std/test/obligation/CatchAllObligationHandler.class
+org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedCatchAllObligationHandler.class
+org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedRedactionObligationHandler.class
+org/openliberty/openaz/pepapi/std/test/mapper/Document.class
+org/openliberty/openaz/pepapi/std/test/TestAPI.class
+org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAuditObligationHandler.class
+org/openliberty/openaz/pepapi/std/test/TestMapper.class
+org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecord.class
+org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContextMapper.class
+org/openliberty/openaz/pepapi/std/test/TestAnnotatedHandlerRegistration.class
+org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedFilteringObligationHandler.class
+org/openliberty/openaz/pepapi/std/test/TestDataTypes.class
+org/openliberty/openaz/pepapi/std/test/obligation/RedactionObligationHandler.class
+org/openliberty/openaz/pepapi/std/test/obligation/AccessRestrictionObligationHandler.class
+org/openliberty/openaz/pepapi/std/test/mapper/DocumentMapper.class
+org/openliberty/openaz/pepapi/std/test/mapper/ClientMapper.class
+org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContext.class
diff --git a/openaz-pep/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/openaz-pep/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
new file mode 100644
index 0000000..571d370
--- /dev/null
+++ b/openaz-pep/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
@@ -0,0 +1,28 @@
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/util/AzInvoker.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/FilteringObligationHandler.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecord.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AuditObligationHandler.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedObligationHandler.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/Document.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AgeRestrictionObligationHandler.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAccessRestrictionObligationHandler.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecordMapper.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedCatchAllObligationHandler.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/DocumentMapper.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/Client.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/ClientMapper.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestDataTypes.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContext.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/CatchAllObligationHandler.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedFilteringObligationHandler.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestAPIWithPIP.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAuditObligationHandler.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/RedactionObligationHandler.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedRedactionObligationHandler.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAgeRestrictionObligationHandler.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestAnnotatedHandlerRegistration.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestAPI.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AccessRestrictionObligationHandler.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContextMapper.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestMapper.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/util/HasResult.java
diff --git a/openaz-pep/target/openaz-pep-0.0.1-SNAPSHOT.jar b/openaz-pep/target/openaz-pep-0.0.1-SNAPSHOT.jar
new file mode 100644
index 0000000..b7949c2
--- /dev/null
+++ b/openaz-pep/target/openaz-pep-0.0.1-SNAPSHOT.jar
Binary files differ
diff --git a/openaz-pep/target/surefire-reports/TEST-org.openliberty.openaz.pepapi.std.test.TestAPI.xml b/openaz-pep/target/surefire-reports/TEST-org.openliberty.openaz.pepapi.std.test.TestAPI.xml
new file mode 100644
index 0000000..67ca2a1
--- /dev/null
+++ b/openaz-pep/target/surefire-reports/TEST-org.openliberty.openaz.pepapi.std.test.TestAPI.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<testsuite name="org.openliberty.openaz.pepapi.std.test.TestAPI" time="0.662" tests="4" errors="0" skipped="0" failures="0">
+  <properties>
+    <property name="idea.version" value="14.0.3"/>
+    <property name="java.runtime.name" value="Java(TM) SE Runtime Environment"/>
+    <property name="sun.boot.library.path" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib"/>
+    <property name="java.vm.version" value="24.75-b04"/>
+    <property name="gopherProxySet" value="false"/>
+    <property name="java.vm.vendor" value="Oracle Corporation"/>
+    <property name="java.vendor.url" value="http://java.oracle.com/"/>
+    <property name="path.separator" value=":"/>
+    <property name="guice.disable.misplaced.annotation.check" value="true"/>
+    <property name="java.vm.name" value="Java HotSpot(TM) 64-Bit Server VM"/>
+    <property name="file.encoding.pkg" value="sun.io"/>
+    <property name="idea.launcher.port" value="7534"/>
+    <property name="user.country" value="US"/>
+    <property name="sun.java.launcher" value="SUN_STANDARD"/>
+    <property name="sun.os.patch.level" value="unknown"/>
+    <property name="java.vm.specification.name" value="Java Virtual Machine Specification"/>
+    <property name="user.dir" value="/Users/ajith/IdeaProjects/openaz"/>
+    <property name="java.runtime.version" value="1.7.0_75-b13"/>
+    <property name="java.awt.graphicsenv" value="sun.awt.CGraphicsEnvironment"/>
+    <property name="java.endorsed.dirs" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/endorsed"/>
+    <property name="os.arch" value="x86_64"/>
+    <property name="java.io.tmpdir" value="/var/folders/xs/4h_cw5ds0bj_lpk90db3v9dr0000gn/T/"/>
+    <property name="line.separator" value="&#10;"/>
+    <property name="java.vm.specification.vendor" value="Oracle Corporation"/>
+    <property name="os.name" value="Mac OS X"/>
+    <property name="classworlds.conf" value="/Applications/apache-maven-3.1.1/bin/m2.conf"/>
+    <property name="sun.jnu.encoding" value="UTF-8"/>
+    <property name="java.library.path" value="/Users/ajith/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:."/>
+    <property name="java.specification.name" value="Java Platform API Specification"/>
+    <property name="java.class.version" value="51.0"/>
+    <property name="sun.management.compiler" value="HotSpot 64-Bit Tiered Compilers"/>
+    <property name="os.version" value="10.10.2"/>
+    <property name="user.home" value="/Users/ajith"/>
+    <property name="user.timezone" value="America/New_York"/>
+    <property name="java.awt.printerjob" value="sun.lwawt.macosx.CPrinterJob"/>
+    <property name="java.specification.version" value="1.7"/>
+    <property name="idea.launcher.bin.path" value="/Applications/IntelliJ IDEA 14 CE.app/Contents/bin"/>
+    <property name="file.encoding" value="UTF-8"/>
+    <property name="user.name" value="ajith"/>
+    <property name="java.class.path" value="/Applications/apache-maven-3.1.1/boot/plexus-classworlds-2.5.1.jar:/Applications/IntelliJ IDEA 14 CE.app/Contents/lib/idea_rt.jar"/>
+    <property name="org.slf4j.simpleLogger.defaultLogLevel" value="info"/>
+    <property name="java.vm.specification.version" value="1.7"/>
+    <property name="sun.arch.data.model" value="64"/>
+    <property name="java.home" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre"/>
+    <property name="sun.java.command" value="com.intellij.rt.execution.application.AppMain org.codehaus.classworlds.Launcher -Didea.version=14.0.3 install -rf :openaz-pep"/>
+    <property name="java.specification.vendor" value="Oracle Corporation"/>
+    <property name="user.language" value="en"/>
+    <property name="awt.toolkit" value="sun.lwawt.macosx.LWCToolkit"/>
+    <property name="java.vm.info" value="mixed mode"/>
+    <property name="java.version" value="1.7.0_75"/>
+    <property name="java.ext.dirs" value="/Users/ajith/Library/Java/Extensions:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/ext:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java"/>
+    <property name="sun.boot.class.path" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/sunrsasign.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/classes"/>
+    <property name="java.vendor" value="Oracle Corporation"/>
+    <property name="maven.home" value="/Applications/apache-maven-3.1.1"/>
+    <property name="file.separator" value="/"/>
+    <property name="java.vendor.url.bug" value="http://bugreport.sun.com/bugreport/"/>
+    <property name="sun.cpu.endian" value="little"/>
+    <property name="sun.io.unicode.encoding" value="UnicodeBig"/>
+    <property name="sun.cpu.isalist" value=""/>
+  </properties>
+  <testcase name="testMultiRequest" classname="org.openliberty.openaz.pepapi.std.test.TestAPI" time="0.629"/>
+  <testcase name="testNotApplicable" classname="org.openliberty.openaz.pepapi.std.test.TestAPI" time="0.017"/>
+  <testcase name="testPepAgent" classname="org.openliberty.openaz.pepapi.std.test.TestAPI" time="0.001"/>
+  <testcase name="testPermit" classname="org.openliberty.openaz.pepapi.std.test.TestAPI" time="0.015"/>
+</testsuite>
\ No newline at end of file
diff --git a/openaz-pep/target/surefire-reports/TEST-org.openliberty.openaz.pepapi.std.test.TestAPIWithPIP.xml b/openaz-pep/target/surefire-reports/TEST-org.openliberty.openaz.pepapi.std.test.TestAPIWithPIP.xml
new file mode 100644
index 0000000..160982b
--- /dev/null
+++ b/openaz-pep/target/surefire-reports/TEST-org.openliberty.openaz.pepapi.std.test.TestAPIWithPIP.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<testsuite name="org.openliberty.openaz.pepapi.std.test.TestAPIWithPIP" time="0" tests="4" errors="0" skipped="4" failures="0">
+  <properties>
+    <property name="idea.version" value="14.0.3"/>
+    <property name="java.runtime.name" value="Java(TM) SE Runtime Environment"/>
+    <property name="sun.boot.library.path" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib"/>
+    <property name="java.vm.version" value="24.75-b04"/>
+    <property name="gopherProxySet" value="false"/>
+    <property name="java.vm.vendor" value="Oracle Corporation"/>
+    <property name="java.vendor.url" value="http://java.oracle.com/"/>
+    <property name="path.separator" value=":"/>
+    <property name="guice.disable.misplaced.annotation.check" value="true"/>
+    <property name="java.vm.name" value="Java HotSpot(TM) 64-Bit Server VM"/>
+    <property name="file.encoding.pkg" value="sun.io"/>
+    <property name="idea.launcher.port" value="7534"/>
+    <property name="user.country" value="US"/>
+    <property name="sun.java.launcher" value="SUN_STANDARD"/>
+    <property name="sun.os.patch.level" value="unknown"/>
+    <property name="java.vm.specification.name" value="Java Virtual Machine Specification"/>
+    <property name="user.dir" value="/Users/ajith/IdeaProjects/openaz"/>
+    <property name="java.runtime.version" value="1.7.0_75-b13"/>
+    <property name="java.awt.graphicsenv" value="sun.awt.CGraphicsEnvironment"/>
+    <property name="java.endorsed.dirs" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/endorsed"/>
+    <property name="os.arch" value="x86_64"/>
+    <property name="java.io.tmpdir" value="/var/folders/xs/4h_cw5ds0bj_lpk90db3v9dr0000gn/T/"/>
+    <property name="line.separator" value="&#10;"/>
+    <property name="java.vm.specification.vendor" value="Oracle Corporation"/>
+    <property name="os.name" value="Mac OS X"/>
+    <property name="classworlds.conf" value="/Applications/apache-maven-3.1.1/bin/m2.conf"/>
+    <property name="sun.jnu.encoding" value="UTF-8"/>
+    <property name="java.library.path" value="/Users/ajith/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:."/>
+    <property name="java.specification.name" value="Java Platform API Specification"/>
+    <property name="java.class.version" value="51.0"/>
+    <property name="sun.management.compiler" value="HotSpot 64-Bit Tiered Compilers"/>
+    <property name="os.version" value="10.10.2"/>
+    <property name="user.home" value="/Users/ajith"/>
+    <property name="user.timezone" value="America/New_York"/>
+    <property name="java.awt.printerjob" value="sun.lwawt.macosx.CPrinterJob"/>
+    <property name="java.specification.version" value="1.7"/>
+    <property name="idea.launcher.bin.path" value="/Applications/IntelliJ IDEA 14 CE.app/Contents/bin"/>
+    <property name="file.encoding" value="UTF-8"/>
+    <property name="user.name" value="ajith"/>
+    <property name="java.class.path" value="/Applications/apache-maven-3.1.1/boot/plexus-classworlds-2.5.1.jar:/Applications/IntelliJ IDEA 14 CE.app/Contents/lib/idea_rt.jar"/>
+    <property name="org.slf4j.simpleLogger.defaultLogLevel" value="info"/>
+    <property name="java.vm.specification.version" value="1.7"/>
+    <property name="sun.arch.data.model" value="64"/>
+    <property name="java.home" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre"/>
+    <property name="sun.java.command" value="com.intellij.rt.execution.application.AppMain org.codehaus.classworlds.Launcher -Didea.version=14.0.3 install -rf :openaz-pep"/>
+    <property name="java.specification.vendor" value="Oracle Corporation"/>
+    <property name="user.language" value="en"/>
+    <property name="awt.toolkit" value="sun.lwawt.macosx.LWCToolkit"/>
+    <property name="java.vm.info" value="mixed mode"/>
+    <property name="java.version" value="1.7.0_75"/>
+    <property name="java.ext.dirs" value="/Users/ajith/Library/Java/Extensions:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/ext:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java"/>
+    <property name="sun.boot.class.path" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/sunrsasign.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/classes"/>
+    <property name="java.vendor" value="Oracle Corporation"/>
+    <property name="maven.home" value="/Applications/apache-maven-3.1.1"/>
+    <property name="file.separator" value="/"/>
+    <property name="java.vendor.url.bug" value="http://bugreport.sun.com/bugreport/"/>
+    <property name="sun.cpu.endian" value="little"/>
+    <property name="sun.io.unicode.encoding" value="UnicodeBig"/>
+    <property name="sun.cpu.isalist" value=""/>
+  </properties>
+  <testcase name="testMultiRequest" classname="org.openliberty.openaz.pepapi.std.test.TestAPIWithPIP" time="0">
+    <skipped/>
+  </testcase>
+  <testcase name="testNotApplicable" classname="org.openliberty.openaz.pepapi.std.test.TestAPIWithPIP" time="0">
+    <skipped/>
+  </testcase>
+  <testcase name="testPepAgent" classname="org.openliberty.openaz.pepapi.std.test.TestAPIWithPIP" time="0">
+    <skipped/>
+  </testcase>
+  <testcase name="testPermit" classname="org.openliberty.openaz.pepapi.std.test.TestAPIWithPIP" time="0">
+    <skipped/>
+  </testcase>
+</testsuite>
\ No newline at end of file
diff --git a/openaz-pep/target/surefire-reports/TEST-org.openliberty.openaz.pepapi.std.test.TestAnnotatedHandlerRegistration.xml b/openaz-pep/target/surefire-reports/TEST-org.openliberty.openaz.pepapi.std.test.TestAnnotatedHandlerRegistration.xml
new file mode 100644
index 0000000..fea22f8
--- /dev/null
+++ b/openaz-pep/target/surefire-reports/TEST-org.openliberty.openaz.pepapi.std.test.TestAnnotatedHandlerRegistration.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<testsuite name="org.openliberty.openaz.pepapi.std.test.TestAnnotatedHandlerRegistration" time="0" tests="2" errors="0" skipped="2" failures="0">
+  <properties>
+    <property name="idea.version" value="14.0.3"/>
+    <property name="java.runtime.name" value="Java(TM) SE Runtime Environment"/>
+    <property name="sun.boot.library.path" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib"/>
+    <property name="java.vm.version" value="24.75-b04"/>
+    <property name="gopherProxySet" value="false"/>
+    <property name="java.vm.vendor" value="Oracle Corporation"/>
+    <property name="java.vendor.url" value="http://java.oracle.com/"/>
+    <property name="path.separator" value=":"/>
+    <property name="guice.disable.misplaced.annotation.check" value="true"/>
+    <property name="java.vm.name" value="Java HotSpot(TM) 64-Bit Server VM"/>
+    <property name="file.encoding.pkg" value="sun.io"/>
+    <property name="idea.launcher.port" value="7534"/>
+    <property name="user.country" value="US"/>
+    <property name="sun.java.launcher" value="SUN_STANDARD"/>
+    <property name="sun.os.patch.level" value="unknown"/>
+    <property name="java.vm.specification.name" value="Java Virtual Machine Specification"/>
+    <property name="user.dir" value="/Users/ajith/IdeaProjects/openaz"/>
+    <property name="java.runtime.version" value="1.7.0_75-b13"/>
+    <property name="java.awt.graphicsenv" value="sun.awt.CGraphicsEnvironment"/>
+    <property name="java.endorsed.dirs" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/endorsed"/>
+    <property name="os.arch" value="x86_64"/>
+    <property name="java.io.tmpdir" value="/var/folders/xs/4h_cw5ds0bj_lpk90db3v9dr0000gn/T/"/>
+    <property name="line.separator" value="&#10;"/>
+    <property name="java.vm.specification.vendor" value="Oracle Corporation"/>
+    <property name="os.name" value="Mac OS X"/>
+    <property name="classworlds.conf" value="/Applications/apache-maven-3.1.1/bin/m2.conf"/>
+    <property name="sun.jnu.encoding" value="UTF-8"/>
+    <property name="java.library.path" value="/Users/ajith/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:."/>
+    <property name="java.specification.name" value="Java Platform API Specification"/>
+    <property name="java.class.version" value="51.0"/>
+    <property name="sun.management.compiler" value="HotSpot 64-Bit Tiered Compilers"/>
+    <property name="os.version" value="10.10.2"/>
+    <property name="user.home" value="/Users/ajith"/>
+    <property name="user.timezone" value="America/New_York"/>
+    <property name="java.awt.printerjob" value="sun.lwawt.macosx.CPrinterJob"/>
+    <property name="java.specification.version" value="1.7"/>
+    <property name="idea.launcher.bin.path" value="/Applications/IntelliJ IDEA 14 CE.app/Contents/bin"/>
+    <property name="file.encoding" value="UTF-8"/>
+    <property name="user.name" value="ajith"/>
+    <property name="java.class.path" value="/Applications/apache-maven-3.1.1/boot/plexus-classworlds-2.5.1.jar:/Applications/IntelliJ IDEA 14 CE.app/Contents/lib/idea_rt.jar"/>
+    <property name="org.slf4j.simpleLogger.defaultLogLevel" value="info"/>
+    <property name="java.vm.specification.version" value="1.7"/>
+    <property name="sun.arch.data.model" value="64"/>
+    <property name="java.home" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre"/>
+    <property name="sun.java.command" value="com.intellij.rt.execution.application.AppMain org.codehaus.classworlds.Launcher -Didea.version=14.0.3 install -rf :openaz-pep"/>
+    <property name="java.specification.vendor" value="Oracle Corporation"/>
+    <property name="user.language" value="en"/>
+    <property name="awt.toolkit" value="sun.lwawt.macosx.LWCToolkit"/>
+    <property name="java.vm.info" value="mixed mode"/>
+    <property name="java.version" value="1.7.0_75"/>
+    <property name="java.ext.dirs" value="/Users/ajith/Library/Java/Extensions:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/ext:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java"/>
+    <property name="sun.boot.class.path" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/sunrsasign.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/classes"/>
+    <property name="java.vendor" value="Oracle Corporation"/>
+    <property name="maven.home" value="/Applications/apache-maven-3.1.1"/>
+    <property name="file.separator" value="/"/>
+    <property name="java.vendor.url.bug" value="http://bugreport.sun.com/bugreport/"/>
+    <property name="sun.cpu.endian" value="little"/>
+    <property name="sun.io.unicode.encoding" value="UnicodeBig"/>
+    <property name="sun.cpu.isalist" value=""/>
+  </properties>
+  <testcase name="testRegistration" classname="org.openliberty.openaz.pepapi.std.test.TestAnnotatedHandlerRegistration" time="0">
+    <skipped/>
+  </testcase>
+  <testcase name="testPepAgent" classname="org.openliberty.openaz.pepapi.std.test.TestAnnotatedHandlerRegistration" time="0">
+    <skipped/>
+  </testcase>
+</testsuite>
\ No newline at end of file
diff --git a/openaz-pep/target/surefire-reports/TEST-org.openliberty.openaz.pepapi.std.test.TestDataTypes.xml b/openaz-pep/target/surefire-reports/TEST-org.openliberty.openaz.pepapi.std.test.TestDataTypes.xml
new file mode 100644
index 0000000..5c7ae2e
--- /dev/null
+++ b/openaz-pep/target/surefire-reports/TEST-org.openliberty.openaz.pepapi.std.test.TestDataTypes.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<testsuite name="org.openliberty.openaz.pepapi.std.test.TestDataTypes" time="0.556" tests="4" errors="0" skipped="0" failures="0">
+  <properties>
+    <property name="idea.version" value="14.0.3"/>
+    <property name="java.runtime.name" value="Java(TM) SE Runtime Environment"/>
+    <property name="sun.boot.library.path" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib"/>
+    <property name="java.vm.version" value="24.75-b04"/>
+    <property name="gopherProxySet" value="false"/>
+    <property name="java.vm.vendor" value="Oracle Corporation"/>
+    <property name="java.vendor.url" value="http://java.oracle.com/"/>
+    <property name="path.separator" value=":"/>
+    <property name="guice.disable.misplaced.annotation.check" value="true"/>
+    <property name="java.vm.name" value="Java HotSpot(TM) 64-Bit Server VM"/>
+    <property name="file.encoding.pkg" value="sun.io"/>
+    <property name="idea.launcher.port" value="7534"/>
+    <property name="user.country" value="US"/>
+    <property name="sun.java.launcher" value="SUN_STANDARD"/>
+    <property name="sun.os.patch.level" value="unknown"/>
+    <property name="java.vm.specification.name" value="Java Virtual Machine Specification"/>
+    <property name="user.dir" value="/Users/ajith/IdeaProjects/openaz"/>
+    <property name="java.runtime.version" value="1.7.0_75-b13"/>
+    <property name="java.awt.graphicsenv" value="sun.awt.CGraphicsEnvironment"/>
+    <property name="java.endorsed.dirs" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/endorsed"/>
+    <property name="os.arch" value="x86_64"/>
+    <property name="java.io.tmpdir" value="/var/folders/xs/4h_cw5ds0bj_lpk90db3v9dr0000gn/T/"/>
+    <property name="line.separator" value="&#10;"/>
+    <property name="java.vm.specification.vendor" value="Oracle Corporation"/>
+    <property name="os.name" value="Mac OS X"/>
+    <property name="classworlds.conf" value="/Applications/apache-maven-3.1.1/bin/m2.conf"/>
+    <property name="sun.jnu.encoding" value="UTF-8"/>
+    <property name="java.library.path" value="/Users/ajith/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:."/>
+    <property name="java.specification.name" value="Java Platform API Specification"/>
+    <property name="java.class.version" value="51.0"/>
+    <property name="sun.management.compiler" value="HotSpot 64-Bit Tiered Compilers"/>
+    <property name="os.version" value="10.10.2"/>
+    <property name="user.home" value="/Users/ajith"/>
+    <property name="user.timezone" value="America/New_York"/>
+    <property name="java.awt.printerjob" value="sun.lwawt.macosx.CPrinterJob"/>
+    <property name="java.specification.version" value="1.7"/>
+    <property name="idea.launcher.bin.path" value="/Applications/IntelliJ IDEA 14 CE.app/Contents/bin"/>
+    <property name="file.encoding" value="UTF-8"/>
+    <property name="user.name" value="ajith"/>
+    <property name="java.class.path" value="/Applications/apache-maven-3.1.1/boot/plexus-classworlds-2.5.1.jar:/Applications/IntelliJ IDEA 14 CE.app/Contents/lib/idea_rt.jar"/>
+    <property name="org.slf4j.simpleLogger.defaultLogLevel" value="info"/>
+    <property name="java.vm.specification.version" value="1.7"/>
+    <property name="sun.arch.data.model" value="64"/>
+    <property name="java.home" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre"/>
+    <property name="sun.java.command" value="com.intellij.rt.execution.application.AppMain org.codehaus.classworlds.Launcher -Didea.version=14.0.3 install -rf :openaz-pep"/>
+    <property name="java.specification.vendor" value="Oracle Corporation"/>
+    <property name="user.language" value="en"/>
+    <property name="awt.toolkit" value="sun.lwawt.macosx.LWCToolkit"/>
+    <property name="java.vm.info" value="mixed mode"/>
+    <property name="java.version" value="1.7.0_75"/>
+    <property name="java.ext.dirs" value="/Users/ajith/Library/Java/Extensions:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/ext:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java"/>
+    <property name="sun.boot.class.path" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/sunrsasign.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/classes"/>
+    <property name="java.vendor" value="Oracle Corporation"/>
+    <property name="maven.home" value="/Applications/apache-maven-3.1.1"/>
+    <property name="file.separator" value="/"/>
+    <property name="java.vendor.url.bug" value="http://bugreport.sun.com/bugreport/"/>
+    <property name="sun.cpu.endian" value="little"/>
+    <property name="sun.io.unicode.encoding" value="UnicodeBig"/>
+    <property name="sun.cpu.isalist" value=""/>
+  </properties>
+  <testcase name="testMultiRequestWithURI" classname="org.openliberty.openaz.pepapi.std.test.TestDataTypes" time="0.511"/>
+  <testcase name="testPermitWithURIResource" classname="org.openliberty.openaz.pepapi.std.test.TestDataTypes" time="0.022"/>
+  <testcase name="testPermitWithIntegerResource" classname="org.openliberty.openaz.pepapi.std.test.TestDataTypes" time="0.022"/>
+  <testcase name="testPepAgent" classname="org.openliberty.openaz.pepapi.std.test.TestDataTypes" time="0.001"/>
+</testsuite>
\ No newline at end of file
diff --git a/openaz-pep/target/surefire-reports/TEST-org.openliberty.openaz.pepapi.std.test.TestMapper.xml b/openaz-pep/target/surefire-reports/TEST-org.openliberty.openaz.pepapi.std.test.TestMapper.xml
new file mode 100644
index 0000000..4c652e2
--- /dev/null
+++ b/openaz-pep/target/surefire-reports/TEST-org.openliberty.openaz.pepapi.std.test.TestMapper.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<testsuite name="org.openliberty.openaz.pepapi.std.test.TestMapper" time="0.515" tests="6" errors="0" skipped="0" failures="0">
+  <properties>
+    <property name="idea.version" value="14.0.3"/>
+    <property name="java.runtime.name" value="Java(TM) SE Runtime Environment"/>
+    <property name="sun.boot.library.path" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib"/>
+    <property name="java.vm.version" value="24.75-b04"/>
+    <property name="gopherProxySet" value="false"/>
+    <property name="java.vm.vendor" value="Oracle Corporation"/>
+    <property name="java.vendor.url" value="http://java.oracle.com/"/>
+    <property name="path.separator" value=":"/>
+    <property name="guice.disable.misplaced.annotation.check" value="true"/>
+    <property name="java.vm.name" value="Java HotSpot(TM) 64-Bit Server VM"/>
+    <property name="file.encoding.pkg" value="sun.io"/>
+    <property name="idea.launcher.port" value="7534"/>
+    <property name="user.country" value="US"/>
+    <property name="sun.java.launcher" value="SUN_STANDARD"/>
+    <property name="sun.os.patch.level" value="unknown"/>
+    <property name="java.vm.specification.name" value="Java Virtual Machine Specification"/>
+    <property name="user.dir" value="/Users/ajith/IdeaProjects/openaz"/>
+    <property name="java.runtime.version" value="1.7.0_75-b13"/>
+    <property name="java.awt.graphicsenv" value="sun.awt.CGraphicsEnvironment"/>
+    <property name="java.endorsed.dirs" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/endorsed"/>
+    <property name="os.arch" value="x86_64"/>
+    <property name="java.io.tmpdir" value="/var/folders/xs/4h_cw5ds0bj_lpk90db3v9dr0000gn/T/"/>
+    <property name="line.separator" value="&#10;"/>
+    <property name="java.vm.specification.vendor" value="Oracle Corporation"/>
+    <property name="os.name" value="Mac OS X"/>
+    <property name="classworlds.conf" value="/Applications/apache-maven-3.1.1/bin/m2.conf"/>
+    <property name="sun.jnu.encoding" value="UTF-8"/>
+    <property name="java.library.path" value="/Users/ajith/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:."/>
+    <property name="java.specification.name" value="Java Platform API Specification"/>
+    <property name="java.class.version" value="51.0"/>
+    <property name="sun.management.compiler" value="HotSpot 64-Bit Tiered Compilers"/>
+    <property name="os.version" value="10.10.2"/>
+    <property name="user.home" value="/Users/ajith"/>
+    <property name="user.timezone" value="America/New_York"/>
+    <property name="java.awt.printerjob" value="sun.lwawt.macosx.CPrinterJob"/>
+    <property name="java.specification.version" value="1.7"/>
+    <property name="idea.launcher.bin.path" value="/Applications/IntelliJ IDEA 14 CE.app/Contents/bin"/>
+    <property name="file.encoding" value="UTF-8"/>
+    <property name="user.name" value="ajith"/>
+    <property name="java.class.path" value="/Applications/apache-maven-3.1.1/boot/plexus-classworlds-2.5.1.jar:/Applications/IntelliJ IDEA 14 CE.app/Contents/lib/idea_rt.jar"/>
+    <property name="org.slf4j.simpleLogger.defaultLogLevel" value="info"/>
+    <property name="java.vm.specification.version" value="1.7"/>
+    <property name="sun.arch.data.model" value="64"/>
+    <property name="java.home" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre"/>
+    <property name="sun.java.command" value="com.intellij.rt.execution.application.AppMain org.codehaus.classworlds.Launcher -Didea.version=14.0.3 install -rf :openaz-pep"/>
+    <property name="java.specification.vendor" value="Oracle Corporation"/>
+    <property name="user.language" value="en"/>
+    <property name="awt.toolkit" value="sun.lwawt.macosx.LWCToolkit"/>
+    <property name="java.vm.info" value="mixed mode"/>
+    <property name="java.version" value="1.7.0_75"/>
+    <property name="java.ext.dirs" value="/Users/ajith/Library/Java/Extensions:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/ext:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java"/>
+    <property name="sun.boot.class.path" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/sunrsasign.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/classes"/>
+    <property name="java.vendor" value="Oracle Corporation"/>
+    <property name="maven.home" value="/Applications/apache-maven-3.1.1"/>
+    <property name="file.separator" value="/"/>
+    <property name="java.vendor.url.bug" value="http://bugreport.sun.com/bugreport/"/>
+    <property name="sun.cpu.endian" value="little"/>
+    <property name="sun.io.unicode.encoding" value="UnicodeBig"/>
+    <property name="sun.cpu.isalist" value=""/>
+  </properties>
+  <testcase name="testMix" classname="org.openliberty.openaz.pepapi.std.test.TestMapper" time="0.441"/>
+  <testcase name="testVarArgsDeny" classname="org.openliberty.openaz.pepapi.std.test.TestMapper" time="0.02"/>
+  <testcase name="testVarArgsPermit" classname="org.openliberty.openaz.pepapi.std.test.TestMapper" time="0.018"/>
+  <testcase name="testNotApplicable" classname="org.openliberty.openaz.pepapi.std.test.TestMapper" time="0.016"/>
+  <testcase name="testPepAgent" classname="org.openliberty.openaz.pepapi.std.test.TestMapper" time="0.001"/>
+  <testcase name="testPermit" classname="org.openliberty.openaz.pepapi.std.test.TestMapper" time="0.019"/>
+</testsuite>
\ No newline at end of file
diff --git a/openaz-pep/target/surefire-reports/org.openliberty.openaz.pepapi.std.test.TestAPI.txt b/openaz-pep/target/surefire-reports/org.openliberty.openaz.pepapi.std.test.TestAPI.txt
new file mode 100644
index 0000000..3ad938b
--- /dev/null
+++ b/openaz-pep/target/surefire-reports/org.openliberty.openaz.pepapi.std.test.TestAPI.txt
@@ -0,0 +1,4 @@
+-------------------------------------------------------------------------------
+Test set: org.openliberty.openaz.pepapi.std.test.TestAPI
+-------------------------------------------------------------------------------
+Tests run: 4, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.736 sec - in org.openliberty.openaz.pepapi.std.test.TestAPI
diff --git a/openaz-pep/target/surefire-reports/org.openliberty.openaz.pepapi.std.test.TestAPIWithPIP.txt b/openaz-pep/target/surefire-reports/org.openliberty.openaz.pepapi.std.test.TestAPIWithPIP.txt
new file mode 100644
index 0000000..b725ae3
--- /dev/null
+++ b/openaz-pep/target/surefire-reports/org.openliberty.openaz.pepapi.std.test.TestAPIWithPIP.txt
@@ -0,0 +1,4 @@
+-------------------------------------------------------------------------------
+Test set: org.openliberty.openaz.pepapi.std.test.TestAPIWithPIP
+-------------------------------------------------------------------------------
+Tests run: 4, Failures: 0, Errors: 0, Skipped: 4, Time elapsed: 0.058 sec - in org.openliberty.openaz.pepapi.std.test.TestAPIWithPIP
diff --git a/openaz-pep/target/surefire-reports/org.openliberty.openaz.pepapi.std.test.TestAnnotatedHandlerRegistration.txt b/openaz-pep/target/surefire-reports/org.openliberty.openaz.pepapi.std.test.TestAnnotatedHandlerRegistration.txt
new file mode 100644
index 0000000..23471ca
--- /dev/null
+++ b/openaz-pep/target/surefire-reports/org.openliberty.openaz.pepapi.std.test.TestAnnotatedHandlerRegistration.txt
@@ -0,0 +1,4 @@
+-------------------------------------------------------------------------------
+Test set: org.openliberty.openaz.pepapi.std.test.TestAnnotatedHandlerRegistration
+-------------------------------------------------------------------------------
+Tests run: 2, Failures: 0, Errors: 0, Skipped: 2, Time elapsed: 0.066 sec - in org.openliberty.openaz.pepapi.std.test.TestAnnotatedHandlerRegistration
diff --git a/openaz-pep/target/surefire-reports/org.openliberty.openaz.pepapi.std.test.TestDataTypes.txt b/openaz-pep/target/surefire-reports/org.openliberty.openaz.pepapi.std.test.TestDataTypes.txt
new file mode 100644
index 0000000..d07c3f4
--- /dev/null
+++ b/openaz-pep/target/surefire-reports/org.openliberty.openaz.pepapi.std.test.TestDataTypes.txt
@@ -0,0 +1,4 @@
+-------------------------------------------------------------------------------
+Test set: org.openliberty.openaz.pepapi.std.test.TestDataTypes
+-------------------------------------------------------------------------------
+Tests run: 4, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.631 sec - in org.openliberty.openaz.pepapi.std.test.TestDataTypes
diff --git a/openaz-pep/target/surefire-reports/org.openliberty.openaz.pepapi.std.test.TestMapper.txt b/openaz-pep/target/surefire-reports/org.openliberty.openaz.pepapi.std.test.TestMapper.txt
new file mode 100644
index 0000000..3457155
--- /dev/null
+++ b/openaz-pep/target/surefire-reports/org.openliberty.openaz.pepapi.std.test.TestMapper.txt
@@ -0,0 +1,4 @@
+-------------------------------------------------------------------------------
+Test set: org.openliberty.openaz.pepapi.std.test.TestMapper
+-------------------------------------------------------------------------------
+Tests run: 6, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.675 sec - in org.openliberty.openaz.pepapi.std.test.TestMapper
diff --git a/openaz-pep/target/test-classes/log4j.xml b/openaz-pep/target/test-classes/log4j.xml
new file mode 100644
index 0000000..ff481f9
--- /dev/null
+++ b/openaz-pep/target/test-classes/log4j.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" ?>

+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

+<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>

+

+   <appender name="consoleAppender" class="org.apache.log4j.ConsoleAppender">

+      <layout class="org.apache.log4j.PatternLayout">

+         <param name="ConversionPattern" value="%d{HH:mm:ss.SSS} [%t] %5p %c{1} - %m%n"/>

+      </layout>

+   </appender>

+

+   <appender name="fileAppender" class="org.apache.log4j.RollingFileAppender">

+      <param name="append" value="false"/>

+      <param name="file" value="target/openaz-junit-tests.log"/>

+      <layout class="org.apache.log4j.PatternLayout">

+         <param name="ConversionPattern" value="%d{HH:mm:ss.SSS} [%t] %5p %c{1} - %m%n"/>

+      </layout>

+   </appender>

+   

+   <logger name="org.openliberty.openaz">

+   		<level value="debug"/>

+   </logger>

+

+   <logger name="org.springframework">

+      <level value="error"/>

+   </logger>

+

+   <root>

+      <level value="debug"/>

+      <appender-ref ref="consoleAppender"/>

+     <!-- <appender-ref ref="fileAppender"/> -->

+   </root>

+

+</log4j:configuration>
\ No newline at end of file
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/TestAPI.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/TestAPI.class
new file mode 100644
index 0000000..3aff1fb
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/TestAPI.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/TestAPIWithPIP.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/TestAPIWithPIP.class
new file mode 100644
index 0000000..4884fbf
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/TestAPIWithPIP.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/TestAnnotatedHandlerRegistration.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/TestAnnotatedHandlerRegistration.class
new file mode 100644
index 0000000..c8aac30
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/TestAnnotatedHandlerRegistration.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/TestDataTypes.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/TestDataTypes.class
new file mode 100644
index 0000000..a1b1126
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/TestDataTypes.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/TestMapper.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/TestMapper.class
new file mode 100644
index 0000000..918799c
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/TestMapper.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContext.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContext.class
new file mode 100644
index 0000000..0d80c1f
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContext.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContextMapper.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContextMapper.class
new file mode 100644
index 0000000..7681006
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContextMapper.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/Client.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/Client.class
new file mode 100644
index 0000000..2dc35b6
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/Client.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/ClientMapper.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/ClientMapper.class
new file mode 100644
index 0000000..a65c689
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/ClientMapper.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/Document.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/Document.class
new file mode 100644
index 0000000..9bb4d24
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/Document.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/DocumentMapper.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/DocumentMapper.class
new file mode 100644
index 0000000..4a12f1c
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/DocumentMapper.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecord.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecord.class
new file mode 100644
index 0000000..62cf6e2
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecord.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecordMapper.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecordMapper.class
new file mode 100644
index 0000000..b0d1fec
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecordMapper.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AccessRestrictionObligationHandler.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AccessRestrictionObligationHandler.class
new file mode 100644
index 0000000..e3f3659
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AccessRestrictionObligationHandler.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AgeRestrictionObligationHandler.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AgeRestrictionObligationHandler.class
new file mode 100644
index 0000000..9ea4d49
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AgeRestrictionObligationHandler.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAccessRestrictionObligationHandler.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAccessRestrictionObligationHandler.class
new file mode 100644
index 0000000..a239d16
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAccessRestrictionObligationHandler.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAgeRestrictionObligationHandler.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAgeRestrictionObligationHandler.class
new file mode 100644
index 0000000..f5e751d
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAgeRestrictionObligationHandler.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAuditObligationHandler.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAuditObligationHandler.class
new file mode 100644
index 0000000..26ac39e
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAuditObligationHandler.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedCatchAllObligationHandler.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedCatchAllObligationHandler.class
new file mode 100644
index 0000000..b07bf19
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedCatchAllObligationHandler.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedFilteringObligationHandler.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedFilteringObligationHandler.class
new file mode 100644
index 0000000..e5ac144
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedFilteringObligationHandler.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedObligationHandler.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedObligationHandler.class
new file mode 100644
index 0000000..04017a5
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedObligationHandler.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedRedactionObligationHandler.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedRedactionObligationHandler.class
new file mode 100644
index 0000000..b2dbde5
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedRedactionObligationHandler.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AuditObligationHandler.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AuditObligationHandler.class
new file mode 100644
index 0000000..9d3ccbf
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AuditObligationHandler.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/CatchAllObligationHandler.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/CatchAllObligationHandler.class
new file mode 100644
index 0000000..070c920
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/CatchAllObligationHandler.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/FilteringObligationHandler.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/FilteringObligationHandler.class
new file mode 100644
index 0000000..867f3df
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/FilteringObligationHandler.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/RedactionObligationHandler.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/RedactionObligationHandler.class
new file mode 100644
index 0000000..387f894
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/RedactionObligationHandler.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/util/AzInvoker.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/util/AzInvoker.class
new file mode 100644
index 0000000..4fb49b6
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/util/AzInvoker.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/util/HasResult.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/util/HasResult.class
new file mode 100644
index 0000000..a82a6fd
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/util/HasResult.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/policies/TestPolicy001.xml b/openaz-pep/target/test-classes/policies/TestPolicy001.xml
new file mode 100644
index 0000000..4f2a711
--- /dev/null
+++ b/openaz-pep/target/test-classes/policies/TestPolicy001.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>

+<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" PolicyId="urn:oasis:names:tc:xacml:2.0:test001:policy"

+        RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-overrides" Version="1.0" xsi:schemaLocation="urn:oasis:names:tc:xacml:3.0:policy:schema:os access_control-xacml-2.0-policy-schema-os.xsd">

+    <Description></Description>

+    <Target/>

+    <Rule RuleId="urn:oasis:names:tc:xacml:1.0:test001:rule-1" Effect="Permit">

+        <Description>

+            Julius Hibbert can read or write Bart Simpson's medical record.

+        </Description>

+        <Target>

+            <AnyOf>

+                <AllOf>

+                    <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                        <AttributeValue

+                            DataType="http://www.w3.org/2001/XMLSchema#string">Julius Hibbert</AttributeValue>

+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"

+                            AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"

+                            DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>

+                    </Match>

+                </AllOf>

+            </AnyOf>

+            <AnyOf>

+                <AllOf>

+                    <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                        <AttributeValue

+                            DataType="http://www.w3.org/2001/XMLSchema#string">http://medico.com/record/patient/BartSimpson</AttributeValue>

+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"

+                            AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id"

+                            DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>

+                    </Match>

+                </AllOf>

+            </AnyOf>

+            <AnyOf>

+                <AllOf>

+                    <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                        <AttributeValue

+                            DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue>

+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"

+                            AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"

+                            DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>

+                    </Match>

+                </AllOf>

+                <AllOf>

+                    <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                        <AttributeValue

+                            DataType="http://www.w3.org/2001/XMLSchema#string">write</AttributeValue>

+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"

+                            AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"

+                            DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>

+                    </Match>

+                </AllOf>

+            </AnyOf>

+        </Target>

+    </Rule>

+</Policy>

diff --git a/openaz-pep/target/test-classes/policies/TestPolicy002.xml b/openaz-pep/target/test-classes/policies/TestPolicy002.xml
new file mode 100644
index 0000000..d0308c9
--- /dev/null
+++ b/openaz-pep/target/test-classes/policies/TestPolicy002.xml
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<Policy

+      xmlns="urn:oasis:names:tc:xacml:2.0:policy:schema:os"

+      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

+      PolicyId="urn:oasis:names:tc:xacml:1.0:conformance-test:IIA2:policy"

+      RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:deny-overrides">

+    <Description>

+        Policy for Conformance Test IIA001.

+    </Description>

+    <Target/>

+    <Rule

+          RuleId="urn:oasis:names:tc:xacml:1.0:test-2:rule-1"

+          Effect="Permit">

+        <Description>

+            Physicians can read or write Bart Simpson's medical record.

+        </Description>

+        <Target>

+            <Subjects>

+                <Subject>

+                    <SubjectMatch

+                          MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                        <AttributeValue

+                              DataType="http://www.w3.org/2001/XMLSchema#string">Physician</AttributeValue>

+                        <SubjectAttributeDesignator

+                              AttributeId="urn:oasis:names:tc:xacml:1.0:subject:role-id"

+                              DataType="http://www.w3.org/2001/XMLSchema#string"/>

+                    </SubjectMatch>

+                </Subject>

+            </Subjects>

+            <Resources>

+                <Resource>

+                    <ResourceMatch

+                          MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                        <AttributeValue

+                              DataType="http://www.w3.org/2001/XMLSchema#string">http://medico.com/record/patient/BartSimpson</AttributeValue>

+                        <ResourceAttributeDesignator

+                              AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id"

+                              DataType="http://www.w3.org/2001/XMLSchema#string"/>

+                    </ResourceMatch>

+                </Resource>

+            </Resources>

+            <Actions>

+                <Action>

+                    <ActionMatch

+                          MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                        <AttributeValue

+                              DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue>

+                        <ActionAttributeDesignator

+                              AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"

+                              DataType="http://www.w3.org/2001/XMLSchema#string"/>

+                    </ActionMatch>

+                </Action>

+                <Action>

+                    <ActionMatch

+                          MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                        <AttributeValue

+                              DataType="http://www.w3.org/2001/XMLSchema#string">write</AttributeValue>

+                        <ActionAttributeDesignator

+                              AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"

+                              DataType="http://www.w3.org/2001/XMLSchema#string"/>

+                    </ActionMatch>

+                </Action>

+            </Actions>

+        </Target>

+    </Rule>

+    <Rule

+          RuleId="urn:oasis:names:tc:xacml:1.0:test-2:rule-2"

+          Effect="Permit">

+        <Description>

+           Patient is allowed to read his/her medical record.

+        </Description>

+        <Target>

+            <Subjects>

+                <Subject>

+                    <SubjectMatch

+                          MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                        <AttributeValue

+                              DataType="http://www.w3.org/2001/XMLSchema#string">Patient</AttributeValue>

+                        <SubjectAttributeDesignator

+                              AttributeId="urn:oasis:names:tc:xacml:1.0:subject:role-id"

+                              DataType="http://www.w3.org/2001/XMLSchema#string"/>

+                    </SubjectMatch>

+                </Subject>

+            </Subjects>

+            <Resources>

+                <Resource>

+                    <ResourceMatch

+                          MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                        <AttributeValue

+                              DataType="http://www.w3.org/2001/XMLSchema#string">http://medico.com/record/patient/BartSimpson</AttributeValue>

+                        <ResourceAttributeDesignator

+                              AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id"

+                              DataType="http://www.w3.org/2001/XMLSchema#string"/>

+                    </ResourceMatch>

+                </Resource>

+            </Resources>

+            <Actions>

+                <Action>

+                    <ActionMatch

+                          MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                        <AttributeValue

+                              DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue>

+                        <ActionAttributeDesignator

+                              AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"

+                              DataType="http://www.w3.org/2001/XMLSchema#string"/>

+                    </ActionMatch>

+                </Action>

+            </Actions>

+        </Target>

+        <Condition>

+        	<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+        		<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">

+					<ResourceAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-owner" 

+								DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false" />

+				</Apply>

+				<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">

+					<SubjectAttributeDesignator

+						AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"

+						DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"

+						SubjectCategory="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" />

+				</Apply>

+        	</Apply>

+        </Condition>

+    </Rule>

+</Policy>

diff --git a/openaz-pep/target/test-classes/policies/TestPolicy003.xml b/openaz-pep/target/test-classes/policies/TestPolicy003.xml
new file mode 100644
index 0000000..f730e34
--- /dev/null
+++ b/openaz-pep/target/test-classes/policies/TestPolicy003.xml
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" PolicyId="urn:oasis:names:tc:xacml:2.0:test003:policy"

+        RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-overrides" Version="1.0" xsi:schemaLocation="urn:oasis:names:tc:xacml:3.0:policy:schema:os access_control-xacml-2.0-policy-schema-os.xsd">

+    <Description></Description>

+    <Target/>

+    <Rule RuleId="urn:oasis:names:tc:xacml:2.0:test003:rule1" Effect="Permit">

+        <Target>

+            <AnyOf>

+                <AllOf>

+                    <Match

+                          MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                        <AttributeValue

+                              DataType="http://www.w3.org/2001/XMLSchema#string">John Smith</AttributeValue>

+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"

+                              AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"

+                              DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>

+                    </Match>

+                </AllOf>

+            </AnyOf>

+            <AnyOf>

+                <AllOf>

+                    <Match

+                          MatchId="urn:oasis:names:tc:xacml:1.0:function:anyURI-equal">

+                        <AttributeValue

+                              DataType="http://www.w3.org/2001/XMLSchema#anyURI">file://repository/classified/abc</AttributeValue>

+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"

+                              AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id"

+                              DataType="http://www.w3.org/2001/XMLSchema#anyURI" MustBePresent="false"/>

+                    </Match>

+                </AllOf>

+            </AnyOf>

+            <AnyOf>

+                <AllOf>

+                    <Match

+                          MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                        <AttributeValue

+                              DataType="http://www.w3.org/2001/XMLSchema#string">view</AttributeValue>

+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"

+                              AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"

+                              DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>

+                    </Match>

+                </AllOf>

+            </AnyOf>

+        </Target>

+    </Rule>

+     <Rule RuleId="urn:oasis:names:tc:xacml:2.0:test003:rule2" Effect="Permit">

+         <Target>

+             <AnyOf>

+                 <AllOf>

+                     <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                         <AttributeValue

+                            DataType="http://www.w3.org/2001/XMLSchema#string">John Smith</AttributeValue>

+                         <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"

+                            AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"

+                            DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>

+                     </Match>

+                 </AllOf>

+             </AnyOf>

+             <AnyOf>

+                 <AllOf>

+                     <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:anyURI-equal">

+                         <AttributeValue

+                            DataType="http://www.w3.org/2001/XMLSchema#anyURI">file://repository/classified/xyz</AttributeValue>

+                         <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"

+                            AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id"

+                            DataType="http://www.w3.org/2001/XMLSchema#anyURI" MustBePresent="false"/>

+                     </Match>

+                 </AllOf>

+             </AnyOf>

+             <AnyOf>

+                 <AllOf>

+                     <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                         <AttributeValue

+                            DataType="http://www.w3.org/2001/XMLSchema#string">view</AttributeValue>

+                         <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"

+                            AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"

+                            DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>

+                     </Match>

+                 </AllOf>

+             </AnyOf>

+         </Target>

+    </Rule>

+    <Rule RuleId="urn:oasis:names:tc:xacml:1.0:conformance-test:IIA3:rule3" Effect="Permit">

+        <Target>

+            <AnyOf>

+                <AllOf>

+                    <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                        <AttributeValue

+                            DataType="http://www.w3.org/2001/XMLSchema#string">John Smith</AttributeValue>

+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"

+                            AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"

+                            DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>

+                    </Match>

+                </AllOf>

+            </AnyOf>

+            <AnyOf>

+                <AllOf>

+                    <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:integer-equal">

+                        <AttributeValue

+                              DataType="http://www.w3.org/2001/XMLSchema#integer">101</AttributeValue>

+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"

+                              AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id"

+                              DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="false"/>

+                    </Match>

+                </AllOf>

+            </AnyOf>

+            <AnyOf>

+                <AllOf>

+                    <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                        <AttributeValue

+                            DataType="http://www.w3.org/2001/XMLSchema#string">view</AttributeValue>

+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"

+                            AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"

+                            DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>

+                    </Match>

+                </AllOf>

+            </AnyOf>

+        </Target>

+    </Rule>

+</Policy>

diff --git a/openaz-pep/target/test-classes/policies/TestPolicy004.xml b/openaz-pep/target/test-classes/policies/TestPolicy004.xml
new file mode 100644
index 0000000..83ec917
--- /dev/null
+++ b/openaz-pep/target/test-classes/policies/TestPolicy004.xml
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>

+<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" PolicyId="urn:oasis:names:tc:xacml:2.0:test004:policy"

+        RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-overrides" Version="1.0" xsi:schemaLocation="urn:oasis:names:tc:xacml:3.0:policy:schema:os access_control-xacml-2.0-policy-schema-os.xsd">

+    <Description></Description>

+    <Target/>

+    <Rule

+          RuleId="urn:oasis:names:tc:xacml:1.0:mapper-test:rule1"

+          Effect="Permit">

+        <Description></Description>

+        <Target>

+        	<AnyOf>

+                <AllOf>

+                    <Match

+                          MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                        <AttributeValue

+                              DataType="http://www.w3.org/2001/XMLSchema#string">ROLE_DOCUMENT_WRITER</AttributeValue>

+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"

+                              AttributeId="urn:oasis:names:tc:xacml:1.0:subject:role-id"

+                              DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>

+                    </Match>

+                </AllOf>

+            </AnyOf>

+            <AnyOf>

+                <AllOf>

+                    <Match

+                          MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                        <AttributeValue

+                              DataType="http://www.w3.org/2001/XMLSchema#string">Document</AttributeValue>

+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"

+                              AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-type"

+                              DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>

+                    </Match>

+                </AllOf>

+            </AnyOf>

+            <AnyOf>

+                <AllOf>

+                    <Match

+                          MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                        <AttributeValue

+                              DataType="http://www.w3.org/2001/XMLSchema#string">write</AttributeValue>

+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"

+                              AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"

+                              DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>

+                    </Match>

+                </AllOf>

+            </AnyOf>

+        </Target>

+        <Condition>

+        	<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+        		<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">

+					<AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"

+                        AttributeId="jpmc:document:document-owner"

+                        DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false" />

+				</Apply>

+				<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">

+					<AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"

+						AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"

+						DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false" />

+				</Apply>

+        	</Apply>

+        </Condition>

+    </Rule>

+    <Rule

+          RuleId="urn:oasis:names:tc:xacml:1.0:mapper-test:rule2"

+          Effect="Permit">

+        <Description></Description>

+        <Target>

+            <AnyOf>

+                <AllOf>

+                    <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                        <AttributeValue

+                            DataType="http://www.w3.org/2001/XMLSchema#string">ROLE_DOCUMENT_READER</AttributeValue>

+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"

+                            AttributeId="urn:oasis:names:tc:xacml:1.0:subject:role-id"

+                            DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>

+                    </Match>

+                </AllOf>

+            </AnyOf>

+            <AnyOf>

+                <AllOf>

+                    <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Document</AttributeValue>

+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"

+                            AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-type"

+                            DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>

+                    </Match>

+                </AllOf>

+            </AnyOf>

+            <AnyOf>

+                <AllOf>

+                    <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                        <AttributeValue

+                            DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue>

+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"

+                            AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"

+                            DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>

+                    </Match>

+                </AllOf>

+            </AnyOf>

+        </Target>

+        <Condition>

+        	<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+        		<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">

+					<AttributeDesignator AttributeId="jpmc:client:country-of-domicile"

+                        Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"

+                        DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false" />

+				</Apply>

+				<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">

+					<AttributeDesignator AttributeId="jpmc:request-context:country"

+                        Category="urn:oasis:names:tc:xacml:3.0:attribute-category:environment"

+						DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false" />

+				</Apply>

+        	</Apply>

+        </Condition>

+    </Rule>

+</Policy>

diff --git a/openaz-pep/target/test-classes/policies/TestPolicy005.xml b/openaz-pep/target/test-classes/policies/TestPolicy005.xml
new file mode 100644
index 0000000..e8d43b5
--- /dev/null
+++ b/openaz-pep/target/test-classes/policies/TestPolicy005.xml
@@ -0,0 +1,190 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<PolicySet

+      xmlns="urn:oasis:names:tc:xacml:2.0:policy:schema:os"

+      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

+      xsi:schemaLocation="urn:oasis:names:tc:xacml:2.0:policy:schema:os

+        access_control-xacml-2.0-policy-schema-os.xsd"

+      PolicySetId="urn:oasis:names:tc:xacml:2.0:test005:policyset"

+      PolicyCombiningAlgId="urn:oasis:names:tc:xacml:1.0:policy-combining-algorithm:first-applicable">

+    <Description>

+        PolicySet for Test 005.

+    </Description>

+    <Target/>

+    <Policy PolicyId="urn:oasis:names:tc:xacml:2.0:test005:policy1"

+          RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">

+        <Description>

+            Policy for Test 005.

+        </Description>

+        <Target/>

+        <Rule RuleId="urn:oasis:names:tc:xacml:2.0:test005:rule1"

+              Effect="Permit">

+            <Target>

+                <Subjects>

+                    <Subject>

+                        <SubjectMatch

+                              MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                            <AttributeValue

+                                  DataType="http://www.w3.org/2001/XMLSchema#string">Physician</AttributeValue>

+                            <SubjectAttributeDesignator

+                                  AttributeId="urn:oasis:names:tc:xacml:1.0:subject:role-id"

+                                  DataType="http://www.w3.org/2001/XMLSchema#string"/>

+                        </SubjectMatch>

+                    </Subject>

+                </Subjects>

+                <Resources>

+	                <Resource>

+	                    <ResourceMatch

+	                          MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+	                        <AttributeValue

+	                              DataType="http://www.w3.org/2001/XMLSchema#string">PatientMedicalRecord</AttributeValue>

+	                        <ResourceAttributeDesignator

+	                              AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-type"

+	                              DataType="http://www.w3.org/2001/XMLSchema#string"/>

+	                    </ResourceMatch>

+	                </Resource>

+	            </Resources>

+	            <Actions>

+	                <Action>

+	                    <ActionMatch

+	                          MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+	                        <AttributeValue

+	                              DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue>

+	                        <ActionAttributeDesignator

+	                              AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"

+	                              DataType="http://www.w3.org/2001/XMLSchema#string"/>

+	                    </ActionMatch>

+	                </Action>

+	            </Actions>

+            </Target>

+        </Rule>

+	    <Obligations>

+	        <Obligation

+	            ObligationId="urn:oasis:names:tc:xacml:2.0:obligation:simpletest"

+	            FulfillOn="Permit">

+	             <AttributeAssignment

+	                AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"

+	                DataType="http://www.w3.org/2001/XMLSchema#string">EVAL_SUBJECT_ATTRIBUTE</AttributeAssignment>

+	        </Obligation>

+	    </Obligations>

+    </Policy>

+    <Policy PolicyId="urn:oasis:names:tc:xacml:2.0:test005:policy2"

+          RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">

+        <Description>

+            Policy for Test 005.

+        </Description>

+        <Target/>

+        <Rule RuleId="urn:oasis:names:tc:xacml:2.0:test005:rule2"

+              Effect="Permit">

+            <Target>

+                <Subjects>

+                    <Subject>

+                        <SubjectMatch

+                              MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                            <AttributeValue

+                                  DataType="http://www.w3.org/2001/XMLSchema#string">Patient</AttributeValue>

+                            <SubjectAttributeDesignator

+                                  AttributeId="urn:oasis:names:tc:xacml:1.0:subject:role-id"

+                                  DataType="http://www.w3.org/2001/XMLSchema#string"/>

+                        </SubjectMatch>

+                    </Subject>

+                </Subjects>

+	            <Resources>

+	                <Resource>

+	                    <ResourceMatch

+	                          MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+	                        <AttributeValue

+	                              DataType="http://www.w3.org/2001/XMLSchema#string">PatientMedicalRecord</AttributeValue>

+	                        <ResourceAttributeDesignator

+	                              AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-type"

+	                              DataType="http://www.w3.org/2001/XMLSchema#string"/>

+	                    </ResourceMatch>

+	                </Resource>

+	            </Resources>

+	            <Actions>

+	                <Action>

+	                    <ActionMatch

+	                          MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+	                        <AttributeValue

+	                              DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue>

+	                        <ActionAttributeDesignator

+	                              AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"

+	                              DataType="http://www.w3.org/2001/XMLSchema#string"/>

+	                    </ActionMatch>

+	                </Action>

+	            </Actions>

+            </Target>

+        </Rule>

+	    <Obligations>

+	        <Obligation

+	            ObligationId="urn:oasis:names:tc:xacml:2.0:obligation:age-restriction"

+	            FulfillOn="Permit">

+	            <AttributeAssignment

+	                AttributeId="urn:oasis:names:tc:xacml:1.0:subject:age"

+	                DataType="http://www.w3.org/2001/XMLSchema#string">EVAL_SUBJECT_ATTRIBUTE</AttributeAssignment>

+	        </Obligation>

+	        <Obligation

+	            ObligationId="urn:oasis:names:tc:xacml:2.0:obligation:audit"

+	            FulfillOn="Permit"/>

+	    </Obligations>

+    </Policy>

+    <Policy PolicyId="urn:oasis:names:tc:xacml:2.0:test005:policy3"

+          RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">

+        <Description>

+            Policy for Test 005.

+        </Description>

+        <Target/>

+        <Rule RuleId="urn:oasis:names:tc:xacml:2.0:test005:rule3"

+              Effect="Permit">

+            <Target>

+                <Subjects>

+                    <Subject>

+                        <SubjectMatch

+                              MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                            <AttributeValue

+                                  DataType="http://www.w3.org/2001/XMLSchema#string">InsuranceAgent</AttributeValue>

+                            <SubjectAttributeDesignator

+                                  AttributeId="urn:oasis:names:tc:xacml:1.0:subject:role-id"

+                                  DataType="http://www.w3.org/2001/XMLSchema#string"/>

+                        </SubjectMatch>

+                    </Subject>

+                </Subjects>

+                <Resources>

+	                <Resource>

+	                    <ResourceMatch

+	                          MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+	                        <AttributeValue

+	                              DataType="http://www.w3.org/2001/XMLSchema#string">PatientMedicalRecord</AttributeValue>

+	                        <ResourceAttributeDesignator

+	                              AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-type"

+	                              DataType="http://www.w3.org/2001/XMLSchema#string"/>

+	                    </ResourceMatch>

+	                </Resource>

+	            </Resources>

+	            <Actions>

+	                <Action>

+	                    <ActionMatch

+	                          MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+	                        <AttributeValue

+	                              DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue>

+	                        <ActionAttributeDesignator

+	                              AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"

+	                              DataType="http://www.w3.org/2001/XMLSchema#string"/>

+	                    </ActionMatch>

+	                </Action>

+	            </Actions>

+            </Target>

+        </Rule>

+	    <Obligations>

+	        <Obligation

+	            ObligationId="urn:oasis:names:tc:xacml:2.0:obligation:access-restriction"

+	            FulfillOn="Permit">

+	            <AttributeAssignment

+	                AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-access-group"

+	                DataType="http://www.w3.org/2001/XMLSchema#string">EVAL_RESOURCE_ATTRIBUTE</AttributeAssignment>

+	            <AttributeAssignment

+	                AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"

+	                DataType="http://www.w3.org/2001/XMLSchema#string">EVAL_SUBJECT_ATTRIBUTE</AttributeAssignment>

+	        </Obligation>

+	    </Obligations>

+    </Policy>

+</PolicySet>

diff --git a/openaz-pep/target/test-classes/policies/TestPolicy006.xml b/openaz-pep/target/test-classes/policies/TestPolicy006.xml
new file mode 100644
index 0000000..d609e58
--- /dev/null
+++ b/openaz-pep/target/test-classes/policies/TestPolicy006.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<PolicySet

+      xmlns="urn:oasis:names:tc:xacml:2.0:policy:schema:os"

+      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

+      xsi:schemaLocation="urn:oasis:names:tc:xacml:2.0:policy:schema:os

+        access_control-xacml-2.0-policy-schema-os.xsd"

+      PolicySetId="urn:oasis:names:tc:xacml:2.0:test005:policyset"

+      PolicyCombiningAlgId="urn:oasis:names:tc:xacml:1.0:policy-combining-algorithm:first-applicable">

+    <Description>

+        PolicySet for Test 005.

+    </Description>

+    <Target/>

+    <Policy PolicyId="urn:oasis:names:tc:xacml:2.0:test005:policy1"

+          RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">

+        <Description>

+            Policy for Test 005.

+        </Description>

+        <Target/>

+        <Rule RuleId="urn:oasis:names:tc:xacml:2.0:test005:rule1"

+              Effect="Permit">

+            <Target>

+                <Subjects>

+                    <Subject>

+                        <SubjectMatch

+                              MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+                            <AttributeValue

+                                  DataType="http://www.w3.org/2001/XMLSchema#string">John Smith</AttributeValue>

+                            <SubjectAttributeDesignator

+                                  AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"

+                                  DataType="http://www.w3.org/2001/XMLSchema#string"/>

+                        </SubjectMatch>

+                    </Subject>

+                </Subjects>

+                <Resources>

+	                <Resource>

+	                    <ResourceMatch

+	                          MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+	                        <AttributeValue

+	                              DataType="http://www.w3.org/2001/XMLSchema#string">resource1</AttributeValue>

+	                        <ResourceAttributeDesignator

+	                              AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id"

+	                              DataType="http://www.w3.org/2001/XMLSchema#string"/>

+	                    </ResourceMatch>

+	                </Resource>

+	            </Resources>

+	            <Actions>

+	                <Action>

+	                    <ActionMatch

+	                          MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">

+	                        <AttributeValue

+	                              DataType="http://www.w3.org/2001/XMLSchema#string">view</AttributeValue>

+	                        <ActionAttributeDesignator

+	                              AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"

+	                              DataType="http://www.w3.org/2001/XMLSchema#string"/>

+	                    </ActionMatch>

+	                </Action>

+	            </Actions>

+            </Target>

+        </Rule>

+	    <Obligations>

+	        <Obligation

+	            ObligationId="urn:oasis:names:tc:xacml:2.0:obligation:obligation-1"

+	            FulfillOn="Permit">

+	            <AttributeAssignment

+	                AttributeId="jpmc:obligation:obligation-type"

+	                DataType="http://www.w3.org/2001/XMLSchema#string">Filtering</AttributeAssignment>

+	             <AttributeAssignment

+	                AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"

+	                DataType="http://www.w3.org/2001/XMLSchema#string">EVAL_SUBJECT_ATTRIBUTE</AttributeAssignment>

+	        </Obligation>

+	         <Obligation

+	            ObligationId="urn:oasis:names:tc:xacml:2.0:obligation:obligation-2"

+	            FulfillOn="Permit">

+	            <AttributeAssignment

+	                AttributeId="urn:oasis:names:tc:xacml:1.0:subject:age"

+	                DataType="http://www.w3.org/2001/XMLSchema#string">EVAL_SUBJECT_ATTRIBUTE</AttributeAssignment>

+	        </Obligation>

+	    </Obligations>

+    </Policy>

+</PolicySet>

diff --git a/openaz-pep/target/test-classes/properties/testapi.xacml.properties b/openaz-pep/target/test-classes/properties/testapi.xacml.properties
new file mode 100644
index 0000000..b45d2c1
--- /dev/null
+++ b/openaz-pep/target/test-classes/properties/testapi.xacml.properties
@@ -0,0 +1,20 @@
+# Default XACML Properties File
+# Standard API Factories
+#
+xacml.dataTypeFactory=com.att.research.xacml.std.StdDataTypeFactory
+xacml.pdpEngineFactory=com.att.research.xacmlatt.pdp.ATTPDPEngineFactory
+xacml.pepEngineFactory=com.att.research.xacml.std.pep.StdEngineFactory
+xacml.pipFinderFactory=com.att.research.xacml.std.pip.StdPIPFinderFactory
+
+# AT&T PDP Implementation Factories
+#
+xacml.att.evaluationContextFactory=com.att.research.xacmlatt.pdp.std.StdEvaluationContextFactory
+xacml.att.combiningAlgorithmFactory=com.att.research.xacmlatt.pdp.std.StdCombiningAlgorithmFactory
+xacml.att.functionDefinitionFactory=com.att.research.xacmlatt.pdp.std.StdFunctionDefinitionFactory
+xacml.att.policyFinderFactory=com.att.research.xacmlatt.pdp.std.StdPolicyFinderFactory
+
+xacml.rootPolicies=testPolicy
+testPolicy.file=src/test/resources/policies/TestPolicy001.xml
+
+# If there is a standard policy for the engine:
+# xacml.att.stdPolicyFinderFactory.rootPolicyFile=/etc/stdpolicyset.xml
diff --git a/openaz-pep/target/test-classes/properties/testdatatypes.xacml.properties b/openaz-pep/target/test-classes/properties/testdatatypes.xacml.properties
new file mode 100644
index 0000000..cb6d77b
--- /dev/null
+++ b/openaz-pep/target/test-classes/properties/testdatatypes.xacml.properties
@@ -0,0 +1,20 @@
+# Default XACML Properties File
+# Standard API Factories
+#
+xacml.dataTypeFactory=com.att.research.xacml.std.StdDataTypeFactory
+xacml.pdpEngineFactory=com.att.research.xacmlatt.pdp.ATTPDPEngineFactory
+xacml.pepEngineFactory=com.att.research.xacml.std.pep.StdEngineFactory
+xacml.pipFinderFactory=com.att.research.xacml.std.pip.StdPIPFinderFactory
+
+# AT&T PDP Implementation Factories
+#
+xacml.att.evaluationContextFactory=com.att.research.xacmlatt.pdp.std.StdEvaluationContextFactory
+xacml.att.combiningAlgorithmFactory=com.att.research.xacmlatt.pdp.std.StdCombiningAlgorithmFactory
+xacml.att.functionDefinitionFactory=com.att.research.xacmlatt.pdp.std.StdFunctionDefinitionFactory
+xacml.att.policyFinderFactory=com.att.research.xacmlatt.pdp.std.StdPolicyFinderFactory
+
+xacml.rootPolicies=testPolicy
+testPolicy.file=src/test/resources/policies/TestPolicy003.xml
+
+# If there is a standard policy for the engine:
+# xacml.att.stdPolicyFinderFactory.rootPolicyFile=/etc/stdpolicyset.xml
diff --git a/openaz-pep/target/test-classes/properties/testmapper.xacml.properties b/openaz-pep/target/test-classes/properties/testmapper.xacml.properties
new file mode 100644
index 0000000..12e1754
--- /dev/null
+++ b/openaz-pep/target/test-classes/properties/testmapper.xacml.properties
@@ -0,0 +1,24 @@
+# Default XACML Properties File
+# Standard API Factories
+#
+xacml.dataTypeFactory=com.att.research.xacml.std.StdDataTypeFactory
+xacml.pdpEngineFactory=com.att.research.xacmlatt.pdp.ATTPDPEngineFactory
+xacml.pepEngineFactory=com.att.research.xacml.std.pep.StdEngineFactory
+xacml.pipFinderFactory=com.att.research.xacml.std.pip.StdPIPFinderFactory
+
+# AT&T PDP Implementation Factories
+#
+xacml.att.evaluationContextFactory=com.att.research.xacmlatt.pdp.std.StdEvaluationContextFactory
+xacml.att.combiningAlgorithmFactory=com.att.research.xacmlatt.pdp.std.StdCombiningAlgorithmFactory
+xacml.att.functionDefinitionFactory=com.att.research.xacmlatt.pdp.std.StdFunctionDefinitionFactory
+xacml.att.policyFinderFactory=com.att.research.xacmlatt.pdp.std.StdPolicyFinderFactory
+
+xacml.rootPolicies=testPolicy
+testPolicy.file=src/test/resources/policies/TestPolicy004.xml
+
+#pep properties
+pep.issuer=test
+pep.mapper.classes=org.openliberty.openaz.pepapi.std.test.mapper.BusinessRequestContextMapper,\
+  org.openliberty.openaz.pepapi.std.test.mapper.DocumentMapper, \
+  org.openliberty.openaz.pepapi.std.test.mapper.ClientMapper, \
+  org.openliberty.openaz.pepapi.std.test.mapper.MedicalRecordMapper
diff --git a/openaz-xacml-pap-admin/pom.xml b/openaz-xacml-pap-admin/pom.xml
new file mode 100755
index 0000000..78f7817
--- /dev/null
+++ b/openaz-xacml-pap-admin/pom.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>openaz</artifactId>
+        <groupId>org.openliberty.openaz</groupId>
+        <version>0.0.1-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>openaz-xacml-pap-admin</artifactId>
+
+
+</project>
\ No newline at end of file
diff --git a/openaz-xacml-pap-admin/target/maven-archiver/pom.properties b/openaz-xacml-pap-admin/target/maven-archiver/pom.properties
new file mode 100644
index 0000000..d531585
--- /dev/null
+++ b/openaz-xacml-pap-admin/target/maven-archiver/pom.properties
@@ -0,0 +1,5 @@
+#Generated by Maven
+#Tue Apr 07 07:42:37 EDT 2015
+version=0.0.1-SNAPSHOT
+groupId=org.openliberty.openaz
+artifactId=openaz-xacml-pap-admin
diff --git a/openaz-xacml-pap-admin/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/openaz-xacml-pap-admin/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/openaz-xacml-pap-admin/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
diff --git a/openaz-xacml-pap-admin/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/openaz-xacml-pap-admin/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/openaz-xacml-pap-admin/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
diff --git a/openaz-xacml-pap-admin/target/openaz-xacml-pap-admin-0.0.1-SNAPSHOT.jar b/openaz-xacml-pap-admin/target/openaz-xacml-pap-admin-0.0.1-SNAPSHOT.jar
new file mode 100644
index 0000000..00bbf9f
--- /dev/null
+++ b/openaz-xacml-pap-admin/target/openaz-xacml-pap-admin-0.0.1-SNAPSHOT.jar
Binary files differ
diff --git a/openaz-xacml-pap-rest/WebContent/META-INF/MANIFEST.MF b/openaz-xacml-pap-rest/WebContent/META-INF/MANIFEST.MF
new file mode 100755
index 0000000..58630c0
--- /dev/null
+++ b/openaz-xacml-pap-rest/WebContent/META-INF/MANIFEST.MF
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0

+

diff --git a/openaz-xacml-pap-rest/WebContent/README.txt b/openaz-xacml-pap-rest/WebContent/README.txt
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/openaz-xacml-pap-rest/WebContent/README.txt
diff --git a/openaz-xacml-pap-rest/pdps/annotation/AnnotationPolicy.v1.xml b/openaz-xacml-pap-rest/pdps/annotation/AnnotationPolicy.v1.xml
new file mode 100755
index 0000000..ae838f4
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/annotation/AnnotationPolicy.v1.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="urn:com:att:xacml:policy:id:5b82db34-1613-4108-8973-93074182dd94" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">
+    <Description>A sample policy to demonstrate use of annotations in a Java class.</Description>
+    <Target>
+        <AnyOf>
+            <AllOf>
+                <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">www.mywebsite.com</AttributeValue>
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+                </Match>
+            </AllOf>
+        </AnyOf>
+    </Target>
+    <Rule RuleId="urn:com:att:xacml:rule:id:8b257f30-4e06-4c8e-8fb7-691b9534d55c" Effect="Permit">
+        <Description>PERMIT - John can access it</Description>
+        <Target>
+            <AnyOf>
+                <AllOf>
+                    <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">John</AttributeValue>
+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+                    </Match>
+                    <Match MatchId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case">
+                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">ACCESS</AttributeValue>
+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+                    </Match>
+                </AllOf>
+            </AnyOf>
+        </Target>
+    </Rule>
+    <Rule RuleId="urn:com:att:xacml:rule:id:4fe7c147-7811-4e30-a463-9135afb1cfc2" Effect="Deny">
+        <Description>DENY - Ringo cannot</Description>
+        <Target>
+            <AnyOf>
+                <AllOf>
+                    <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Ringo</AttributeValue>
+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+                    </Match>
+                </AllOf>
+            </AnyOf>
+        </Target>
+    </Rule>
+</Policy>
diff --git a/openaz-xacml-pap-rest/pdps/annotation/xacml.pip.properties b/openaz-xacml-pap-rest/pdps/annotation/xacml.pip.properties
new file mode 100755
index 0000000..999c160
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/annotation/xacml.pip.properties
@@ -0,0 +1,3 @@
+# PIP Engine Definition
+#
+xacml.pip.engines=
diff --git a/openaz-xacml-pap-rest/pdps/annotation/xacml.policy.properties b/openaz-xacml-pap-rest/pdps/annotation/xacml.policy.properties
new file mode 100755
index 0000000..1e6bf8a
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/annotation/xacml.policy.properties
@@ -0,0 +1,5 @@
+xacml.rootPolicies=AnnotationPolicy.v1.xml
+xacml.referencedPolicies=
+
+
+AnnotationPolicy.v1.xml.url=http://localhost:9090/pap/?id=AnnotationPolicy.v1.xml
diff --git a/openaz-xacml-pap-rest/pdps/configurable-csv-and-hyper/CSV-Baseball-Hall-Of-Fame-v1.xml b/openaz-xacml-pap-rest/pdps/configurable-csv-and-hyper/CSV-Baseball-Hall-Of-Fame-v1.xml
new file mode 100755
index 0000000..68c7783
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/configurable-csv-and-hyper/CSV-Baseball-Hall-Of-Fame-v1.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<PolicySet xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicySetId="urn:com:att:xacml:policy:id:f3047eab-6f97-49b4-8127-a2737a184b35" Version="1" PolicyCombiningAlgId="urn:oasis:names:tc:xacml:3.0:policy-combining-algorithm:deny-overrides">
+    <Description>This policy enforces the BBWAA rules for baseball Hall of Fame induction.
+
+http://baseballhall.org/hall-famers/rules-election/bbwaa
+</Description>
+    <Target>
+        <AnyOf>
+            <AllOf>
+                <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">eligible</AttributeValue>
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+                </Match>
+                <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">HOF</AttributeValue>
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+                </Match>
+            </AllOf>
+        </AnyOf>
+    </Target>
+    <Policy PolicyId="urn:com:att:xacml:policy:id:8f295c67-7b6e-4db6-b558-005b36abd970" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">
+        <Description>Active Timeframe:
+
+A. A baseball player must have been active as a player in the Major Leagues at some time during a period beginning twenty (20) years before and ending five (5) years prior to election.</Description>
+        <Target/>
+        <Rule RuleId="urn:com:att:xacml:rule:id:f04b2700-1236-4066-81e4-e341b5b2f3b5" Effect="Permit">
+            <Description>Player's debut date &gt;= (today's date - 20 years) AND final date &lt;= (today's date - 5 years).</Description>
+            <Target/>
+            <Condition>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
+                    <Description>debut within 20 years AND final game more than 5 years ago.</Description>
+                    <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-less-than-or-equal">
+                        <Description>Debut date &lt;= (today's date - 20 years)</Description>
+                        <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-one-and-only">
+                            <Description>UN-bag player's debut date.</Description>
+                            <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:debut" DataType="http://www.w3.org/2001/XMLSchema#date" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/>
+                        </Apply>
+                        <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:date-subtract-yearMonthDuration">
+                            <Description>Subtract 20 years from  today's date.</Description>
+                            <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-one-and-only">
+<Description>UN-bag today's date.</Description>
+<AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:environment" AttributeId="urn:oasis:names:tc:xacml:1.0:environment:current-date" DataType="http://www.w3.org/2001/XMLSchema#date" MustBePresent="false"/>
+                            </Apply>
+                            <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#yearMonthDuration">P20Y</AttributeValue>
+                        </Apply>
+                    </Apply>
+                    <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-less-than-or-equal">
+                        <Description>Final Game &lt;= (today's date - 5 years)</Description>
+                        <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-one-and-only">
+                            <Description>UN-bag final game date</Description>
+                            <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:finalgame" DataType="http://www.w3.org/2001/XMLSchema#date" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/>
+                        </Apply>
+                        <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:date-subtract-yearMonthDuration">
+                            <Description>Subtract 5 years from today's date.</Description>
+                            <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-one-and-only">
+<Description>UN-bag today's date.</Description>
+<AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:environment" AttributeId="urn:oasis:names:tc:xacml:1.0:environment:current-date" DataType="http://www.w3.org/2001/XMLSchema#date" MustBePresent="false"/>
+                            </Apply>
+                            <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#yearMonthDuration">P5Y</AttributeValue>
+                        </Apply>
+                    </Apply>
+                </Apply>
+            </Condition>
+        </Rule>
+        <Rule RuleId="urn:com:att:xacml:rule:id:33a42a79-9d82-4aa1-99d3-9fd168363695" Effect="Deny">
+            <Description>DENY - Default</Description>
+            <Target/>
+        </Rule>
+    </Policy>
+    <Policy PolicyId="urn:com:att:xacml:policy:id:1bf74cc4-658f-4e87-be22-5d5cb741f1f5" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">
+        <Description>B. Player must have played in each of ten (10) Major League championship seasons, some part of which must have been within the period described in 3 (A).</Description>
+        <Target/>
+        <Rule RuleId="urn:com:att:xacml:rule:id:54405c39-a3f6-4a88-89bd-084f68567acd" Effect="Permit">
+            <Description>There should be &gt;= 10 years of appearance(s) values.</Description>
+            <Target/>
+            <Condition>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal">
+                    <Description>The number of years a player appeared.</Description>
+                    <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-bag-size">
+                        <Description>Count the number.</Description>
+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:appearance" DataType="http://www.w3.org/2001/XMLSchema#integer" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/>
+                    </Apply>
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">10</AttributeValue>
+                </Apply>
+            </Condition>
+        </Rule>
+        <Rule RuleId="urn:com:att:xacml:rule:id:912dd1a2-1527-4b6f-a95b-6a729ff9caab" Effect="Deny">
+            <Description>DENY - Default</Description>
+            <Target/>
+        </Rule>
+    </Policy>
+</PolicySet>
diff --git a/openaz-xacml-pap-rest/pdps/configurable-csv-and-hyper/CSV-Legal-Age-Marriage-v1.xml b/openaz-xacml-pap-rest/pdps/configurable-csv-and-hyper/CSV-Legal-Age-Marriage-v1.xml
new file mode 100755
index 0000000..15e25ed
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/configurable-csv-and-hyper/CSV-Legal-Age-Marriage-v1.xml
@@ -0,0 +1,200 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<PolicySet xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicySetId="urn:com:att:xacml:policy:id:98779898-b880-44d7-bee5-ce54e42266eb" Version="1" PolicyCombiningAlgId="urn:oasis:names:tc:xacml:3.0:policy-combining-algorithm:deny-overrides">
+    <Description>Sample policy for the XACML-TEST project that tests the configurable CSV PIP.</Description>
+    <Target>
+        <AnyOf>
+            <AllOf>
+                <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Marry</AttributeValue>
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+                </Match>
+            </AllOf>
+        </AnyOf>
+    </Target>
+    <Policy PolicyId="urn:com:att:xacml:policy:id:c6791398-7e1f-4564-8f5c-19f406ea9950" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-unless-permit">
+        <Description>Checks the subject. </Description>
+        <Target/>
+        <VariableDefinition VariableId="isSubjectFemale">
+            <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case">
+                <Description>sex=Female</Description>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+                    <Description>un-bag</Description>
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:sex" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+                </Apply>
+                <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Female</AttributeValue>
+            </Apply>
+        </VariableDefinition>
+        <VariableDefinition VariableId="isSubjectMale">
+            <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case">
+                <Description>subject sex=Male</Description>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+                    <Description>Un-bag</Description>
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:sex" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+                </Apply>
+                <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Male</AttributeValue>
+            </Apply>
+        </VariableDefinition>
+        <VariableDefinition VariableId="doesSubjectNeedParentalConsent">
+            <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:or">
+                <Description>Is the subject a female OR male?</Description>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
+                    <Description>Is female AND does not need parental consent.</Description>
+                    <VariableReference VariableId="isSubjectFemale"/>
+                    <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than">
+                        <Description>age &gt;= consent age</Description>
+                        <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+                            <Description>Un-bag attribute.</Description>
+                            <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:age" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="true"/>
+                        </Apply>
+                        <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+                            <Description>Un-bag attribute.</Description>
+                            <AttributeDesignator Category="com:att:research:xacml:test:csv:category:country" AttributeId="com:att:research:xacml:test:csv:country:no-consent:female" DataType="http://www.w3.org/2001/XMLSchema#integer" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/>
+                        </Apply>
+                    </Apply>
+                </Apply>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
+                    <Description>Is subject male AND age &gt;= male consent age.</Description>
+                    <VariableReference VariableId="isSubjectMale"/>
+                    <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than">
+                        <Description>age &gt;= legal age of consent for male.</Description>
+                        <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+                            <Description>Un-bag attribute.</Description>
+                            <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:age" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="true"/>
+                        </Apply>
+                        <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+                            <Description>Un-bag attribute.</Description>
+                            <AttributeDesignator Category="com:att:research:xacml:test:csv:category:country" AttributeId="com:att:research:xacml:test:csv:country:no-consent:male" DataType="http://www.w3.org/2001/XMLSchema#integer" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/>
+                        </Apply>
+                    </Apply>
+                </Apply>
+            </Apply>
+        </VariableDefinition>
+         <VariableDefinition VariableId="doesSubjectHaveParentalConsent">
+            <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-one-and-only">
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:parental-consent" DataType="http://www.w3.org/2001/XMLSchema#boolean" MustBePresent="true"/>
+                </Apply>
+                <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue>
+            </Apply>
+        </VariableDefinition>
+        <Rule RuleId="urn:com:att:xacml:rule:id:5970b5d2-c0f3-4132-bfa2-268467b21ed7" Effect="Permit">
+            <Description>If the subject does NOT need consent, then PERMIT.</Description>
+            <Target/>
+            <Condition>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+                    <VariableReference VariableId="doesSubjectNeedParentalConsent"/>
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">false</AttributeValue>
+                </Apply>
+            </Condition>
+        </Rule>
+        <Rule RuleId="urn:com:att:xacml:rule:id:04b3e93d-ec4e-4cce-a00e-6a54cf3c4056" Effect="Permit">
+            <Description>If the subject needs consent AND has parental consent, then Permit.</Description>
+            <Target/>
+            <Condition>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
+                    <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+                        <VariableReference VariableId="doesSubjectNeedParentalConsent"/>
+                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue>
+                    </Apply>
+                    <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+                        <VariableReference VariableId="doesSubjectHaveParentalConsent"/>
+                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue>
+                    </Apply>
+                </Apply>
+            </Condition>
+        </Rule>
+    </Policy>
+    <Policy PolicyId="urn:com:att:xacml:policy:id:32474315-9d06-47a4-bc2d-319e0568742c" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-unless-permit">
+        <Description>Check the resource.</Description>
+        <Target/>
+        <VariableDefinition VariableId="isResourceFemale">
+            <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case">
+                <Description>sex=Female</Description>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+                    <Description>un-bag</Description>
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:csv:resource:sex" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+                </Apply>
+                <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Female</AttributeValue>
+            </Apply>
+        </VariableDefinition>
+        <VariableDefinition VariableId="isResourceMale">
+            <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case">
+                <Description>subject sex=Male</Description>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+                    <Description>Un-bag</Description>
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:csv:resource:sex" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+                </Apply>
+                <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Male</AttributeValue>
+            </Apply>
+        </VariableDefinition>
+        <VariableDefinition VariableId="doesResourceNeedParentalConsent">
+            <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:or">
+                <Description>Is resource female OR male?</Description>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
+                    <Description>Is female AND does not need parental consent.</Description>
+                    <VariableReference VariableId="isResourceFemale"/>
+                    <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than">
+                        <Description>age &gt;= consent age for female.</Description>
+                        <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+                            <Description>Un-bag attribute</Description>
+                            <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:csv:resource:age" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="true"/>
+                        </Apply>
+                        <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+                            <Description>un-bag attribute</Description>
+                            <AttributeDesignator Category="com:att:research:xacml:test:csv:category:country" AttributeId="com:att:research:xacml:test:csv:country:no-consent:female" DataType="http://www.w3.org/2001/XMLSchema#integer" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/>
+                        </Apply>
+                    </Apply>
+                </Apply>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
+                    <Description>Is male and AND does not need parental consent.</Description>
+                    <VariableReference VariableId="isResourceMale"/>
+                    <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than">
+                        <Description>age &gt;= consent age for male.</Description>
+                        <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+                            <Description>Un-bag</Description>
+                            <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:csv:resource:age" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="false"/>
+                        </Apply>
+                        <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+                            <Description>Un-bag</Description>
+                            <AttributeDesignator Category="com:att:research:xacml:test:csv:category:country" AttributeId="com:att:research:xacml:test:csv:country:no-consent:male" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="false"/>
+                        </Apply>
+                    </Apply>
+                </Apply>
+            </Apply>
+        </VariableDefinition>
+        <VariableDefinition VariableId="doesResourceHaveParentalConsent">
+            <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-one-and-only">
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:csv:resource:parental-consent" DataType="http://www.w3.org/2001/XMLSchema#boolean" MustBePresent="true"/>
+                </Apply>
+                <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue>
+            </Apply>
+        </VariableDefinition>
+        <Rule RuleId="urn:com:att:xacml:rule:id:7d1c6802-97f7-44f6-9819-12edc1801fb7" Effect="Permit">
+            <Description>If the resource does NOT need consent, then PERMIT.</Description>
+            <Target/>
+            <Condition>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+                    <VariableReference VariableId="doesResourceNeedParentalConsent"/>
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">false</AttributeValue>
+                </Apply>
+            </Condition>
+        </Rule>
+        <Rule RuleId="urn:com:att:xacml:rule:id:62e07da4-f0e5-46eb-9894-f5e6d2e5868b" Effect="Permit">
+            <Description>The resources needs parental consent and has parental consent then PERMIT.</Description>
+            <Target/>
+            <Condition>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
+                    <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+                        <VariableReference VariableId="doesResourceNeedParentalConsent"/>
+                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue>
+                    </Apply>
+                    <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+                        <VariableReference VariableId="doesResourceHaveParentalConsent"/>
+                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue>
+                    </Apply>
+                </Apply>
+            </Condition>
+        </Rule>
+    </Policy>
+</PolicySet>
diff --git a/openaz-xacml-pap-rest/pdps/configurable-csv-and-hyper/xacml.pip.properties b/openaz-xacml-pap-rest/pdps/configurable-csv-and-hyper/xacml.pip.properties
new file mode 100755
index 0000000..17ec3a2
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/configurable-csv-and-hyper/xacml.pip.properties
@@ -0,0 +1,227 @@
+# PIP Engine Definition
+#
+xacml.pip.engines=csv1,csv2,hyper1
+
+ATTWebPhone.classname=com.att.research.xacmlatt.pip.webphone.PIPEngineATTWebphone
+CSO.classname=com.att.research.xacmlatt.pip.cso.PIPEngineCSOCookie
+CSO.mode=DEVL
+
+csv1.classname=com.att.research.xacml.std.pip.engines.csv.CSVEngine
+csv1.name=Master
+csv1.description=Sean Lahman Basebase stats - Player names, DOB, and biographical info
+csv1.issuer=com:att:research:xacml:test:csv
+csv1.source=../XACML-TEST/testsets/pip/configurable-csv/adminDB/Master.txt
+csv1.maxsize=500000
+csv1.delimiter=,
+csv1.quote="
+csv1.skip=0
+
+csv1.resolvers=data
+
+csv1.resolver.data.classname=com.att.research.xacml.std.pip.engines.csv.ConfigurableCSVResolver
+csv1.resolver.data.name=Player Resolver
+csv1.resolver.data.description=This resolver finds player information in the Master table.
+csv1.resolver.data.fields=firstname,lastname,deathyear,deathmonth,deathday,debut,finalgame
+csv1.resolver.data.field.firstname.column=16
+csv1.resolver.data.field.firstname.id=com:att:research:xacml:test:csv:subject:firstname
+csv1.resolver.data.field.firstname.datatype=http://www.w3.org/2001/XMLSchema#string
+csv1.resolver.data.field.firstname.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.lastname.column=17
+csv1.resolver.data.field.lastname.id=com:att:research:xacml:test:csv:subject:lastname
+csv1.resolver.data.field.lastname.datatype=http://www.w3.org/2001/XMLSchema#string
+csv1.resolver.data.field.lastname.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.deathyear.column=10
+csv1.resolver.data.field.deathyear.id=com:att:research:xacml:test:csv:subject:deathyear
+csv1.resolver.data.field.deathyear.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv1.resolver.data.field.deathyear.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.deathmonth.column=11
+csv1.resolver.data.field.deathmonth.id=com:att:research:xacml:test:csv:subject:deathmonth
+csv1.resolver.data.field.deathmonth.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv1.resolver.data.field.deathmonth.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.deathday.column=12
+csv1.resolver.data.field.deathday.id=com:att:research:xacml:test:csv:subject:deathday
+csv1.resolver.data.field.deathday.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv1.resolver.data.field.deathday.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.debut.column=25
+csv1.resolver.data.field.debut.id=com:att:research:xacml:test:csv:subject:debut
+csv1.resolver.data.field.debut.datatype=http://www.w3.org/2001/XMLSchema#date
+csv1.resolver.data.field.debut.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.finalgame.column=26
+csv1.resolver.data.field.finalgame.id=com:att:research:xacml:test:csv:subject:finalgame
+csv1.resolver.data.field.finalgame.datatype=http://www.w3.org/2001/XMLSchema#date
+csv1.resolver.data.field.finalgame.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.parameters=playerid
+csv1.resolver.data.parameter.playerid.column=1
+csv1.resolver.data.parameter.playerid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id
+csv1.resolver.data.parameter.playerid.datatype=http://www.w3.org/2001/XMLSchema#string
+csv1.resolver.data.parameter.playerid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv2.classname=com.att.research.xacml.std.pip.engines.csv.CSVEngine
+csv2.name=Appearances
+csv2.description=Sean Lahman Basebase stats - Player appearances for a team in a given year.
+#csv2.issuer=
+csv2.source=../XACML-TEST/testsets/pip/configurable-csv/adminDB/Appearances.txt
+csv2.maxsize=500000
+csv2.delimiter=,
+csv2.quote="
+csv2.skip=0
+
+csv2.resolvers=data
+
+csv2.resolver.data.classname=com.att.research.xacml.std.pip.engines.csv.ConfigurableCSVResolver
+csv2.resolver.data.name=Appearance Resolver
+csv2.resolver.data.description=This resolver returns all the appearances for a player from the appearance table.
+csv2.resolver.data.fields=appearance
+csv2.resolver.data.field.appearance.column=0
+csv2.resolver.data.field.appearance.id=com:att:research:xacml:test:csv:subject:appearance
+csv2.resolver.data.field.appearance.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv2.resolver.data.field.appearance.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+csv2.resolver.data.field.appearance.issuer=com:att:research:xacml:test:csv
+
+csv2.resolver.data.parameters=playerid
+csv2.resolver.data.parameter.playerid.column=3
+csv2.resolver.data.parameter.playerid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id
+csv2.resolver.data.parameter.playerid.datatype=http://www.w3.org/2001/XMLSchema#string
+csv2.resolver.data.parameter.playerid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+#csv1.resolver.data.parameter.playerid.issuer=
+
+hyper1.classname=com.att.research.xacml.std.pip.engines.csv.HyperCSVEngine
+hyper1.name=World Marriage Age Limits
+hyper1.description=Minimum age for female/male marriages with or without their parental consent.
+hyper1.source=../XACML-TEST/testsets/pip/configurable-csv-hyper/marriage.csv
+hyper1.target=marriage
+hyper1.definition=country VARCHAR(80) PRIMARY KEY, wofemale INT, womale INT, wfemale INT, wmale INT, year INT, source VARCHAR(20)
+
+hyper1.resolvers=age_consent
+
+hyper1.resolver.age_consent.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver
+hyper1.resolver.age_consent.name=Ages
+hyper1.resolver.age_consent.description=This returns all the age's for consent or no consent for a country.
+hyper1.resolver.age_consent.select=SELECT wofemale,womale,wfemale,wmale FROM marriage WHERE country=?
+hyper1.resolver.age_consent.fields=wofemale,womale,wfemale,wmale
+
+hyper1.resolver.age_consent.field.wofemale.id=com:att:research:xacml:test:csv:country:no-consent:female
+hyper1.resolver.age_consent.field.wofemale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.wofemale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.wofemale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.field.womale.id=com:att:research:xacml:test:csv:country:no-consent:male
+hyper1.resolver.age_consent.field.womale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.womale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.womale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.field.wfemale.id=com:att:research:xacml:test:csv:country:consent:female
+hyper1.resolver.age_consent.field.wfemale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.wfemale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.wfemale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.field.wmale.id=com:att:research:xacml:test:csv:country:consent:male
+hyper1.resolver.age_consent.field.wmale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.wmale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.wmale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.parameters=country
+hyper1.resolver.age_consent.parameter.country.id=com:att:research:xacml:test:csv:country:name
+hyper1.resolver.age_consent.parameter.country.datatype=http://www.w3.org/2001/XMLSchema#string
+hyper1.resolver.age_consent.parameter.country.category=com:att:research:xacml:test:csv:category:country
+#hyper1.resolver.age_consent.parameter.country.issuer=
+
+sql1.classname=com.att.research.xacml.std.pip.engines.jdbc.JDBCEngine
+sql1.name=World
+sql1.description=World Database from MySQL website. Copyright Statistics Finland, http://www.stat.fi/worldinfigures.
+# This will be the default issuer for the resolvers. NOTE: Issuer only used for attributes provided by the engine.
+sql1.issuer=com:att:research:xacml:test:sql
+#
+# This is the configuration for JDBC. You will have to setup the database and run the data\world*.sql script to
+# create the tables and load the data. 
+#
+sql1.type=jdbc
+sql1.jdbc.driver=org.postgresql.Driver
+#sql1.jdbc.url=jdbc:postgresql://localhost:5432/world
+#sql1.jdbc.conn.user=sa
+#sql1.jdbc.conn.password=
+sql1.jdbc.url=jdbc:postgresql://xacml-pip.research.att.com:5432/world
+sql1.jdbc.conn.user=pip
+sql1.jdbc.conn.password=p1pUs3r
+#
+# This is the configuration for JNDI datasource.
+#
+#sql1.type=jndi
+#sql1.datasource=jdbc/xacml
+
+sql1.resolvers=langer
+
+sql1.resolver.langer.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver
+sql1.resolver.langer.name=Language
+sql1.resolver.langer.description=This returns the language for a city.
+sql1.resolver.langer.select=SELECT language FROM city INNER JOIN countrylanguage ON city.countrycode = countrylanguage.countrycode WHERE name=?
+sql1.resolver.langer.fields=language
+sql1.resolver.langer.field.language.id=com:att:research:xacml:test:sql:resource:city:language
+sql1.resolver.langer.field.language.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.langer.field.language.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+#You can override the default issuer that is set in the JDBCEngine definition if you want.
+#sql1.resolver.langer.field.language.issuer=com:att:research:xacml:test:sql
+sql1.resolver.langer.parameters=name
+sql1.resolver.langer.parameter.name.id=urn:oasis:names:tc:xacml:1.0:resource:resource-id
+sql1.resolver.langer.parameter.name.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.langer.parameter.name.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+
+
+ldap1.classname=com.att.research.xacml.std.pip.engines.ldap.LDAPEngine
+ldap1.name=LDAP PIP
+ldap1.description=The LDAP containing the seven seas sample LDIF data.
+ldap1.issuer=com:att:research:xacml:test:ldap
+ldap1.java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory
+#
+# NOTE: You will have to setup a local LDAP server and load the data\apache-ds-tutorial.ldif before
+# this example will work.
+#
+#ldap1.java.naming.provider.url=ldap://localhost:10389
+ldap1.java.naming.provider.url=ldap://xacml-pip.research.att.com:10389
+#ldap.java.naming.security.principal=
+#ldap.java.naming.security.credentials=
+ldap1.scope=subtree
+
+ldap1.resolvers=dn,ship
+
+ldap1.resolver.dn.classname=com.att.research.xacml.std.pip.engines.ldap.ConfigurableLDAPResolver
+ldap1.resolver.dn.name=Domain Names
+ldap1.resolver.dn.description=Find all the dn's for the subject id
+ldap1.resolver.dn.base=o=sevenseas
+ldap1.resolver.dn.base.parameters=
+ldap1.resolver.dn.filter=(|(uid=${uid})(mail=${uid}))
+ldap1.resolver.dn.filter.parameters=uid
+ldap1.resolver.dn.filter.parameters.uid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id
+ldap1.resolver.dn.filter.parameters.uid.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.dn.filter.parameters.uid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+#ldap1.resolver.dn.filter.parameters.uid.issuer=com:att:research:xacml:test:ldap
+ldap1.resolver.dn.filter.view=dn
+ldap1.resolver.dn.filter.view.dn.id=com:att:research:xacml:test:ldap:subject:dn
+ldap1.resolver.dn.filter.view.dn.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.dn.filter.view.dn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+ldap1.resolver.dn.filter.view.dn.issuer=com:att:research:xacml:test:ldap
+
+ldap1.resolver.ship.classname=com.att.research.xacml.std.pip.engines.ldap.ConfigurableLDAPResolver
+ldap1.resolver.ship.name=Ship Resolver
+ldap1.resolver.ship.description=This resolves a subject's dn to a ship.
+ldap1.resolver.ship.base=o=sevenseas
+ldap1.resolver.ship.base.parameters=
+ldap1.resolver.ship.filter=uniquemember=${dn}
+ldap1.resolver.ship.filter.parameters=dn
+ldap1.resolver.ship.filter.parameters.dn.id=com:att:research:xacml:test:ldap:subject:dn
+ldap1.resolver.ship.filter.parameters.dn.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.ship.filter.parameters.dn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+ldap1.resolver.ship.filter.parameters.dn.issuer=com:att:research:xacml:test:ldap
+ldap1.resolver.ship.filter.view=cn
+ldap1.resolver.ship.filter.view.cn.id=com:att:research:xacml:test:ldap:subject:ship
+ldap1.resolver.ship.filter.view.cn.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.ship.filter.view.cn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+ldap1.resolver.ship.filter.view.cn.issuer=com:att:research:xacml:test:ldap
+
diff --git a/openaz-xacml-pap-rest/pdps/configurable-csv-and-hyper/xacml.policy.properties b/openaz-xacml-pap-rest/pdps/configurable-csv-and-hyper/xacml.policy.properties
new file mode 100755
index 0000000..6c2cb20
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/configurable-csv-and-hyper/xacml.policy.properties
@@ -0,0 +1,8 @@
+xacml.rootPolicies=CSV-Baseball-Hall-Of-Fame-v1.xml,CSV-Legal-Age-Marriage-v1.xml
+xacml.referencedPolicies=
+
+
+CSV-Baseball-Hall-Of-Fame-v1.xml.url=http://localhost:9090/pap/?id=CSV-Baseball-Hall-Of-Fame-v1.xml
+
+CSV-Legal-Age-Marriage-v1.xml.url=http://localhost:9090/pap/?id=CSV-Legal-Age-Marriage-v1.xml
+
diff --git a/openaz-xacml-pap-rest/pdps/configurable-csv-hyper/CSV-Legal-Age-Marriage-v1.xml b/openaz-xacml-pap-rest/pdps/configurable-csv-hyper/CSV-Legal-Age-Marriage-v1.xml
new file mode 100755
index 0000000..15e25ed
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/configurable-csv-hyper/CSV-Legal-Age-Marriage-v1.xml
@@ -0,0 +1,200 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<PolicySet xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicySetId="urn:com:att:xacml:policy:id:98779898-b880-44d7-bee5-ce54e42266eb" Version="1" PolicyCombiningAlgId="urn:oasis:names:tc:xacml:3.0:policy-combining-algorithm:deny-overrides">
+    <Description>Sample policy for the XACML-TEST project that tests the configurable CSV PIP.</Description>
+    <Target>
+        <AnyOf>
+            <AllOf>
+                <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Marry</AttributeValue>
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+                </Match>
+            </AllOf>
+        </AnyOf>
+    </Target>
+    <Policy PolicyId="urn:com:att:xacml:policy:id:c6791398-7e1f-4564-8f5c-19f406ea9950" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-unless-permit">
+        <Description>Checks the subject. </Description>
+        <Target/>
+        <VariableDefinition VariableId="isSubjectFemale">
+            <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case">
+                <Description>sex=Female</Description>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+                    <Description>un-bag</Description>
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:sex" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+                </Apply>
+                <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Female</AttributeValue>
+            </Apply>
+        </VariableDefinition>
+        <VariableDefinition VariableId="isSubjectMale">
+            <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case">
+                <Description>subject sex=Male</Description>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+                    <Description>Un-bag</Description>
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:sex" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+                </Apply>
+                <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Male</AttributeValue>
+            </Apply>
+        </VariableDefinition>
+        <VariableDefinition VariableId="doesSubjectNeedParentalConsent">
+            <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:or">
+                <Description>Is the subject a female OR male?</Description>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
+                    <Description>Is female AND does not need parental consent.</Description>
+                    <VariableReference VariableId="isSubjectFemale"/>
+                    <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than">
+                        <Description>age &gt;= consent age</Description>
+                        <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+                            <Description>Un-bag attribute.</Description>
+                            <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:age" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="true"/>
+                        </Apply>
+                        <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+                            <Description>Un-bag attribute.</Description>
+                            <AttributeDesignator Category="com:att:research:xacml:test:csv:category:country" AttributeId="com:att:research:xacml:test:csv:country:no-consent:female" DataType="http://www.w3.org/2001/XMLSchema#integer" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/>
+                        </Apply>
+                    </Apply>
+                </Apply>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
+                    <Description>Is subject male AND age &gt;= male consent age.</Description>
+                    <VariableReference VariableId="isSubjectMale"/>
+                    <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than">
+                        <Description>age &gt;= legal age of consent for male.</Description>
+                        <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+                            <Description>Un-bag attribute.</Description>
+                            <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:age" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="true"/>
+                        </Apply>
+                        <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+                            <Description>Un-bag attribute.</Description>
+                            <AttributeDesignator Category="com:att:research:xacml:test:csv:category:country" AttributeId="com:att:research:xacml:test:csv:country:no-consent:male" DataType="http://www.w3.org/2001/XMLSchema#integer" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/>
+                        </Apply>
+                    </Apply>
+                </Apply>
+            </Apply>
+        </VariableDefinition>
+         <VariableDefinition VariableId="doesSubjectHaveParentalConsent">
+            <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-one-and-only">
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:parental-consent" DataType="http://www.w3.org/2001/XMLSchema#boolean" MustBePresent="true"/>
+                </Apply>
+                <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue>
+            </Apply>
+        </VariableDefinition>
+        <Rule RuleId="urn:com:att:xacml:rule:id:5970b5d2-c0f3-4132-bfa2-268467b21ed7" Effect="Permit">
+            <Description>If the subject does NOT need consent, then PERMIT.</Description>
+            <Target/>
+            <Condition>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+                    <VariableReference VariableId="doesSubjectNeedParentalConsent"/>
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">false</AttributeValue>
+                </Apply>
+            </Condition>
+        </Rule>
+        <Rule RuleId="urn:com:att:xacml:rule:id:04b3e93d-ec4e-4cce-a00e-6a54cf3c4056" Effect="Permit">
+            <Description>If the subject needs consent AND has parental consent, then Permit.</Description>
+            <Target/>
+            <Condition>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
+                    <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+                        <VariableReference VariableId="doesSubjectNeedParentalConsent"/>
+                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue>
+                    </Apply>
+                    <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+                        <VariableReference VariableId="doesSubjectHaveParentalConsent"/>
+                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue>
+                    </Apply>
+                </Apply>
+            </Condition>
+        </Rule>
+    </Policy>
+    <Policy PolicyId="urn:com:att:xacml:policy:id:32474315-9d06-47a4-bc2d-319e0568742c" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-unless-permit">
+        <Description>Check the resource.</Description>
+        <Target/>
+        <VariableDefinition VariableId="isResourceFemale">
+            <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case">
+                <Description>sex=Female</Description>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+                    <Description>un-bag</Description>
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:csv:resource:sex" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+                </Apply>
+                <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Female</AttributeValue>
+            </Apply>
+        </VariableDefinition>
+        <VariableDefinition VariableId="isResourceMale">
+            <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case">
+                <Description>subject sex=Male</Description>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+                    <Description>Un-bag</Description>
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:csv:resource:sex" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+                </Apply>
+                <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Male</AttributeValue>
+            </Apply>
+        </VariableDefinition>
+        <VariableDefinition VariableId="doesResourceNeedParentalConsent">
+            <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:or">
+                <Description>Is resource female OR male?</Description>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
+                    <Description>Is female AND does not need parental consent.</Description>
+                    <VariableReference VariableId="isResourceFemale"/>
+                    <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than">
+                        <Description>age &gt;= consent age for female.</Description>
+                        <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+                            <Description>Un-bag attribute</Description>
+                            <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:csv:resource:age" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="true"/>
+                        </Apply>
+                        <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+                            <Description>un-bag attribute</Description>
+                            <AttributeDesignator Category="com:att:research:xacml:test:csv:category:country" AttributeId="com:att:research:xacml:test:csv:country:no-consent:female" DataType="http://www.w3.org/2001/XMLSchema#integer" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/>
+                        </Apply>
+                    </Apply>
+                </Apply>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
+                    <Description>Is male and AND does not need parental consent.</Description>
+                    <VariableReference VariableId="isResourceMale"/>
+                    <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than">
+                        <Description>age &gt;= consent age for male.</Description>
+                        <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+                            <Description>Un-bag</Description>
+                            <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:csv:resource:age" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="false"/>
+                        </Apply>
+                        <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+                            <Description>Un-bag</Description>
+                            <AttributeDesignator Category="com:att:research:xacml:test:csv:category:country" AttributeId="com:att:research:xacml:test:csv:country:no-consent:male" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="false"/>
+                        </Apply>
+                    </Apply>
+                </Apply>
+            </Apply>
+        </VariableDefinition>
+        <VariableDefinition VariableId="doesResourceHaveParentalConsent">
+            <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-one-and-only">
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:csv:resource:parental-consent" DataType="http://www.w3.org/2001/XMLSchema#boolean" MustBePresent="true"/>
+                </Apply>
+                <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue>
+            </Apply>
+        </VariableDefinition>
+        <Rule RuleId="urn:com:att:xacml:rule:id:7d1c6802-97f7-44f6-9819-12edc1801fb7" Effect="Permit">
+            <Description>If the resource does NOT need consent, then PERMIT.</Description>
+            <Target/>
+            <Condition>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+                    <VariableReference VariableId="doesResourceNeedParentalConsent"/>
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">false</AttributeValue>
+                </Apply>
+            </Condition>
+        </Rule>
+        <Rule RuleId="urn:com:att:xacml:rule:id:62e07da4-f0e5-46eb-9894-f5e6d2e5868b" Effect="Permit">
+            <Description>The resources needs parental consent and has parental consent then PERMIT.</Description>
+            <Target/>
+            <Condition>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
+                    <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+                        <VariableReference VariableId="doesResourceNeedParentalConsent"/>
+                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue>
+                    </Apply>
+                    <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+                        <VariableReference VariableId="doesResourceHaveParentalConsent"/>
+                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue>
+                    </Apply>
+                </Apply>
+            </Condition>
+        </Rule>
+    </Policy>
+</PolicySet>
diff --git a/openaz-xacml-pap-rest/pdps/configurable-csv-hyper/xacml.pip.properties b/openaz-xacml-pap-rest/pdps/configurable-csv-hyper/xacml.pip.properties
new file mode 100755
index 0000000..5f66428
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/configurable-csv-hyper/xacml.pip.properties
@@ -0,0 +1,227 @@
+# PIP Engine Definition
+#
+xacml.pip.engines=hyper1
+
+ATTWebPhone.classname=com.att.research.xacmlatt.pip.webphone.PIPEngineATTWebphone
+CSO.classname=com.att.research.xacmlatt.pip.cso.PIPEngineCSOCookie
+CSO.mode=DEVL
+
+csv1.classname=com.att.research.xacml.std.pip.engines.csv.CSVEngine
+csv1.name=Master
+csv1.description=Sean Lahman Basebase stats - Player names, DOB, and biographical info
+csv1.issuer=com:att:research:xacml:test:csv
+csv1.source=../XACML-TEST/testsets/pip/configurable-csv/adminDB/Master.txt
+csv1.maxsize=500000
+csv1.delimiter=,
+csv1.quote="
+csv1.skip=0
+
+csv1.resolvers=data
+
+csv1.resolver.data.classname=com.att.research.xacml.std.pip.engines.csv.ConfigurableCSVResolver
+csv1.resolver.data.name=Player Resolver
+csv1.resolver.data.description=This resolver finds player information in the Master table.
+csv1.resolver.data.fields=firstname,lastname,deathyear,deathmonth,deathday,debut,finalgame
+csv1.resolver.data.field.firstname.column=16
+csv1.resolver.data.field.firstname.id=com:att:research:xacml:test:csv:subject:firstname
+csv1.resolver.data.field.firstname.datatype=http://www.w3.org/2001/XMLSchema#string
+csv1.resolver.data.field.firstname.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.lastname.column=17
+csv1.resolver.data.field.lastname.id=com:att:research:xacml:test:csv:subject:lastname
+csv1.resolver.data.field.lastname.datatype=http://www.w3.org/2001/XMLSchema#string
+csv1.resolver.data.field.lastname.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.deathyear.column=10
+csv1.resolver.data.field.deathyear.id=com:att:research:xacml:test:csv:subject:deathyear
+csv1.resolver.data.field.deathyear.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv1.resolver.data.field.deathyear.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.deathmonth.column=11
+csv1.resolver.data.field.deathmonth.id=com:att:research:xacml:test:csv:subject:deathmonth
+csv1.resolver.data.field.deathmonth.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv1.resolver.data.field.deathmonth.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.deathday.column=12
+csv1.resolver.data.field.deathday.id=com:att:research:xacml:test:csv:subject:deathday
+csv1.resolver.data.field.deathday.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv1.resolver.data.field.deathday.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.debut.column=25
+csv1.resolver.data.field.debut.id=com:att:research:xacml:test:csv:subject:debut
+csv1.resolver.data.field.debut.datatype=http://www.w3.org/2001/XMLSchema#date
+csv1.resolver.data.field.debut.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.finalgame.column=26
+csv1.resolver.data.field.finalgame.id=com:att:research:xacml:test:csv:subject:finalgame
+csv1.resolver.data.field.finalgame.datatype=http://www.w3.org/2001/XMLSchema#date
+csv1.resolver.data.field.finalgame.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.parameters=playerid
+csv1.resolver.data.parameter.playerid.column=1
+csv1.resolver.data.parameter.playerid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id
+csv1.resolver.data.parameter.playerid.datatype=http://www.w3.org/2001/XMLSchema#string
+csv1.resolver.data.parameter.playerid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv2.classname=com.att.research.xacml.std.pip.engines.csv.CSVEngine
+csv2.name=Appearances
+csv2.description=Sean Lahman Basebase stats - Player appearances for a team in a given year.
+#csv2.issuer=
+csv2.source=../XACML-TEST/testsets/pip/configurable-csv/adminDB/Appearances.txt
+csv2.maxsize=500000
+csv2.delimiter=,
+csv2.quote="
+csv2.skip=0
+
+csv2.resolvers=data
+
+csv2.resolver.data.classname=com.att.research.xacml.std.pip.engines.csv.ConfigurableCSVResolver
+csv2.resolver.data.name=Appearance Resolver
+csv2.resolver.data.description=This resolver returns all the appearances for a player from the appearance table.
+csv2.resolver.data.fields=appearance
+csv2.resolver.data.field.appearance.column=0
+csv2.resolver.data.field.appearance.id=com:att:research:xacml:test:csv:subject:appearance
+csv2.resolver.data.field.appearance.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv2.resolver.data.field.appearance.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+csv2.resolver.data.field.appearance.issuer=com:att:research:xacml:test:csv
+
+csv2.resolver.data.parameters=playerid
+csv2.resolver.data.parameter.playerid.column=3
+csv2.resolver.data.parameter.playerid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id
+csv2.resolver.data.parameter.playerid.datatype=http://www.w3.org/2001/XMLSchema#string
+csv2.resolver.data.parameter.playerid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+#csv1.resolver.data.parameter.playerid.issuer=
+
+hyper1.classname=com.att.research.xacml.std.pip.engines.csv.HyperCSVEngine
+hyper1.name=World Marriage Age Limits
+hyper1.description=Minimum age for female/male marriages with or without their parental consent.
+hyper1.source=../XACML-TEST/testsets/pip/configurable-csv-hyper/marriage.csv
+hyper1.target=marriage
+hyper1.definition=country VARCHAR(80) PRIMARY KEY, wofemale INT, womale INT, wfemale INT, wmale INT, year INT, source VARCHAR(20)
+
+hyper1.resolvers=age_consent
+
+hyper1.resolver.age_consent.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver
+hyper1.resolver.age_consent.name=Ages
+hyper1.resolver.age_consent.description=This returns all the age's for consent or no consent for a country.
+hyper1.resolver.age_consent.select=SELECT wofemale,womale,wfemale,wmale FROM marriage WHERE country=?
+hyper1.resolver.age_consent.fields=wofemale,womale,wfemale,wmale
+
+hyper1.resolver.age_consent.field.wofemale.id=com:att:research:xacml:test:csv:country:no-consent:female
+hyper1.resolver.age_consent.field.wofemale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.wofemale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.wofemale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.field.womale.id=com:att:research:xacml:test:csv:country:no-consent:male
+hyper1.resolver.age_consent.field.womale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.womale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.womale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.field.wfemale.id=com:att:research:xacml:test:csv:country:consent:female
+hyper1.resolver.age_consent.field.wfemale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.wfemale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.wfemale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.field.wmale.id=com:att:research:xacml:test:csv:country:consent:male
+hyper1.resolver.age_consent.field.wmale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.wmale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.wmale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.parameters=country
+hyper1.resolver.age_consent.parameter.country.id=com:att:research:xacml:test:csv:country:name
+hyper1.resolver.age_consent.parameter.country.datatype=http://www.w3.org/2001/XMLSchema#string
+hyper1.resolver.age_consent.parameter.country.category=com:att:research:xacml:test:csv:category:country
+#hyper1.resolver.age_consent.parameter.country.issuer=
+
+sql1.classname=com.att.research.xacml.std.pip.engines.jdbc.JDBCEngine
+sql1.name=World
+sql1.description=World Database from MySQL website. Copyright Statistics Finland, http://www.stat.fi/worldinfigures.
+# This will be the default issuer for the resolvers. NOTE: Issuer only used for attributes provided by the engine.
+sql1.issuer=com:att:research:xacml:test:sql
+#
+# This is the configuration for JDBC. You will have to setup the database and run the data\world*.sql script to
+# create the tables and load the data. 
+#
+sql1.type=jdbc
+sql1.jdbc.driver=org.postgresql.Driver
+#sql1.jdbc.url=jdbc:postgresql://localhost:5432/world
+#sql1.jdbc.conn.user=sa
+#sql1.jdbc.conn.password=
+sql1.jdbc.url=jdbc:postgresql://xacml-pip.research.att.com:5432/world
+sql1.jdbc.conn.user=pip
+sql1.jdbc.conn.password=p1pUs3r
+#
+# This is the configuration for JNDI datasource.
+#
+#sql1.type=jndi
+#sql1.datasource=jdbc/xacml
+
+sql1.resolvers=langer
+
+sql1.resolver.langer.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver
+sql1.resolver.langer.name=Language
+sql1.resolver.langer.description=This returns the language for a city.
+sql1.resolver.langer.select=SELECT language FROM city INNER JOIN countrylanguage ON city.countrycode = countrylanguage.countrycode WHERE name=?
+sql1.resolver.langer.fields=language
+sql1.resolver.langer.field.language.id=com:att:research:xacml:test:sql:resource:city:language
+sql1.resolver.langer.field.language.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.langer.field.language.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+#You can override the default issuer that is set in the JDBCEngine definition if you want.
+#sql1.resolver.langer.field.language.issuer=com:att:research:xacml:test:sql
+sql1.resolver.langer.parameters=name
+sql1.resolver.langer.parameter.name.id=urn:oasis:names:tc:xacml:1.0:resource:resource-id
+sql1.resolver.langer.parameter.name.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.langer.parameter.name.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+
+
+ldap1.classname=com.att.research.xacml.std.pip.engines.ldap.LDAPEngine
+ldap1.name=LDAP PIP
+ldap1.description=The LDAP containing the seven seas sample LDIF data.
+ldap1.issuer=com:att:research:xacml:test:ldap
+ldap1.java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory
+#
+# NOTE: You will have to setup a local LDAP server and load the data\apache-ds-tutorial.ldif before
+# this example will work.
+#
+#ldap1.java.naming.provider.url=ldap://localhost:10389
+ldap1.java.naming.provider.url=ldap://xacml-pip.research.att.com:10389
+#ldap.java.naming.security.principal=
+#ldap.java.naming.security.credentials=
+ldap1.scope=subtree
+
+ldap1.resolvers=dn,ship
+
+ldap1.resolver.dn.classname=com.att.research.xacml.std.pip.engines.ldap.ConfigurableLDAPResolver
+ldap1.resolver.dn.name=Domain Names
+ldap1.resolver.dn.description=Find all the dn's for the subject id
+ldap1.resolver.dn.base=o=sevenseas
+ldap1.resolver.dn.base.parameters=
+ldap1.resolver.dn.filter=(|(uid=${uid})(mail=${uid}))
+ldap1.resolver.dn.filter.parameters=uid
+ldap1.resolver.dn.filter.parameters.uid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id
+ldap1.resolver.dn.filter.parameters.uid.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.dn.filter.parameters.uid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+#ldap1.resolver.dn.filter.parameters.uid.issuer=com:att:research:xacml:test:ldap
+ldap1.resolver.dn.filter.view=dn
+ldap1.resolver.dn.filter.view.dn.id=com:att:research:xacml:test:ldap:subject:dn
+ldap1.resolver.dn.filter.view.dn.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.dn.filter.view.dn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+ldap1.resolver.dn.filter.view.dn.issuer=com:att:research:xacml:test:ldap
+
+ldap1.resolver.ship.classname=com.att.research.xacml.std.pip.engines.ldap.ConfigurableLDAPResolver
+ldap1.resolver.ship.name=Ship Resolver
+ldap1.resolver.ship.description=This resolves a subject's dn to a ship.
+ldap1.resolver.ship.base=o=sevenseas
+ldap1.resolver.ship.base.parameters=
+ldap1.resolver.ship.filter=uniquemember=${dn}
+ldap1.resolver.ship.filter.parameters=dn
+ldap1.resolver.ship.filter.parameters.dn.id=com:att:research:xacml:test:ldap:subject:dn
+ldap1.resolver.ship.filter.parameters.dn.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.ship.filter.parameters.dn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+ldap1.resolver.ship.filter.parameters.dn.issuer=com:att:research:xacml:test:ldap
+ldap1.resolver.ship.filter.view=cn
+ldap1.resolver.ship.filter.view.cn.id=com:att:research:xacml:test:ldap:subject:ship
+ldap1.resolver.ship.filter.view.cn.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.ship.filter.view.cn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+ldap1.resolver.ship.filter.view.cn.issuer=com:att:research:xacml:test:ldap
+
diff --git a/openaz-xacml-pap-rest/pdps/configurable-csv-hyper/xacml.policy.properties b/openaz-xacml-pap-rest/pdps/configurable-csv-hyper/xacml.policy.properties
new file mode 100755
index 0000000..273f36d
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/configurable-csv-hyper/xacml.policy.properties
@@ -0,0 +1,6 @@
+xacml.rootPolicies=CSV-Legal-Age-Marriage-v1.xml
+xacml.referencedPolicies=
+
+
+CSV-Legal-Age-Marriage-v1.xml.url=http://localhost:9090/pap/?id=CSV-Legal-Age-Marriage-v1.xml
+
diff --git a/openaz-xacml-pap-rest/pdps/configurable-csv/CSV-Baseball-Hall-Of-Fame-v1.xml b/openaz-xacml-pap-rest/pdps/configurable-csv/CSV-Baseball-Hall-Of-Fame-v1.xml
new file mode 100755
index 0000000..68c7783
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/configurable-csv/CSV-Baseball-Hall-Of-Fame-v1.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<PolicySet xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicySetId="urn:com:att:xacml:policy:id:f3047eab-6f97-49b4-8127-a2737a184b35" Version="1" PolicyCombiningAlgId="urn:oasis:names:tc:xacml:3.0:policy-combining-algorithm:deny-overrides">
+    <Description>This policy enforces the BBWAA rules for baseball Hall of Fame induction.
+
+http://baseballhall.org/hall-famers/rules-election/bbwaa
+</Description>
+    <Target>
+        <AnyOf>
+            <AllOf>
+                <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">eligible</AttributeValue>
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+                </Match>
+                <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">HOF</AttributeValue>
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+                </Match>
+            </AllOf>
+        </AnyOf>
+    </Target>
+    <Policy PolicyId="urn:com:att:xacml:policy:id:8f295c67-7b6e-4db6-b558-005b36abd970" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">
+        <Description>Active Timeframe:
+
+A. A baseball player must have been active as a player in the Major Leagues at some time during a period beginning twenty (20) years before and ending five (5) years prior to election.</Description>
+        <Target/>
+        <Rule RuleId="urn:com:att:xacml:rule:id:f04b2700-1236-4066-81e4-e341b5b2f3b5" Effect="Permit">
+            <Description>Player's debut date &gt;= (today's date - 20 years) AND final date &lt;= (today's date - 5 years).</Description>
+            <Target/>
+            <Condition>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
+                    <Description>debut within 20 years AND final game more than 5 years ago.</Description>
+                    <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-less-than-or-equal">
+                        <Description>Debut date &lt;= (today's date - 20 years)</Description>
+                        <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-one-and-only">
+                            <Description>UN-bag player's debut date.</Description>
+                            <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:debut" DataType="http://www.w3.org/2001/XMLSchema#date" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/>
+                        </Apply>
+                        <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:date-subtract-yearMonthDuration">
+                            <Description>Subtract 20 years from  today's date.</Description>
+                            <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-one-and-only">
+<Description>UN-bag today's date.</Description>
+<AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:environment" AttributeId="urn:oasis:names:tc:xacml:1.0:environment:current-date" DataType="http://www.w3.org/2001/XMLSchema#date" MustBePresent="false"/>
+                            </Apply>
+                            <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#yearMonthDuration">P20Y</AttributeValue>
+                        </Apply>
+                    </Apply>
+                    <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-less-than-or-equal">
+                        <Description>Final Game &lt;= (today's date - 5 years)</Description>
+                        <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-one-and-only">
+                            <Description>UN-bag final game date</Description>
+                            <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:finalgame" DataType="http://www.w3.org/2001/XMLSchema#date" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/>
+                        </Apply>
+                        <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:date-subtract-yearMonthDuration">
+                            <Description>Subtract 5 years from today's date.</Description>
+                            <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-one-and-only">
+<Description>UN-bag today's date.</Description>
+<AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:environment" AttributeId="urn:oasis:names:tc:xacml:1.0:environment:current-date" DataType="http://www.w3.org/2001/XMLSchema#date" MustBePresent="false"/>
+                            </Apply>
+                            <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#yearMonthDuration">P5Y</AttributeValue>
+                        </Apply>
+                    </Apply>
+                </Apply>
+            </Condition>
+        </Rule>
+        <Rule RuleId="urn:com:att:xacml:rule:id:33a42a79-9d82-4aa1-99d3-9fd168363695" Effect="Deny">
+            <Description>DENY - Default</Description>
+            <Target/>
+        </Rule>
+    </Policy>
+    <Policy PolicyId="urn:com:att:xacml:policy:id:1bf74cc4-658f-4e87-be22-5d5cb741f1f5" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">
+        <Description>B. Player must have played in each of ten (10) Major League championship seasons, some part of which must have been within the period described in 3 (A).</Description>
+        <Target/>
+        <Rule RuleId="urn:com:att:xacml:rule:id:54405c39-a3f6-4a88-89bd-084f68567acd" Effect="Permit">
+            <Description>There should be &gt;= 10 years of appearance(s) values.</Description>
+            <Target/>
+            <Condition>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal">
+                    <Description>The number of years a player appeared.</Description>
+                    <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-bag-size">
+                        <Description>Count the number.</Description>
+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:appearance" DataType="http://www.w3.org/2001/XMLSchema#integer" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/>
+                    </Apply>
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">10</AttributeValue>
+                </Apply>
+            </Condition>
+        </Rule>
+        <Rule RuleId="urn:com:att:xacml:rule:id:912dd1a2-1527-4b6f-a95b-6a729ff9caab" Effect="Deny">
+            <Description>DENY - Default</Description>
+            <Target/>
+        </Rule>
+    </Policy>
+</PolicySet>
diff --git a/openaz-xacml-pap-rest/pdps/configurable-csv/xacml.pip.properties b/openaz-xacml-pap-rest/pdps/configurable-csv/xacml.pip.properties
new file mode 100755
index 0000000..ebd0904
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/configurable-csv/xacml.pip.properties
@@ -0,0 +1,227 @@
+# PIP Engine Definition
+#
+xacml.pip.engines=csv1,csv2
+
+ATTWebPhone.classname=com.att.research.xacmlatt.pip.webphone.PIPEngineATTWebphone
+CSO.classname=com.att.research.xacmlatt.pip.cso.PIPEngineCSOCookie
+CSO.mode=DEVL
+
+csv1.classname=com.att.research.xacml.std.pip.engines.csv.CSVEngine
+csv1.name=Master
+csv1.description=Sean Lahman Basebase stats - Player names, DOB, and biographical info
+csv1.issuer=com:att:research:xacml:test:csv
+csv1.source=../XACML-TEST/testsets/pip/configurable-csv/adminDB/Master.txt
+csv1.maxsize=500000
+csv1.delimiter=,
+csv1.quote="
+csv1.skip=0
+
+csv1.resolvers=data
+
+csv1.resolver.data.classname=com.att.research.xacml.std.pip.engines.csv.ConfigurableCSVResolver
+csv1.resolver.data.name=Player Resolver
+csv1.resolver.data.description=This resolver finds player information in the Master table.
+csv1.resolver.data.fields=firstname,lastname,deathyear,deathmonth,deathday,debut,finalgame
+csv1.resolver.data.field.firstname.column=16
+csv1.resolver.data.field.firstname.id=com:att:research:xacml:test:csv:subject:firstname
+csv1.resolver.data.field.firstname.datatype=http://www.w3.org/2001/XMLSchema#string
+csv1.resolver.data.field.firstname.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.lastname.column=17
+csv1.resolver.data.field.lastname.id=com:att:research:xacml:test:csv:subject:lastname
+csv1.resolver.data.field.lastname.datatype=http://www.w3.org/2001/XMLSchema#string
+csv1.resolver.data.field.lastname.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.deathyear.column=10
+csv1.resolver.data.field.deathyear.id=com:att:research:xacml:test:csv:subject:deathyear
+csv1.resolver.data.field.deathyear.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv1.resolver.data.field.deathyear.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.deathmonth.column=11
+csv1.resolver.data.field.deathmonth.id=com:att:research:xacml:test:csv:subject:deathmonth
+csv1.resolver.data.field.deathmonth.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv1.resolver.data.field.deathmonth.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.deathday.column=12
+csv1.resolver.data.field.deathday.id=com:att:research:xacml:test:csv:subject:deathday
+csv1.resolver.data.field.deathday.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv1.resolver.data.field.deathday.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.debut.column=25
+csv1.resolver.data.field.debut.id=com:att:research:xacml:test:csv:subject:debut
+csv1.resolver.data.field.debut.datatype=http://www.w3.org/2001/XMLSchema#date
+csv1.resolver.data.field.debut.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.finalgame.column=26
+csv1.resolver.data.field.finalgame.id=com:att:research:xacml:test:csv:subject:finalgame
+csv1.resolver.data.field.finalgame.datatype=http://www.w3.org/2001/XMLSchema#date
+csv1.resolver.data.field.finalgame.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.parameters=playerid
+csv1.resolver.data.parameter.playerid.column=1
+csv1.resolver.data.parameter.playerid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id
+csv1.resolver.data.parameter.playerid.datatype=http://www.w3.org/2001/XMLSchema#string
+csv1.resolver.data.parameter.playerid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv2.classname=com.att.research.xacml.std.pip.engines.csv.CSVEngine
+csv2.name=Appearances
+csv2.description=Sean Lahman Basebase stats - Player appearances for a team in a given year.
+#csv2.issuer=
+csv2.source=../XACML-TEST/testsets/pip/configurable-csv/adminDB/Appearances.txt
+csv2.maxsize=500000
+csv2.delimiter=,
+csv2.quote="
+csv2.skip=0
+
+csv2.resolvers=data
+
+csv2.resolver.data.classname=com.att.research.xacml.std.pip.engines.csv.ConfigurableCSVResolver
+csv2.resolver.data.name=Appearance Resolver
+csv2.resolver.data.description=This resolver returns all the appearances for a player from the appearance table.
+csv2.resolver.data.fields=appearance
+csv2.resolver.data.field.appearance.column=0
+csv2.resolver.data.field.appearance.id=com:att:research:xacml:test:csv:subject:appearance
+csv2.resolver.data.field.appearance.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv2.resolver.data.field.appearance.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+csv2.resolver.data.field.appearance.issuer=com:att:research:xacml:test:csv
+
+csv2.resolver.data.parameters=playerid
+csv2.resolver.data.parameter.playerid.column=3
+csv2.resolver.data.parameter.playerid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id
+csv2.resolver.data.parameter.playerid.datatype=http://www.w3.org/2001/XMLSchema#string
+csv2.resolver.data.parameter.playerid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+#csv1.resolver.data.parameter.playerid.issuer=
+
+hyper1.classname=com.att.research.xacml.std.pip.engines.csv.HyperCSVEngine
+hyper1.name=World Marriage Age Limits
+hyper1.description=Minimum age for female/male marriages with or without their parental consent.
+hyper1.source=../XACML-TEST/testsets/pip/configurable-csv-hyper/marriage.csv
+hyper1.target=marriage
+hyper1.definition=country VARCHAR(80) PRIMARY KEY, wofemale INT, womale INT, wfemale INT, wmale INT, year INT, source VARCHAR(20)
+
+hyper1.resolvers=age_consent
+
+hyper1.resolver.age_consent.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver
+hyper1.resolver.age_consent.name=Ages
+hyper1.resolver.age_consent.description=This returns all the age's for consent or no consent for a country.
+hyper1.resolver.age_consent.select=SELECT wofemale,womale,wfemale,wmale FROM marriage WHERE country=?
+hyper1.resolver.age_consent.fields=wofemale,womale,wfemale,wmale
+
+hyper1.resolver.age_consent.field.wofemale.id=com:att:research:xacml:test:csv:country:no-consent:female
+hyper1.resolver.age_consent.field.wofemale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.wofemale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.wofemale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.field.womale.id=com:att:research:xacml:test:csv:country:no-consent:male
+hyper1.resolver.age_consent.field.womale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.womale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.womale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.field.wfemale.id=com:att:research:xacml:test:csv:country:consent:female
+hyper1.resolver.age_consent.field.wfemale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.wfemale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.wfemale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.field.wmale.id=com:att:research:xacml:test:csv:country:consent:male
+hyper1.resolver.age_consent.field.wmale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.wmale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.wmale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.parameters=country
+hyper1.resolver.age_consent.parameter.country.id=com:att:research:xacml:test:csv:country:name
+hyper1.resolver.age_consent.parameter.country.datatype=http://www.w3.org/2001/XMLSchema#string
+hyper1.resolver.age_consent.parameter.country.category=com:att:research:xacml:test:csv:category:country
+#hyper1.resolver.age_consent.parameter.country.issuer=
+
+sql1.classname=com.att.research.xacml.std.pip.engines.jdbc.JDBCEngine
+sql1.name=World
+sql1.description=World Database from MySQL website. Copyright Statistics Finland, http://www.stat.fi/worldinfigures.
+# This will be the default issuer for the resolvers. NOTE: Issuer only used for attributes provided by the engine.
+sql1.issuer=com:att:research:xacml:test:sql
+#
+# This is the configuration for JDBC. You will have to setup the database and run the data\world*.sql script to
+# create the tables and load the data. 
+#
+sql1.type=jdbc
+sql1.jdbc.driver=org.postgresql.Driver
+#sql1.jdbc.url=jdbc:postgresql://localhost:5432/world
+#sql1.jdbc.conn.user=sa
+#sql1.jdbc.conn.password=
+sql1.jdbc.url=jdbc:postgresql://xacml-pip.research.att.com:5432/world
+sql1.jdbc.conn.user=pip
+sql1.jdbc.conn.password=p1pUs3r
+#
+# This is the configuration for JNDI datasource.
+#
+#sql1.type=jndi
+#sql1.datasource=jdbc/xacml
+
+sql1.resolvers=langer
+
+sql1.resolver.langer.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver
+sql1.resolver.langer.name=Language
+sql1.resolver.langer.description=This returns the language for a city.
+sql1.resolver.langer.select=SELECT language FROM city INNER JOIN countrylanguage ON city.countrycode = countrylanguage.countrycode WHERE name=?
+sql1.resolver.langer.fields=language
+sql1.resolver.langer.field.language.id=com:att:research:xacml:test:sql:resource:city:language
+sql1.resolver.langer.field.language.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.langer.field.language.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+#You can override the default issuer that is set in the JDBCEngine definition if you want.
+#sql1.resolver.langer.field.language.issuer=com:att:research:xacml:test:sql
+sql1.resolver.langer.parameters=name
+sql1.resolver.langer.parameter.name.id=urn:oasis:names:tc:xacml:1.0:resource:resource-id
+sql1.resolver.langer.parameter.name.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.langer.parameter.name.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+
+
+ldap1.classname=com.att.research.xacml.std.pip.engines.ldap.LDAPEngine
+ldap1.name=LDAP PIP
+ldap1.description=The LDAP containing the seven seas sample LDIF data.
+ldap1.issuer=com:att:research:xacml:test:ldap
+ldap1.java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory
+#
+# NOTE: You will have to setup a local LDAP server and load the data\apache-ds-tutorial.ldif before
+# this example will work.
+#
+#ldap1.java.naming.provider.url=ldap://localhost:10389
+ldap1.java.naming.provider.url=ldap://xacml-pip.research.att.com:10389
+#ldap.java.naming.security.principal=
+#ldap.java.naming.security.credentials=
+ldap1.scope=subtree
+
+ldap1.resolvers=dn,ship
+
+ldap1.resolver.dn.classname=com.att.research.xacml.std.pip.engines.ldap.ConfigurableLDAPResolver
+ldap1.resolver.dn.name=Domain Names
+ldap1.resolver.dn.description=Find all the dn's for the subject id
+ldap1.resolver.dn.base=o=sevenseas
+ldap1.resolver.dn.base.parameters=
+ldap1.resolver.dn.filter=(|(uid=${uid})(mail=${uid}))
+ldap1.resolver.dn.filter.parameters=uid
+ldap1.resolver.dn.filter.parameters.uid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id
+ldap1.resolver.dn.filter.parameters.uid.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.dn.filter.parameters.uid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+#ldap1.resolver.dn.filter.parameters.uid.issuer=com:att:research:xacml:test:ldap
+ldap1.resolver.dn.filter.view=dn
+ldap1.resolver.dn.filter.view.dn.id=com:att:research:xacml:test:ldap:subject:dn
+ldap1.resolver.dn.filter.view.dn.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.dn.filter.view.dn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+ldap1.resolver.dn.filter.view.dn.issuer=com:att:research:xacml:test:ldap
+
+ldap1.resolver.ship.classname=com.att.research.xacml.std.pip.engines.ldap.ConfigurableLDAPResolver
+ldap1.resolver.ship.name=Ship Resolver
+ldap1.resolver.ship.description=This resolves a subject's dn to a ship.
+ldap1.resolver.ship.base=o=sevenseas
+ldap1.resolver.ship.base.parameters=
+ldap1.resolver.ship.filter=uniquemember=${dn}
+ldap1.resolver.ship.filter.parameters=dn
+ldap1.resolver.ship.filter.parameters.dn.id=com:att:research:xacml:test:ldap:subject:dn
+ldap1.resolver.ship.filter.parameters.dn.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.ship.filter.parameters.dn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+ldap1.resolver.ship.filter.parameters.dn.issuer=com:att:research:xacml:test:ldap
+ldap1.resolver.ship.filter.view=cn
+ldap1.resolver.ship.filter.view.cn.id=com:att:research:xacml:test:ldap:subject:ship
+ldap1.resolver.ship.filter.view.cn.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.ship.filter.view.cn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+ldap1.resolver.ship.filter.view.cn.issuer=com:att:research:xacml:test:ldap
+
diff --git a/openaz-xacml-pap-rest/pdps/configurable-csv/xacml.policy.properties b/openaz-xacml-pap-rest/pdps/configurable-csv/xacml.policy.properties
new file mode 100755
index 0000000..59a8dd7
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/configurable-csv/xacml.policy.properties
@@ -0,0 +1,6 @@
+xacml.rootPolicies=CSV-Baseball-Hall-Of-Fame-v1.xml
+xacml.referencedPolicies=
+
+
+CSV-Baseball-Hall-Of-Fame-v1.xml.url=http://localhost:9090/pap/?id=CSV-Baseball-Hall-Of-Fame-v1.xml
+
diff --git a/openaz-xacml-pap-rest/pdps/configurable-ldap/LDAP-Seven-Seas-v1.xml b/openaz-xacml-pap-rest/pdps/configurable-ldap/LDAP-Seven-Seas-v1.xml
new file mode 100755
index 0000000..9e36f68
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/configurable-ldap/LDAP-Seven-Seas-v1.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="urn:com:att:xacml:policy:id:94378f81-6810-408f-a072-a1a8a7585a24" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">
+	<Description>Sample policy that demonstrates use of Configurable LDAP Resolver with sample data.
+
+The PEP Request should provide the following attributes:
+action-id=board
+subject-id-qualifer=uid|mail
+subject-id=hnelson|hnelson@royalnavy.mod.uk
+resource-id=HMS Lydia|HMS Victory|HMS Bounty
+	</Description>
+        <Target>
+            <AnyOf>
+                <AllOf>
+                    <Match MatchId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case">
+                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">board</AttributeValue>
+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+                    </Match>
+                </AllOf>
+            </AnyOf>
+        </Target>
+        <Rule RuleId="urn:com:att:xacml:rule:id:bf241671-54de-404c-ac59-bb17b919783f" Effect="Permit">
+            <Description>This sailor is a member of the crew for the ship.</Description>
+            <Target/>
+            <Condition>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+                    <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:ldap:subject:ship" DataType="http://www.w3.org/2001/XMLSchema#string" Issuer="com:att:research:xacml:test:ldap" MustBePresent="false"/>
+                    </Apply>
+                    <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+                    </Apply>
+                </Apply>
+            </Condition>
+        </Rule>
+        <Rule RuleId="urn:com:att:xacml:rule:id:490228ea-98ee-48d8-84c9-da07334726fd" Effect="Deny">
+            <Description>Default is to DENY.</Description>
+            <Target/>
+        </Rule>
+</Policy>
diff --git a/openaz-xacml-pap-rest/pdps/configurable-ldap/xacml.pip.properties b/openaz-xacml-pap-rest/pdps/configurable-ldap/xacml.pip.properties
new file mode 100755
index 0000000..deb58b4
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/configurable-ldap/xacml.pip.properties
@@ -0,0 +1,227 @@
+# PIP Engine Definition
+#
+xacml.pip.engines=ldap1
+
+ATTWebPhone.classname=com.att.research.xacmlatt.pip.webphone.PIPEngineATTWebphone
+CSO.classname=com.att.research.xacmlatt.pip.cso.PIPEngineCSOCookie
+CSO.mode=DEVL
+
+csv1.classname=com.att.research.xacml.std.pip.engines.csv.CSVEngine
+csv1.name=Master
+csv1.description=Sean Lahman Basebase stats - Player names, DOB, and biographical info
+csv1.issuer=com:att:research:xacml:test:csv
+csv1.source=../XACML-TEST/testsets/pip/configurable-csv/adminDB/Master.txt
+csv1.maxsize=4000000
+csv1.delimiter=,
+csv1.quote="
+csv1.skip=0
+
+csv1.resolvers=data
+
+csv1.resolver.data.classname=com.att.research.xacml.std.pip.engines.csv.ConfigurableCSVResolver
+csv1.resolver.data.name=Player Resolver
+csv1.resolver.data.description=This resolver finds player information in the Master table.
+csv1.resolver.data.fields=firstname,lastname,deathyear,deathmonth,deathday,debut,finalgame
+csv1.resolver.data.field.firstname.column=16
+csv1.resolver.data.field.firstname.id=com:att:research:xacml:test:csv:subject:firstname
+csv1.resolver.data.field.firstname.datatype=http://www.w3.org/2001/XMLSchema#string
+csv1.resolver.data.field.firstname.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.lastname.column=17
+csv1.resolver.data.field.lastname.id=com:att:research:xacml:test:csv:subject:lastname
+csv1.resolver.data.field.lastname.datatype=http://www.w3.org/2001/XMLSchema#string
+csv1.resolver.data.field.lastname.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.deathyear.column=10
+csv1.resolver.data.field.deathyear.id=com:att:research:xacml:test:csv:subject:deathyear
+csv1.resolver.data.field.deathyear.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv1.resolver.data.field.deathyear.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.deathmonth.column=11
+csv1.resolver.data.field.deathmonth.id=com:att:research:xacml:test:csv:subject:deathmonth
+csv1.resolver.data.field.deathmonth.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv1.resolver.data.field.deathmonth.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.deathday.column=12
+csv1.resolver.data.field.deathday.id=com:att:research:xacml:test:csv:subject:deathday
+csv1.resolver.data.field.deathday.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv1.resolver.data.field.deathday.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.debut.column=25
+csv1.resolver.data.field.debut.id=com:att:research:xacml:test:csv:subject:debut
+csv1.resolver.data.field.debut.datatype=http://www.w3.org/2001/XMLSchema#date
+csv1.resolver.data.field.debut.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.finalgame.column=26
+csv1.resolver.data.field.finalgame.id=com:att:research:xacml:test:csv:subject:finalgame
+csv1.resolver.data.field.finalgame.datatype=http://www.w3.org/2001/XMLSchema#date
+csv1.resolver.data.field.finalgame.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.parameters=playerid
+csv1.resolver.data.parameter.playerid.column=1
+csv1.resolver.data.parameter.playerid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id
+csv1.resolver.data.parameter.playerid.datatype=http://www.w3.org/2001/XMLSchema#string
+csv1.resolver.data.parameter.playerid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv2.classname=com.att.research.xacml.std.pip.engines.csv.CSVEngine
+csv2.name=Appearances
+csv2.description=Sean Lahman Basebase stats - Player appearances for a team in a given year.
+#csv2.issuer=
+csv2.source=../XACML-TEST/testsets/pip/configurable-csv/adminDB/Appearances.txt
+csv2.maxsize=4000000
+csv2.delimiter=,
+csv2.quote="
+csv2.skip=0
+
+csv2.resolvers=data
+
+csv2.resolver.data.classname=com.att.research.xacml.std.pip.engines.csv.ConfigurableCSVResolver
+csv2.resolver.data.name=Appearance Resolver
+csv2.resolver.data.description=This resolver returns all the appearances for a player from the appearance table.
+csv2.resolver.data.fields=appearance
+csv2.resolver.data.field.appearance.column=0
+csv2.resolver.data.field.appearance.id=com:att:research:xacml:test:csv:subject:appearance
+csv2.resolver.data.field.appearance.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv2.resolver.data.field.appearance.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+csv2.resolver.data.field.appearance.issuer=com:att:research:xacml:test:csv
+
+csv2.resolver.data.parameters=playerid
+csv2.resolver.data.parameter.playerid.column=3
+csv2.resolver.data.parameter.playerid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id
+csv2.resolver.data.parameter.playerid.datatype=http://www.w3.org/2001/XMLSchema#string
+csv2.resolver.data.parameter.playerid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+#csv1.resolver.data.parameter.playerid.issuer=
+
+hyper1.classname=com.att.research.xacml.std.pip.engines.csv.HyperCSVEngine
+hyper1.name=World Marriage Age Limits
+hyper1.description=Minimum age for female/male marriages with or without their parental consent.
+hyper1.source=../XACML-TEST/testsets/pip/configurable-csv-hyper/marriage.csv
+hyper1.target=marriage
+hyper1.definition=country VARCHAR(80) PRIMARY KEY, wofemale INT, womale INT, wfemale INT, wmale INT, year INT, source VARCHAR(20)
+
+hyper1.resolvers=age_consent
+
+hyper1.resolver.age_consent.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver
+hyper1.resolver.age_consent.name=Ages
+hyper1.resolver.age_consent.description=This returns all the age's for consent or no consent for a country.
+hyper1.resolver.age_consent.select=SELECT wofemale,womale,wfemale,wmale FROM marriage WHERE country=?
+hyper1.resolver.age_consent.fields=wofemale,womale,wfemale,wmale
+
+hyper1.resolver.age_consent.field.wofemale.id=com:att:research:xacml:test:csv:country:no-consent:female
+hyper1.resolver.age_consent.field.wofemale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.wofemale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.wofemale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.field.womale.id=com:att:research:xacml:test:csv:country:no-consent:male
+hyper1.resolver.age_consent.field.womale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.womale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.womale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.field.wfemale.id=com:att:research:xacml:test:csv:country:consent:female
+hyper1.resolver.age_consent.field.wfemale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.wfemale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.wfemale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.field.wmale.id=com:att:research:xacml:test:csv:country:consent:male
+hyper1.resolver.age_consent.field.wmale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.wmale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.wmale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.parameters=country
+hyper1.resolver.age_consent.parameter.country.id=com:att:research:xacml:test:csv:country:name
+hyper1.resolver.age_consent.parameter.country.datatype=http://www.w3.org/2001/XMLSchema#string
+hyper1.resolver.age_consent.parameter.country.category=com:att:research:xacml:test:csv:category:country
+#hyper1.resolver.age_consent.parameter.country.issuer=
+
+sql1.classname=com.att.research.xacml.std.pip.engines.jdbc.JDBCEngine
+sql1.name=World
+sql1.description=World Database from MySQL website. Copyright Statistics Finland, http://www.stat.fi/worldinfigures.
+# This will be the default issuer for the resolvers. NOTE: Issuer only used for attributes provided by the engine.
+sql1.issuer=com:att:research:xacml:test:sql
+#
+# This is the configuration for JDBC. You will have to setup the database and run the data\world*.sql script to
+# create the tables and load the data. 
+#
+sql1.type=jdbc
+sql1.jdbc.driver=org.postgresql.Driver
+#sql1.jdbc.url=jdbc:postgresql://localhost:5432/world
+#sql1.jdbc.conn.user=sa
+#sql1.jdbc.conn.password=
+sql1.jdbc.url=jdbc:postgresql://xacml-pip.research.att.com:5432/world
+sql1.jdbc.conn.user=pip
+sql1.jdbc.conn.password=p1pUs3r
+#
+# This is the configuration for JNDI datasource.
+#
+#sql1.type=jndi
+#sql1.datasource=jdbc/xacml
+
+sql1.resolvers=langer
+
+sql1.resolver.langer.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver
+sql1.resolver.langer.name=Language
+sql1.resolver.langer.description=This returns the language for a city.
+sql1.resolver.langer.select=SELECT language FROM city INNER JOIN countrylanguage ON city.countrycode = countrylanguage.countrycode WHERE name=?
+sql1.resolver.langer.fields=language
+sql1.resolver.langer.field.language.id=com:att:research:xacml:test:sql:resource:city:language
+sql1.resolver.langer.field.language.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.langer.field.language.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+#You can override the default issuer that is set in the JDBCEngine definition if you want.
+#sql1.resolver.langer.field.language.issuer=com:att:research:xacml:test:sql
+sql1.resolver.langer.parameters=name
+sql1.resolver.langer.parameter.name.id=urn:oasis:names:tc:xacml:1.0:resource:resource-id
+sql1.resolver.langer.parameter.name.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.langer.parameter.name.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+
+
+ldap1.classname=com.att.research.xacml.std.pip.engines.ldap.LDAPEngine
+ldap1.name=LDAP PIP
+ldap1.description=The LDAP containing the seven seas sample LDIF data.
+ldap1.issuer=com:att:research:xacml:test:ldap
+ldap1.java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory
+#
+# NOTE: You will have to setup a local LDAP server and load the data\apache-ds-tutorial.ldif before
+# this example will work.
+#
+#ldap1.java.naming.provider.url=ldap://localhost:10389
+ldap1.java.naming.provider.url=ldap://xacml-pip.research.att.com:10389
+#ldap.java.naming.security.principal=
+#ldap.java.naming.security.credentials=
+ldap1.scope=subtree
+
+ldap1.resolvers=dn,ship
+
+ldap1.resolver.dn.classname=com.att.research.xacml.std.pip.engines.ldap.ConfigurableLDAPResolver
+ldap1.resolver.dn.name=Domain Names
+ldap1.resolver.dn.description=Find all the dn's for the subject id
+ldap1.resolver.dn.base=o=sevenseas
+ldap1.resolver.dn.base.parameters=
+ldap1.resolver.dn.filter=(|(uid=${uid})(mail=${uid}))
+ldap1.resolver.dn.filter.parameters=uid
+ldap1.resolver.dn.filter.parameters.uid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id
+ldap1.resolver.dn.filter.parameters.uid.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.dn.filter.parameters.uid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+#ldap1.resolver.dn.filter.parameters.uid.issuer=com:att:research:xacml:test:ldap
+ldap1.resolver.dn.filter.view=dn
+ldap1.resolver.dn.filter.view.dn.id=com:att:research:xacml:test:ldap:subject:dn
+ldap1.resolver.dn.filter.view.dn.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.dn.filter.view.dn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+ldap1.resolver.dn.filter.view.dn.issuer=com:att:research:xacml:test:ldap
+
+ldap1.resolver.ship.classname=com.att.research.xacml.std.pip.engines.ldap.ConfigurableLDAPResolver
+ldap1.resolver.ship.name=Ship Resolver
+ldap1.resolver.ship.description=This resolves a subject's dn to a ship.
+ldap1.resolver.ship.base=o=sevenseas
+ldap1.resolver.ship.base.parameters=
+ldap1.resolver.ship.filter=uniquemember=${dn}
+ldap1.resolver.ship.filter.parameters=dn
+ldap1.resolver.ship.filter.parameters.dn.id=com:att:research:xacml:test:ldap:subject:dn
+ldap1.resolver.ship.filter.parameters.dn.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.ship.filter.parameters.dn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+ldap1.resolver.ship.filter.parameters.dn.issuer=com:att:research:xacml:test:ldap
+ldap1.resolver.ship.filter.view=cn
+ldap1.resolver.ship.filter.view.cn.id=com:att:research:xacml:test:ldap:subject:ship
+ldap1.resolver.ship.filter.view.cn.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.ship.filter.view.cn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+ldap1.resolver.ship.filter.view.cn.issuer=com:att:research:xacml:test:ldap
+
diff --git a/openaz-xacml-pap-rest/pdps/configurable-ldap/xacml.policy.properties b/openaz-xacml-pap-rest/pdps/configurable-ldap/xacml.policy.properties
new file mode 100755
index 0000000..df57627
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/configurable-ldap/xacml.policy.properties
@@ -0,0 +1,5 @@
+xacml.rootPolicies=LDAP-Seven-Seas-v1.xml
+xacml.referencedPolicies=
+
+
+LDAP-Seven-Seas-v1.xml.url=http://localhost:9090/pap/?id=LDAP-Seven-Seas-v1.xml
diff --git a/openaz-xacml-pap-rest/pdps/configurable-sql/SQL-World-Languages-v1.xml b/openaz-xacml-pap-rest/pdps/configurable-sql/SQL-World-Languages-v1.xml
new file mode 100755
index 0000000..85443dc
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/configurable-sql/SQL-World-Languages-v1.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="urn:com:att:xacml:policy:id:25e12b06-11d5-4895-b2a2-6f6c594de069" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">
+        <Description>Policy for speaking a language in a city.</Description>
+        <Target>
+            <AnyOf>
+                <AllOf>
+                    <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">speak</AttributeValue>
+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+                    </Match>
+                </AllOf>
+            </AnyOf>
+        </Target>
+        <Rule RuleId="urn:com:att:xacml:rule:id:e1e8c5c0-e2ba-47d5-9289-6c015305ed21" Effect="Permit">
+            <Description>PERMIT - People in this city speak my language.</Description>
+            <Target/>
+            <Condition>
+                <VariableReference VariableId="cityLanguage"/>
+            </Condition>
+        </Rule>
+        <VariableDefinition VariableId="cityLanguage">
+            <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-is-in">
+                <Description>The city's language must match exactly the subject's language.</Description>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+                </Apply>
+                <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:sql:resource:city:language" DataType="http://www.w3.org/2001/XMLSchema#string" Issuer="com:att:research:xacml:test:sql" MustBePresent="false"/>
+            </Apply>
+        </VariableDefinition>
+        <Rule RuleId="urn:com:att:xacml:rule:id:c9a3fb7d-d0b9-48bb-bdca-87eb4957120c" Effect="Deny">
+            <Description>DENY - default.</Description>
+            <Target/>
+        </Rule>
+</Policy>
diff --git a/openaz-xacml-pap-rest/pdps/configurable-sql/xacml.pip.properties b/openaz-xacml-pap-rest/pdps/configurable-sql/xacml.pip.properties
new file mode 100755
index 0000000..dcfd4c8
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/configurable-sql/xacml.pip.properties
@@ -0,0 +1,227 @@
+# PIP Engine Definition
+#
+xacml.pip.engines=sql1
+
+ATTWebPhone.classname=com.att.research.xacmlatt.pip.webphone.PIPEngineATTWebphone
+CSO.classname=com.att.research.xacmlatt.pip.cso.PIPEngineCSOCookie
+CSO.mode=DEVL
+
+csv1.classname=com.att.research.xacml.std.pip.engines.csv.CSVEngine
+csv1.name=Master
+csv1.description=Sean Lahman Basebase stats - Player names, DOB, and biographical info
+csv1.issuer=com:att:research:xacml:test:csv
+csv1.source=../XACML-TEST/testsets/pip/configurable-csv/adminDB/Master.txt
+csv1.maxsize=4000000
+csv1.delimiter=,
+csv1.quote="
+csv1.skip=0
+
+csv1.resolvers=data
+
+csv1.resolver.data.classname=com.att.research.xacml.std.pip.engines.csv.ConfigurableCSVResolver
+csv1.resolver.data.name=Player Resolver
+csv1.resolver.data.description=This resolver finds player information in the Master table.
+csv1.resolver.data.fields=firstname,lastname,deathyear,deathmonth,deathday,debut,finalgame
+csv1.resolver.data.field.firstname.column=16
+csv1.resolver.data.field.firstname.id=com:att:research:xacml:test:csv:subject:firstname
+csv1.resolver.data.field.firstname.datatype=http://www.w3.org/2001/XMLSchema#string
+csv1.resolver.data.field.firstname.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.lastname.column=17
+csv1.resolver.data.field.lastname.id=com:att:research:xacml:test:csv:subject:lastname
+csv1.resolver.data.field.lastname.datatype=http://www.w3.org/2001/XMLSchema#string
+csv1.resolver.data.field.lastname.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.deathyear.column=10
+csv1.resolver.data.field.deathyear.id=com:att:research:xacml:test:csv:subject:deathyear
+csv1.resolver.data.field.deathyear.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv1.resolver.data.field.deathyear.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.deathmonth.column=11
+csv1.resolver.data.field.deathmonth.id=com:att:research:xacml:test:csv:subject:deathmonth
+csv1.resolver.data.field.deathmonth.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv1.resolver.data.field.deathmonth.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.deathday.column=12
+csv1.resolver.data.field.deathday.id=com:att:research:xacml:test:csv:subject:deathday
+csv1.resolver.data.field.deathday.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv1.resolver.data.field.deathday.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.debut.column=25
+csv1.resolver.data.field.debut.id=com:att:research:xacml:test:csv:subject:debut
+csv1.resolver.data.field.debut.datatype=http://www.w3.org/2001/XMLSchema#date
+csv1.resolver.data.field.debut.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.finalgame.column=26
+csv1.resolver.data.field.finalgame.id=com:att:research:xacml:test:csv:subject:finalgame
+csv1.resolver.data.field.finalgame.datatype=http://www.w3.org/2001/XMLSchema#date
+csv1.resolver.data.field.finalgame.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.parameters=playerid
+csv1.resolver.data.parameter.playerid.column=1
+csv1.resolver.data.parameter.playerid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id
+csv1.resolver.data.parameter.playerid.datatype=http://www.w3.org/2001/XMLSchema#string
+csv1.resolver.data.parameter.playerid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv2.classname=com.att.research.xacml.std.pip.engines.csv.CSVEngine
+csv2.name=Appearances
+csv2.description=Sean Lahman Basebase stats - Player appearances for a team in a given year.
+#csv2.issuer=
+csv2.source=../XACML-TEST/testsets/pip/configurable-csv/adminDB/Appearances.txt
+csv2.maxsize=4000000
+csv2.delimiter=,
+csv2.quote="
+csv2.skip=0
+
+csv2.resolvers=data
+
+csv2.resolver.data.classname=com.att.research.xacml.std.pip.engines.csv.ConfigurableCSVResolver
+csv2.resolver.data.name=Appearance Resolver
+csv2.resolver.data.description=This resolver returns all the appearances for a player from the appearance table.
+csv2.resolver.data.fields=appearance
+csv2.resolver.data.field.appearance.column=0
+csv2.resolver.data.field.appearance.id=com:att:research:xacml:test:csv:subject:appearance
+csv2.resolver.data.field.appearance.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv2.resolver.data.field.appearance.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+csv2.resolver.data.field.appearance.issuer=com:att:research:xacml:test:csv
+
+csv2.resolver.data.parameters=playerid
+csv2.resolver.data.parameter.playerid.column=3
+csv2.resolver.data.parameter.playerid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id
+csv2.resolver.data.parameter.playerid.datatype=http://www.w3.org/2001/XMLSchema#string
+csv2.resolver.data.parameter.playerid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+#csv1.resolver.data.parameter.playerid.issuer=
+
+hyper1.classname=com.att.research.xacml.std.pip.engines.csv.HyperCSVEngine
+hyper1.name=World Marriage Age Limits
+hyper1.description=Minimum age for female/male marriages with or without their parental consent.
+hyper1.source=../XACML-TEST/testsets/pip/configurable-csv-hyper/marriage.csv
+hyper1.target=marriage
+hyper1.definition=country VARCHAR(80) PRIMARY KEY, wofemale INT, womale INT, wfemale INT, wmale INT, year INT, source VARCHAR(20)
+
+hyper1.resolvers=age_consent
+
+hyper1.resolver.age_consent.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver
+hyper1.resolver.age_consent.name=Ages
+hyper1.resolver.age_consent.description=This returns all the age's for consent or no consent for a country.
+hyper1.resolver.age_consent.select=SELECT wofemale,womale,wfemale,wmale FROM marriage WHERE country=?
+hyper1.resolver.age_consent.fields=wofemale,womale,wfemale,wmale
+
+hyper1.resolver.age_consent.field.wofemale.id=com:att:research:xacml:test:csv:country:no-consent:female
+hyper1.resolver.age_consent.field.wofemale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.wofemale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.wofemale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.field.womale.id=com:att:research:xacml:test:csv:country:no-consent:male
+hyper1.resolver.age_consent.field.womale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.womale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.womale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.field.wfemale.id=com:att:research:xacml:test:csv:country:consent:female
+hyper1.resolver.age_consent.field.wfemale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.wfemale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.wfemale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.field.wmale.id=com:att:research:xacml:test:csv:country:consent:male
+hyper1.resolver.age_consent.field.wmale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.wmale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.wmale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.parameters=country
+hyper1.resolver.age_consent.parameter.country.id=com:att:research:xacml:test:csv:country:name
+hyper1.resolver.age_consent.parameter.country.datatype=http://www.w3.org/2001/XMLSchema#string
+hyper1.resolver.age_consent.parameter.country.category=com:att:research:xacml:test:csv:category:country
+#hyper1.resolver.age_consent.parameter.country.issuer=
+
+sql1.classname=com.att.research.xacml.std.pip.engines.jdbc.JDBCEngine
+sql1.name=World
+sql1.description=World Database from MySQL website. Copyright Statistics Finland, http://www.stat.fi/worldinfigures.
+# This will be the default issuer for the resolvers. NOTE: Issuer only used for attributes provided by the engine.
+sql1.issuer=com:att:research:xacml:test:sql
+#
+# This is the configuration for JDBC. You will have to setup the database and run the data\world*.sql script to
+# create the tables and load the data. 
+#
+sql1.type=jdbc
+sql1.jdbc.driver=org.postgresql.Driver
+#sql1.jdbc.url=jdbc:postgresql://localhost:5432/world
+#sql1.jdbc.conn.user=sa
+#sql1.jdbc.conn.password=
+sql1.jdbc.url=jdbc:postgresql://xacml-pip.research.att.com:5432/world
+sql1.jdbc.conn.user=pip
+sql1.jdbc.conn.password=p1pUs3r
+#
+# This is the configuration for JNDI datasource.
+#
+#sql1.type=jndi
+#sql1.datasource=jdbc/xacml
+
+sql1.resolvers=langer
+
+sql1.resolver.langer.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver
+sql1.resolver.langer.name=Language
+sql1.resolver.langer.description=This returns the language for a city.
+sql1.resolver.langer.select=SELECT language FROM city INNER JOIN countrylanguage ON city.countrycode = countrylanguage.countrycode WHERE name=?
+sql1.resolver.langer.fields=language
+sql1.resolver.langer.field.language.id=com:att:research:xacml:test:sql:resource:city:language
+sql1.resolver.langer.field.language.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.langer.field.language.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+#You can override the default issuer that is set in the JDBCEngine definition if you want.
+#sql1.resolver.langer.field.language.issuer=com:att:research:xacml:test:sql
+sql1.resolver.langer.parameters=name
+sql1.resolver.langer.parameter.name.id=urn:oasis:names:tc:xacml:1.0:resource:resource-id
+sql1.resolver.langer.parameter.name.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.langer.parameter.name.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+
+
+ldap1.classname=com.att.research.xacml.std.pip.engines.ldap.LDAPEngine
+ldap1.name=LDAP PIP
+ldap1.description=The LDAP containing the seven seas sample LDIF data.
+ldap1.issuer=com:att:research:xacml:test:ldap
+ldap1.java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory
+#
+# NOTE: You will have to setup a local LDAP server and load the data\apache-ds-tutorial.ldif before
+# this example will work.
+#
+#ldap1.java.naming.provider.url=ldap://localhost:10389
+ldap1.java.naming.provider.url=ldap://xacml-pip.research.att.com:10389
+#ldap.java.naming.security.principal=
+#ldap.java.naming.security.credentials=
+ldap1.scope=subtree
+
+ldap1.resolvers=dn,ship
+
+ldap1.resolver.dn.classname=com.att.research.xacml.std.pip.engines.ldap.ConfigurableLDAPResolver
+ldap1.resolver.dn.name=Domain Names
+ldap1.resolver.dn.description=Find all the dn's for the subject id
+ldap1.resolver.dn.base=o=sevenseas
+ldap1.resolver.dn.base.parameters=
+ldap1.resolver.dn.filter=(|(uid=${uid})(mail=${uid}))
+ldap1.resolver.dn.filter.parameters=uid
+ldap1.resolver.dn.filter.parameters.uid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id
+ldap1.resolver.dn.filter.parameters.uid.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.dn.filter.parameters.uid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+#ldap1.resolver.dn.filter.parameters.uid.issuer=com:att:research:xacml:test:ldap
+ldap1.resolver.dn.filter.view=dn
+ldap1.resolver.dn.filter.view.dn.id=com:att:research:xacml:test:ldap:subject:dn
+ldap1.resolver.dn.filter.view.dn.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.dn.filter.view.dn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+ldap1.resolver.dn.filter.view.dn.issuer=com:att:research:xacml:test:ldap
+
+ldap1.resolver.ship.classname=com.att.research.xacml.std.pip.engines.ldap.ConfigurableLDAPResolver
+ldap1.resolver.ship.name=Ship Resolver
+ldap1.resolver.ship.description=This resolves a subject's dn to a ship.
+ldap1.resolver.ship.base=o=sevenseas
+ldap1.resolver.ship.base.parameters=
+ldap1.resolver.ship.filter=uniquemember=${dn}
+ldap1.resolver.ship.filter.parameters=dn
+ldap1.resolver.ship.filter.parameters.dn.id=com:att:research:xacml:test:ldap:subject:dn
+ldap1.resolver.ship.filter.parameters.dn.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.ship.filter.parameters.dn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+ldap1.resolver.ship.filter.parameters.dn.issuer=com:att:research:xacml:test:ldap
+ldap1.resolver.ship.filter.view=cn
+ldap1.resolver.ship.filter.view.cn.id=com:att:research:xacml:test:ldap:subject:ship
+ldap1.resolver.ship.filter.view.cn.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.ship.filter.view.cn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+ldap1.resolver.ship.filter.view.cn.issuer=com:att:research:xacml:test:ldap
+
diff --git a/openaz-xacml-pap-rest/pdps/configurable-sql/xacml.policy.properties b/openaz-xacml-pap-rest/pdps/configurable-sql/xacml.policy.properties
new file mode 100755
index 0000000..ed296ed
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/configurable-sql/xacml.policy.properties
@@ -0,0 +1,6 @@
+xacml.rootPolicies=SQL-World-Languages-v1.xml
+xacml.referencedPolicies=
+
+
+SQL-World-Languages-v1.xml.url=http://localhost:9090/pap/?id=SQL-World-Languages-v1.xml
+
diff --git a/openaz-xacml-pap-rest/pdps/default/AnnotationPolicy.v1.xml b/openaz-xacml-pap-rest/pdps/default/AnnotationPolicy.v1.xml
new file mode 100755
index 0000000..ae838f4
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/default/AnnotationPolicy.v1.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="urn:com:att:xacml:policy:id:5b82db34-1613-4108-8973-93074182dd94" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">
+    <Description>A sample policy to demonstrate use of annotations in a Java class.</Description>
+    <Target>
+        <AnyOf>
+            <AllOf>
+                <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">www.mywebsite.com</AttributeValue>
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+                </Match>
+            </AllOf>
+        </AnyOf>
+    </Target>
+    <Rule RuleId="urn:com:att:xacml:rule:id:8b257f30-4e06-4c8e-8fb7-691b9534d55c" Effect="Permit">
+        <Description>PERMIT - John can access it</Description>
+        <Target>
+            <AnyOf>
+                <AllOf>
+                    <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">John</AttributeValue>
+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+                    </Match>
+                    <Match MatchId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case">
+                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">ACCESS</AttributeValue>
+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+                    </Match>
+                </AllOf>
+            </AnyOf>
+        </Target>
+    </Rule>
+    <Rule RuleId="urn:com:att:xacml:rule:id:4fe7c147-7811-4e30-a463-9135afb1cfc2" Effect="Deny">
+        <Description>DENY - Ringo cannot</Description>
+        <Target>
+            <AnyOf>
+                <AllOf>
+                    <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Ringo</AttributeValue>
+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+                    </Match>
+                </AllOf>
+            </AnyOf>
+        </Target>
+    </Rule>
+</Policy>
diff --git a/openaz-xacml-pap-rest/pdps/default/CSV-Baseball-Hall-Of-Fame-v1.xml b/openaz-xacml-pap-rest/pdps/default/CSV-Baseball-Hall-Of-Fame-v1.xml
new file mode 100755
index 0000000..68c7783
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/default/CSV-Baseball-Hall-Of-Fame-v1.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<PolicySet xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicySetId="urn:com:att:xacml:policy:id:f3047eab-6f97-49b4-8127-a2737a184b35" Version="1" PolicyCombiningAlgId="urn:oasis:names:tc:xacml:3.0:policy-combining-algorithm:deny-overrides">
+    <Description>This policy enforces the BBWAA rules for baseball Hall of Fame induction.
+
+http://baseballhall.org/hall-famers/rules-election/bbwaa
+</Description>
+    <Target>
+        <AnyOf>
+            <AllOf>
+                <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">eligible</AttributeValue>
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+                </Match>
+                <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">HOF</AttributeValue>
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+                </Match>
+            </AllOf>
+        </AnyOf>
+    </Target>
+    <Policy PolicyId="urn:com:att:xacml:policy:id:8f295c67-7b6e-4db6-b558-005b36abd970" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">
+        <Description>Active Timeframe:
+
+A. A baseball player must have been active as a player in the Major Leagues at some time during a period beginning twenty (20) years before and ending five (5) years prior to election.</Description>
+        <Target/>
+        <Rule RuleId="urn:com:att:xacml:rule:id:f04b2700-1236-4066-81e4-e341b5b2f3b5" Effect="Permit">
+            <Description>Player's debut date &gt;= (today's date - 20 years) AND final date &lt;= (today's date - 5 years).</Description>
+            <Target/>
+            <Condition>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
+                    <Description>debut within 20 years AND final game more than 5 years ago.</Description>
+                    <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-less-than-or-equal">
+                        <Description>Debut date &lt;= (today's date - 20 years)</Description>
+                        <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-one-and-only">
+                            <Description>UN-bag player's debut date.</Description>
+                            <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:debut" DataType="http://www.w3.org/2001/XMLSchema#date" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/>
+                        </Apply>
+                        <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:date-subtract-yearMonthDuration">
+                            <Description>Subtract 20 years from  today's date.</Description>
+                            <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-one-and-only">
+<Description>UN-bag today's date.</Description>
+<AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:environment" AttributeId="urn:oasis:names:tc:xacml:1.0:environment:current-date" DataType="http://www.w3.org/2001/XMLSchema#date" MustBePresent="false"/>
+                            </Apply>
+                            <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#yearMonthDuration">P20Y</AttributeValue>
+                        </Apply>
+                    </Apply>
+                    <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-less-than-or-equal">
+                        <Description>Final Game &lt;= (today's date - 5 years)</Description>
+                        <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-one-and-only">
+                            <Description>UN-bag final game date</Description>
+                            <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:finalgame" DataType="http://www.w3.org/2001/XMLSchema#date" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/>
+                        </Apply>
+                        <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:date-subtract-yearMonthDuration">
+                            <Description>Subtract 5 years from today's date.</Description>
+                            <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-one-and-only">
+<Description>UN-bag today's date.</Description>
+<AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:environment" AttributeId="urn:oasis:names:tc:xacml:1.0:environment:current-date" DataType="http://www.w3.org/2001/XMLSchema#date" MustBePresent="false"/>
+                            </Apply>
+                            <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#yearMonthDuration">P5Y</AttributeValue>
+                        </Apply>
+                    </Apply>
+                </Apply>
+            </Condition>
+        </Rule>
+        <Rule RuleId="urn:com:att:xacml:rule:id:33a42a79-9d82-4aa1-99d3-9fd168363695" Effect="Deny">
+            <Description>DENY - Default</Description>
+            <Target/>
+        </Rule>
+    </Policy>
+    <Policy PolicyId="urn:com:att:xacml:policy:id:1bf74cc4-658f-4e87-be22-5d5cb741f1f5" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">
+        <Description>B. Player must have played in each of ten (10) Major League championship seasons, some part of which must have been within the period described in 3 (A).</Description>
+        <Target/>
+        <Rule RuleId="urn:com:att:xacml:rule:id:54405c39-a3f6-4a88-89bd-084f68567acd" Effect="Permit">
+            <Description>There should be &gt;= 10 years of appearance(s) values.</Description>
+            <Target/>
+            <Condition>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal">
+                    <Description>The number of years a player appeared.</Description>
+                    <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-bag-size">
+                        <Description>Count the number.</Description>
+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:appearance" DataType="http://www.w3.org/2001/XMLSchema#integer" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/>
+                    </Apply>
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">10</AttributeValue>
+                </Apply>
+            </Condition>
+        </Rule>
+        <Rule RuleId="urn:com:att:xacml:rule:id:912dd1a2-1527-4b6f-a95b-6a729ff9caab" Effect="Deny">
+            <Description>DENY - Default</Description>
+            <Target/>
+        </Rule>
+    </Policy>
+</PolicySet>
diff --git a/openaz-xacml-pap-rest/pdps/default/CSV-Legal-Age-Marriage-v1.xml b/openaz-xacml-pap-rest/pdps/default/CSV-Legal-Age-Marriage-v1.xml
new file mode 100755
index 0000000..15e25ed
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/default/CSV-Legal-Age-Marriage-v1.xml
@@ -0,0 +1,200 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<PolicySet xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicySetId="urn:com:att:xacml:policy:id:98779898-b880-44d7-bee5-ce54e42266eb" Version="1" PolicyCombiningAlgId="urn:oasis:names:tc:xacml:3.0:policy-combining-algorithm:deny-overrides">
+    <Description>Sample policy for the XACML-TEST project that tests the configurable CSV PIP.</Description>
+    <Target>
+        <AnyOf>
+            <AllOf>
+                <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Marry</AttributeValue>
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+                </Match>
+            </AllOf>
+        </AnyOf>
+    </Target>
+    <Policy PolicyId="urn:com:att:xacml:policy:id:c6791398-7e1f-4564-8f5c-19f406ea9950" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-unless-permit">
+        <Description>Checks the subject. </Description>
+        <Target/>
+        <VariableDefinition VariableId="isSubjectFemale">
+            <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case">
+                <Description>sex=Female</Description>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+                    <Description>un-bag</Description>
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:sex" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+                </Apply>
+                <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Female</AttributeValue>
+            </Apply>
+        </VariableDefinition>
+        <VariableDefinition VariableId="isSubjectMale">
+            <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case">
+                <Description>subject sex=Male</Description>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+                    <Description>Un-bag</Description>
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:sex" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+                </Apply>
+                <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Male</AttributeValue>
+            </Apply>
+        </VariableDefinition>
+        <VariableDefinition VariableId="doesSubjectNeedParentalConsent">
+            <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:or">
+                <Description>Is the subject a female OR male?</Description>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
+                    <Description>Is female AND does not need parental consent.</Description>
+                    <VariableReference VariableId="isSubjectFemale"/>
+                    <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than">
+                        <Description>age &gt;= consent age</Description>
+                        <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+                            <Description>Un-bag attribute.</Description>
+                            <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:age" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="true"/>
+                        </Apply>
+                        <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+                            <Description>Un-bag attribute.</Description>
+                            <AttributeDesignator Category="com:att:research:xacml:test:csv:category:country" AttributeId="com:att:research:xacml:test:csv:country:no-consent:female" DataType="http://www.w3.org/2001/XMLSchema#integer" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/>
+                        </Apply>
+                    </Apply>
+                </Apply>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
+                    <Description>Is subject male AND age &gt;= male consent age.</Description>
+                    <VariableReference VariableId="isSubjectMale"/>
+                    <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than">
+                        <Description>age &gt;= legal age of consent for male.</Description>
+                        <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+                            <Description>Un-bag attribute.</Description>
+                            <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:age" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="true"/>
+                        </Apply>
+                        <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+                            <Description>Un-bag attribute.</Description>
+                            <AttributeDesignator Category="com:att:research:xacml:test:csv:category:country" AttributeId="com:att:research:xacml:test:csv:country:no-consent:male" DataType="http://www.w3.org/2001/XMLSchema#integer" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/>
+                        </Apply>
+                    </Apply>
+                </Apply>
+            </Apply>
+        </VariableDefinition>
+         <VariableDefinition VariableId="doesSubjectHaveParentalConsent">
+            <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-one-and-only">
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:parental-consent" DataType="http://www.w3.org/2001/XMLSchema#boolean" MustBePresent="true"/>
+                </Apply>
+                <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue>
+            </Apply>
+        </VariableDefinition>
+        <Rule RuleId="urn:com:att:xacml:rule:id:5970b5d2-c0f3-4132-bfa2-268467b21ed7" Effect="Permit">
+            <Description>If the subject does NOT need consent, then PERMIT.</Description>
+            <Target/>
+            <Condition>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+                    <VariableReference VariableId="doesSubjectNeedParentalConsent"/>
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">false</AttributeValue>
+                </Apply>
+            </Condition>
+        </Rule>
+        <Rule RuleId="urn:com:att:xacml:rule:id:04b3e93d-ec4e-4cce-a00e-6a54cf3c4056" Effect="Permit">
+            <Description>If the subject needs consent AND has parental consent, then Permit.</Description>
+            <Target/>
+            <Condition>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
+                    <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+                        <VariableReference VariableId="doesSubjectNeedParentalConsent"/>
+                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue>
+                    </Apply>
+                    <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+                        <VariableReference VariableId="doesSubjectHaveParentalConsent"/>
+                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue>
+                    </Apply>
+                </Apply>
+            </Condition>
+        </Rule>
+    </Policy>
+    <Policy PolicyId="urn:com:att:xacml:policy:id:32474315-9d06-47a4-bc2d-319e0568742c" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-unless-permit">
+        <Description>Check the resource.</Description>
+        <Target/>
+        <VariableDefinition VariableId="isResourceFemale">
+            <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case">
+                <Description>sex=Female</Description>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+                    <Description>un-bag</Description>
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:csv:resource:sex" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+                </Apply>
+                <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Female</AttributeValue>
+            </Apply>
+        </VariableDefinition>
+        <VariableDefinition VariableId="isResourceMale">
+            <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case">
+                <Description>subject sex=Male</Description>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+                    <Description>Un-bag</Description>
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:csv:resource:sex" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+                </Apply>
+                <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Male</AttributeValue>
+            </Apply>
+        </VariableDefinition>
+        <VariableDefinition VariableId="doesResourceNeedParentalConsent">
+            <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:or">
+                <Description>Is resource female OR male?</Description>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
+                    <Description>Is female AND does not need parental consent.</Description>
+                    <VariableReference VariableId="isResourceFemale"/>
+                    <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than">
+                        <Description>age &gt;= consent age for female.</Description>
+                        <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+                            <Description>Un-bag attribute</Description>
+                            <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:csv:resource:age" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="true"/>
+                        </Apply>
+                        <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+                            <Description>un-bag attribute</Description>
+                            <AttributeDesignator Category="com:att:research:xacml:test:csv:category:country" AttributeId="com:att:research:xacml:test:csv:country:no-consent:female" DataType="http://www.w3.org/2001/XMLSchema#integer" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/>
+                        </Apply>
+                    </Apply>
+                </Apply>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
+                    <Description>Is male and AND does not need parental consent.</Description>
+                    <VariableReference VariableId="isResourceMale"/>
+                    <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than">
+                        <Description>age &gt;= consent age for male.</Description>
+                        <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+                            <Description>Un-bag</Description>
+                            <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:csv:resource:age" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="false"/>
+                        </Apply>
+                        <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+                            <Description>Un-bag</Description>
+                            <AttributeDesignator Category="com:att:research:xacml:test:csv:category:country" AttributeId="com:att:research:xacml:test:csv:country:no-consent:male" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="false"/>
+                        </Apply>
+                    </Apply>
+                </Apply>
+            </Apply>
+        </VariableDefinition>
+        <VariableDefinition VariableId="doesResourceHaveParentalConsent">
+            <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-one-and-only">
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:csv:resource:parental-consent" DataType="http://www.w3.org/2001/XMLSchema#boolean" MustBePresent="true"/>
+                </Apply>
+                <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue>
+            </Apply>
+        </VariableDefinition>
+        <Rule RuleId="urn:com:att:xacml:rule:id:7d1c6802-97f7-44f6-9819-12edc1801fb7" Effect="Permit">
+            <Description>If the resource does NOT need consent, then PERMIT.</Description>
+            <Target/>
+            <Condition>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+                    <VariableReference VariableId="doesResourceNeedParentalConsent"/>
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">false</AttributeValue>
+                </Apply>
+            </Condition>
+        </Rule>
+        <Rule RuleId="urn:com:att:xacml:rule:id:62e07da4-f0e5-46eb-9894-f5e6d2e5868b" Effect="Permit">
+            <Description>The resources needs parental consent and has parental consent then PERMIT.</Description>
+            <Target/>
+            <Condition>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
+                    <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+                        <VariableReference VariableId="doesResourceNeedParentalConsent"/>
+                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue>
+                    </Apply>
+                    <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+                        <VariableReference VariableId="doesResourceHaveParentalConsent"/>
+                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue>
+                    </Apply>
+                </Apply>
+            </Condition>
+        </Rule>
+    </Policy>
+</PolicySet>
diff --git a/openaz-xacml-pap-rest/pdps/default/LDAP-Seven-Seas-v1.xml b/openaz-xacml-pap-rest/pdps/default/LDAP-Seven-Seas-v1.xml
new file mode 100755
index 0000000..9e36f68
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/default/LDAP-Seven-Seas-v1.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="urn:com:att:xacml:policy:id:94378f81-6810-408f-a072-a1a8a7585a24" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">
+	<Description>Sample policy that demonstrates use of Configurable LDAP Resolver with sample data.
+
+The PEP Request should provide the following attributes:
+action-id=board
+subject-id-qualifer=uid|mail
+subject-id=hnelson|hnelson@royalnavy.mod.uk
+resource-id=HMS Lydia|HMS Victory|HMS Bounty
+	</Description>
+        <Target>
+            <AnyOf>
+                <AllOf>
+                    <Match MatchId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case">
+                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">board</AttributeValue>
+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+                    </Match>
+                </AllOf>
+            </AnyOf>
+        </Target>
+        <Rule RuleId="urn:com:att:xacml:rule:id:bf241671-54de-404c-ac59-bb17b919783f" Effect="Permit">
+            <Description>This sailor is a member of the crew for the ship.</Description>
+            <Target/>
+            <Condition>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+                    <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:ldap:subject:ship" DataType="http://www.w3.org/2001/XMLSchema#string" Issuer="com:att:research:xacml:test:ldap" MustBePresent="false"/>
+                    </Apply>
+                    <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+                    </Apply>
+                </Apply>
+            </Condition>
+        </Rule>
+        <Rule RuleId="urn:com:att:xacml:rule:id:490228ea-98ee-48d8-84c9-da07334726fd" Effect="Deny">
+            <Description>Default is to DENY.</Description>
+            <Target/>
+        </Rule>
+</Policy>
diff --git a/openaz-xacml-pap-rest/pdps/default/SQL-World-Languages-v1.xml b/openaz-xacml-pap-rest/pdps/default/SQL-World-Languages-v1.xml
new file mode 100755
index 0000000..85443dc
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/default/SQL-World-Languages-v1.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="urn:com:att:xacml:policy:id:25e12b06-11d5-4895-b2a2-6f6c594de069" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">
+        <Description>Policy for speaking a language in a city.</Description>
+        <Target>
+            <AnyOf>
+                <AllOf>
+                    <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">speak</AttributeValue>
+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+                    </Match>
+                </AllOf>
+            </AnyOf>
+        </Target>
+        <Rule RuleId="urn:com:att:xacml:rule:id:e1e8c5c0-e2ba-47d5-9289-6c015305ed21" Effect="Permit">
+            <Description>PERMIT - People in this city speak my language.</Description>
+            <Target/>
+            <Condition>
+                <VariableReference VariableId="cityLanguage"/>
+            </Condition>
+        </Rule>
+        <VariableDefinition VariableId="cityLanguage">
+            <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-is-in">
+                <Description>The city's language must match exactly the subject's language.</Description>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+                </Apply>
+                <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:sql:resource:city:language" DataType="http://www.w3.org/2001/XMLSchema#string" Issuer="com:att:research:xacml:test:sql" MustBePresent="false"/>
+            </Apply>
+        </VariableDefinition>
+        <Rule RuleId="urn:com:att:xacml:rule:id:c9a3fb7d-d0b9-48bb-bdca-87eb4957120c" Effect="Deny">
+            <Description>DENY - default.</Description>
+            <Target/>
+        </Rule>
+</Policy>
diff --git a/openaz-xacml-pap-rest/pdps/default/xacml.pip.properties b/openaz-xacml-pap-rest/pdps/default/xacml.pip.properties
new file mode 100755
index 0000000..4d49be1
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/default/xacml.pip.properties
@@ -0,0 +1,219 @@
+# PIP Engine Definition
+#
+xacml.pip.engines=csv1,csv2,hyper1,sql1,ldap1
+
+csv1.classname=com.att.research.xacml.std.pip.engines.csv.CSVEngine
+csv1.name=Master
+csv1.description=Sean Lahman Basebase stats - Player names, DOB, and biographical info
+csv1.issuer=com:att:research:xacml:test:csv
+csv1.source=../XACML-TEST/testsets/pip/configurable-csv/adminDB/Master.txt
+csv1.maxsize=500000
+csv1.delimiter=,
+csv1.quote="
+csv1.skip=0
+
+csv1.resolvers=data
+
+csv1.resolver.data.classname=com.att.research.xacml.std.pip.engines.csv.ConfigurableCSVResolver
+csv1.resolver.data.name=Player Resolver
+csv1.resolver.data.description=This resolver finds player information in the Master table.
+csv1.resolver.data.fields=firstname,lastname,deathyear,deathmonth,deathday,debut,finalgame
+csv1.resolver.data.field.firstname.column=16
+csv1.resolver.data.field.firstname.id=com:att:research:xacml:test:csv:subject:firstname
+csv1.resolver.data.field.firstname.datatype=http://www.w3.org/2001/XMLSchema#string
+csv1.resolver.data.field.firstname.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.lastname.column=17
+csv1.resolver.data.field.lastname.id=com:att:research:xacml:test:csv:subject:lastname
+csv1.resolver.data.field.lastname.datatype=http://www.w3.org/2001/XMLSchema#string
+csv1.resolver.data.field.lastname.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.deathyear.column=10
+csv1.resolver.data.field.deathyear.id=com:att:research:xacml:test:csv:subject:deathyear
+csv1.resolver.data.field.deathyear.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv1.resolver.data.field.deathyear.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.deathmonth.column=11
+csv1.resolver.data.field.deathmonth.id=com:att:research:xacml:test:csv:subject:deathmonth
+csv1.resolver.data.field.deathmonth.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv1.resolver.data.field.deathmonth.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.deathday.column=12
+csv1.resolver.data.field.deathday.id=com:att:research:xacml:test:csv:subject:deathday
+csv1.resolver.data.field.deathday.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv1.resolver.data.field.deathday.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.debut.column=25
+csv1.resolver.data.field.debut.id=com:att:research:xacml:test:csv:subject:debut
+csv1.resolver.data.field.debut.datatype=http://www.w3.org/2001/XMLSchema#date
+csv1.resolver.data.field.debut.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.finalgame.column=26
+csv1.resolver.data.field.finalgame.id=com:att:research:xacml:test:csv:subject:finalgame
+csv1.resolver.data.field.finalgame.datatype=http://www.w3.org/2001/XMLSchema#date
+csv1.resolver.data.field.finalgame.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.parameters=playerid
+csv1.resolver.data.parameter.playerid.column=1
+csv1.resolver.data.parameter.playerid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id
+csv1.resolver.data.parameter.playerid.datatype=http://www.w3.org/2001/XMLSchema#string
+csv1.resolver.data.parameter.playerid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv2.classname=com.att.research.xacml.std.pip.engines.csv.CSVEngine
+csv2.name=Appearances
+csv2.description=Sean Lahman Basebase stats - Player appearances for a team in a given year.
+#csv2.issuer=
+csv2.source=../XACML-TEST/testsets/pip/configurable-csv/adminDB/Appearances.txt
+csv2.maxsize=500000
+csv2.delimiter=,
+csv2.quote="
+csv2.skip=0
+
+csv2.resolvers=data
+
+csv2.resolver.data.classname=com.att.research.xacml.std.pip.engines.csv.ConfigurableCSVResolver
+csv2.resolver.data.name=Appearance Resolver
+csv2.resolver.data.description=This resolver returns all the appearances for a player from the appearance table.
+csv2.resolver.data.fields=appearance
+csv2.resolver.data.field.appearance.column=0
+csv2.resolver.data.field.appearance.id=com:att:research:xacml:test:csv:subject:appearance
+csv2.resolver.data.field.appearance.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv2.resolver.data.field.appearance.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+csv2.resolver.data.field.appearance.issuer=com:att:research:xacml:test:csv
+
+csv2.resolver.data.parameters=playerid
+csv2.resolver.data.parameter.playerid.column=3
+csv2.resolver.data.parameter.playerid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id
+csv2.resolver.data.parameter.playerid.datatype=http://www.w3.org/2001/XMLSchema#string
+csv2.resolver.data.parameter.playerid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+#csv1.resolver.data.parameter.playerid.issuer=
+
+hyper1.classname=com.att.research.xacml.std.pip.engines.csv.HyperCSVEngine
+hyper1.name=World Marriage Age Limits
+hyper1.description=Minimum age for female/male marriages with or without their parental consent.
+hyper1.source=../XACML-TEST/testsets/pip/configurable-csv-hyper/marriage.csv
+hyper1.target=marriage
+hyper1.definition=country VARCHAR(80) PRIMARY KEY, wofemale INT, womale INT, wfemale INT, wmale INT, year INT, source VARCHAR(20)
+
+hyper1.resolvers=age_consent
+
+hyper1.resolver.age_consent.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver
+hyper1.resolver.age_consent.name=Ages
+hyper1.resolver.age_consent.description=This returns all the age's for consent or no consent for a country.
+hyper1.resolver.age_consent.select=SELECT wofemale,womale,wfemale,wmale FROM marriage WHERE country=?
+hyper1.resolver.age_consent.fields=wofemale,womale,wfemale,wmale
+
+hyper1.resolver.age_consent.field.wofemale.id=com:att:research:xacml:test:csv:country:no-consent:female
+hyper1.resolver.age_consent.field.wofemale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.wofemale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.wofemale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.field.womale.id=com:att:research:xacml:test:csv:country:no-consent:male
+hyper1.resolver.age_consent.field.womale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.womale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.womale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.field.wfemale.id=com:att:research:xacml:test:csv:country:consent:female
+hyper1.resolver.age_consent.field.wfemale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.wfemale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.wfemale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.field.wmale.id=com:att:research:xacml:test:csv:country:consent:male
+hyper1.resolver.age_consent.field.wmale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.wmale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.wmale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.parameters=country
+hyper1.resolver.age_consent.parameter.country.id=com:att:research:xacml:test:csv:country:name
+hyper1.resolver.age_consent.parameter.country.datatype=http://www.w3.org/2001/XMLSchema#string
+hyper1.resolver.age_consent.parameter.country.category=com:att:research:xacml:test:csv:category:country
+#hyper1.resolver.age_consent.parameter.country.issuer=
+
+sql1.classname=com.att.research.xacml.std.pip.engines.jdbc.JDBCEngine
+sql1.name=World
+sql1.description=World Database from MySQL website. Copyright Statistics Finland, http://www.stat.fi/worldinfigures.
+# This will be the default issuer for the resolvers. NOTE: Issuer only used for attributes provided by the engine.
+sql1.issuer=com:att:research:xacml:test:sql
+#
+# This is the configuration for JDBC. You will have to setup the database and run the data\world*.sql script to
+# create the tables and load the data. 
+#
+sql1.type=jdbc
+sql1.jdbc.driver=org.postgresql.Driver
+sql1.jdbc.url=jdbc:postgresql://localhost:5432/world
+sql1.jdbc.conn.user=sa
+sql1.jdbc.conn.password=
+#
+# This is the configuration for JNDI datasource.
+#
+#sql1.type=jndi
+#sql1.datasource=jdbc/xacml
+
+sql1.resolvers=langer
+
+sql1.resolver.langer.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver
+sql1.resolver.langer.name=Language
+sql1.resolver.langer.description=This returns the language for a city.
+sql1.resolver.langer.select=SELECT language FROM city INNER JOIN countrylanguage ON city.countrycode = countrylanguage.countrycode WHERE name=?
+sql1.resolver.langer.fields=language
+sql1.resolver.langer.field.language.id=com:att:research:xacml:test:sql:resource:city:language
+sql1.resolver.langer.field.language.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.langer.field.language.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+#You can override the default issuer that is set in the JDBCEngine definition if you want.
+#sql1.resolver.langer.field.language.issuer=com:att:research:xacml:test:sql
+sql1.resolver.langer.parameters=name
+sql1.resolver.langer.parameter.name.id=urn:oasis:names:tc:xacml:1.0:resource:resource-id
+sql1.resolver.langer.parameter.name.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.langer.parameter.name.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+
+
+ldap1.classname=com.att.research.xacml.std.pip.engines.ldap.LDAPEngine
+ldap1.name=LDAP PIP
+ldap1.description=The LDAP containing the seven seas sample LDIF data.
+ldap1.issuer=com:att:research:xacml:test:ldap
+ldap1.java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory
+#
+# NOTE: You will have to setup a local LDAP server and load the data\apache-ds-tutorial.ldif before
+# this example will work.
+#
+ldap1.java.naming.provider.url=ldap://localhost:10389
+#ldap.java.naming.security.principal=
+#ldap.java.naming.security.credentials=
+ldap1.scope=subtree
+
+ldap1.resolvers=dn,ship
+
+ldap1.resolver.dn.classname=com.att.research.xacml.std.pip.engines.ldap.ConfigurableLDAPResolver
+ldap1.resolver.dn.name=Domain Names
+ldap1.resolver.dn.description=Find all the dn's for the subject id
+ldap1.resolver.dn.base=o=sevenseas
+ldap1.resolver.dn.base.parameters=
+ldap1.resolver.dn.filter=(|(uid=${uid})(mail=${uid}))
+ldap1.resolver.dn.filter.parameters=uid
+ldap1.resolver.dn.filter.parameters.uid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id
+ldap1.resolver.dn.filter.parameters.uid.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.dn.filter.parameters.uid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+#ldap1.resolver.dn.filter.parameters.uid.issuer=com:att:research:xacml:test:ldap
+ldap1.resolver.dn.filter.view=dn
+ldap1.resolver.dn.filter.view.dn.id=com:att:research:xacml:test:ldap:subject:dn
+ldap1.resolver.dn.filter.view.dn.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.dn.filter.view.dn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+ldap1.resolver.dn.filter.view.dn.issuer=com:att:research:xacml:test:ldap
+
+ldap1.resolver.ship.classname=com.att.research.xacml.std.pip.engines.ldap.ConfigurableLDAPResolver
+ldap1.resolver.ship.name=Ship Resolver
+ldap1.resolver.ship.description=This resolves a subject's dn to a ship.
+ldap1.resolver.ship.base=o=sevenseas
+ldap1.resolver.ship.base.parameters=
+ldap1.resolver.ship.filter=uniquemember=${dn}
+ldap1.resolver.ship.filter.parameters=dn
+ldap1.resolver.ship.filter.parameters.dn.id=com:att:research:xacml:test:ldap:subject:dn
+ldap1.resolver.ship.filter.parameters.dn.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.ship.filter.parameters.dn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+ldap1.resolver.ship.filter.parameters.dn.issuer=com:att:research:xacml:test:ldap
+ldap1.resolver.ship.filter.view=cn
+ldap1.resolver.ship.filter.view.cn.id=com:att:research:xacml:test:ldap:subject:ship
+ldap1.resolver.ship.filter.view.cn.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.ship.filter.view.cn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+ldap1.resolver.ship.filter.view.cn.issuer=com:att:research:xacml:test:ldap
+
diff --git a/openaz-xacml-pap-rest/pdps/default/xacml.policy.properties b/openaz-xacml-pap-rest/pdps/default/xacml.policy.properties
new file mode 100755
index 0000000..78c4a85
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/default/xacml.policy.properties
@@ -0,0 +1,14 @@
+xacml.rootPolicies=AnnotationPolicy.v1.xml,LDAP-Seven-Seas-v1.xml,CSV-Baseball-Hall-Of-Fame-v1.xml,CSV-Legal-Age-Marriage-v1.xml,SQL-World-Languages-v1.xml 
+xacml.referencedPolicies=
+
+AnnotationPolicy.v1.xml.url=http://localhost:9090/pap/?id=AnnotationPolicy.v1.xml
+
+LDAP-Seven-Seas-v1.xml.url=http://localhost:9090/pap/?id=LDAP-Seven-Seas-v1.xml
+
+CSV-Baseball-Hall-Of-Fame-v1.xml.url=http://localhost:9090/pap/?id=CSV-Baseball-Hall-Of-Fame-v1.xml
+
+CSV-Legal-Age-Marriage-v1.xml.url=http://localhost:9090/pap/?id=CSV-Legal-Age-Marriage-v1.xml
+
+SQL-World-Languages-v1.xml.url=http://localhost:9090/pap/?id=SQL-World-Languages-v1.xml
+
+
diff --git a/openaz-xacml-pap-rest/pdps/xacml.properties b/openaz-xacml-pap-rest/pdps/xacml.properties
new file mode 100755
index 0000000..8429c20
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/xacml.properties
@@ -0,0 +1,27 @@
+#
+#Mon Apr 21 11:22:57 EDT 2014
+xacml.pap.groups=default,configurable-csv,configurable-csv-hyper,configurable-ldap,configurable-sql,configurable-csv-and-hyper
+
+default.description=The default group where new PDP's are put.
+default.name=default
+default.pdps=
+
+configurable-csv.description=A group whose policies only serve configurable-csv requests.
+configurable-csv.name=configurable-csv
+configurable-csv.pdps=
+
+configurable-csv-hyper.description=A group whose policies only serve configurable-csv-hyper requests.
+configurable-csv-hyper.name=configurable-csv-hyper
+configurable-csv-hyper.pdps=
+
+configurable-ldap.description=A group whose policies only serve configurable-ldap requests.
+configurable-ldap.name=configurable-ldap
+configurable-ldap.pdps=
+
+configurable-sql.description=A group whose policies only serve configurable-sql requests.
+configurable-sql.name=configurable-sql
+configurable-sql.pdps=
+
+configurable-csv-and-hyper.description=A group whose policies serve both configurable-csv and configurable-csv-hyper requests but not others.
+configurable-csv-and-hyper.name=configurable-csv-and-hyper
+configurable-csv-and-hyper.pdps=
\ No newline at end of file
diff --git a/openaz-xacml-pap-rest/pom.xml b/openaz-xacml-pap-rest/pom.xml
new file mode 100755
index 0000000..d86600c
--- /dev/null
+++ b/openaz-xacml-pap-rest/pom.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>openaz</artifactId>
+        <groupId>org.openliberty.openaz</groupId>
+        <version>0.0.1-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>openaz-xacml-pap-rest</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.openliberty.openaz</groupId>
+            <artifactId>openaz-xacml</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.openliberty.openaz</groupId>
+            <artifactId>openaz-xacml-rest</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-logging</groupId>
+            <artifactId>commons-logging</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/openaz-xacml-pap-rest/src/main/java/com/att/research/xacml/rest/XACMLPapServlet.java b/openaz-xacml-pap-rest/src/main/java/com/att/research/xacml/rest/XACMLPapServlet.java
new file mode 100755
index 0000000..e57a36b
--- /dev/null
+++ b/openaz-xacml-pap-rest/src/main/java/com/att/research/xacml/rest/XACMLPapServlet.java
@@ -0,0 +1,1529 @@
+/*
+ *                        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.xacml.rest;
+
+
+import com.att.research.xacml.api.pap.*;
+import com.att.research.xacml.std.pap.StdPDP;
+import com.att.research.xacml.std.pap.StdPDPGroup;
+import com.att.research.xacml.std.pap.StdPDPItemSetChangeNotifier.StdItemSetChangeListener;
+import com.att.research.xacml.std.pap.StdPDPStatus;
+import com.att.research.xacml.util.FactoryException;
+import com.att.research.xacml.util.XACMLProperties;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.base.Splitter;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.servlet.Servlet;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.annotation.WebInitParam;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.*;
+import java.util.*;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+/**
+ * Servlet implementation class XacmlPapServlet
+ * 
+ * 
+ * @author pameladragosh
+ */
+@WebServlet(
+		description = "Implements the XACML PAP RESTful API.", 
+		urlPatterns = { "/" }, 
+		loadOnStartup=1,
+		initParams = {
+				@WebInitParam(name = "XACML_PROPERTIES_NAME", value = "xacml.pap.properties", description = "The location of the properties file holding configuration information.")
+		})
+
+public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeListener, Runnable {
+	private static final long serialVersionUID = 1L;
+	private static final Log logger	= LogFactory.getLog(XACMLPapServlet.class);
+	
+	/*
+	 * 
+	 * papEngine - This is our engine workhorse that manages the PDP Groups and Nodes.
+	 */
+	private PAPEngine papEngine = null;
+	
+	/*
+	 * This PAP instance's own URL.
+	 * 
+	 * Need this when creating URLs to send to the PDPs so they can GET the Policy files from this process. 
+	 */
+	private static String papURL = null;
+	
+	/*
+	 * List of Admin Console URLs.
+	 * Used to send notifications when configuration changes.
+	 * 
+	 * The CopyOnWriteArrayList *should* protect from concurrency errors.
+	 * This list is seldom changed but often read, so the costs of this approach make sense.
+	 */
+	private static final CopyOnWriteArrayList<String> adminConsoleURLStringList = new CopyOnWriteArrayList<String>();
+	
+	/*
+	 * This thread may be invoked upon startup to initiate sending PDP policy/pip configuration when
+	 * this servlet starts. Its configurable by the admin.
+	 */
+	private Thread initiateThread = null;
+	
+	/*
+	// The heartbeat thread.
+	*/
+	private static Heartbeat heartbeat = null;
+	private static Thread heartbeatThread = null;
+	
+    /**
+     * @see HttpServlet#HttpServlet()
+     */
+    public XACMLPapServlet() {
+        super();
+    }
+
+	/**
+	 * @see Servlet#init(ServletConfig)
+	 */
+	public void init(ServletConfig config) throws ServletException {
+		try {
+			//
+			// Initialize
+			//
+			XACMLRest.xacmlInit(config);
+			//
+			// Load the properties
+			//
+			XACMLRest.loadXacmlProperties(null, null);
+			//
+			// Load our PAP engine, first create a factory
+			//
+			PAPEngineFactory factory = PAPEngineFactory.newInstance(XACMLProperties.getProperty(XACMLProperties.PROP_PAP_PAPENGINEFACTORY));
+			//
+			// The factory knows how to go about creating a PAP Engine
+			//
+			this.papEngine = factory.newEngine();			
+			//
+			// we are about to call the PDPs and give them their configuration.
+			// To do that we need to have the URL of this PAP so we can construct the Policy file URLs
+			//
+			XACMLPapServlet.papURL = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_URL);
+			//
+			// Sanity check that a URL was defined somewhere, its essential.
+			//
+			// How to check that its valid? We can validate the form, but since we are in the init() method we
+			// are not fully loaded yet so we really couldn't ping ourself to see if the URL will work. One
+			// will have to look for errors in the PDP logs to determine if they are failing to initiate a
+			// request to this servlet.
+			//
+			if (XACMLPapServlet.papURL == null) {
+				throw new PAPException("The property " + XACMLRestProperties.PROP_PAP_URL + " is not valid: " + XACMLPapServlet.papURL);
+			}
+			//
+			// Configurable - have the PAP servlet initiate sending the latest PDP policy/pip configuration
+			// to all its known PDP nodes.
+			//
+			// Note: parseBoolean will return false if there is no property defined. This is fine for a default.
+			//
+			if (Boolean.parseBoolean(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_INITIATE_PDP_CONFIG))) {
+				this.initiateThread = new Thread(this);
+				this.initiateThread.start();
+			}
+			//
+			// After startup, the PAP does Heartbeats to each of the PDPs periodically
+			//
+			XACMLPapServlet.heartbeat = new Heartbeat(this.papEngine);
+			XACMLPapServlet.heartbeatThread = new Thread(XACMLPapServlet.heartbeat);
+			XACMLPapServlet.heartbeatThread.start();
+		} catch (FactoryException | PAPException e) {
+			logger.error("Failed to create engine", e);
+			throw new ServletException ("PAP not initialized; error: "+e);
+		} catch (Exception e) {
+			logger.error("Failed to create engine - unexpected error: ", e);
+			throw new ServletException ("PAP not initialized; unexpected error: "+e);		}
+	}
+
+	/**
+	 * Thread used only during PAP startup to initiate change messages to all known PDPs.
+	 * This must be on a separate thread so that any GET requests from the PDPs during this update can be serviced.
+	 */
+	@Override
+	public void run() {
+		//
+		// send the current configuration to all the PDPs that we know about
+		//
+		changed();
+	}
+	
+
+	/**
+	 * @see Servlet#destroy()
+	 * 
+	 * Depending on how this servlet is run, we may or may not care about cleaning up the resources.
+	 * For now we assume that we do care.
+	 */
+	public void destroy() {
+		//
+		// Make sure our threads are destroyed
+		//
+		if (XACMLPapServlet.heartbeatThread != null) {
+			//
+			// stop the heartbeat
+			//
+			try {
+				if (XACMLPapServlet.heartbeat != null) {
+					XACMLPapServlet.heartbeat.terminate();
+				}
+				XACMLPapServlet.heartbeatThread.interrupt();
+				XACMLPapServlet.heartbeatThread.join();
+			} catch (InterruptedException e) {
+				logger.error(e);
+			}
+		}
+		if (this.initiateThread != null) {
+			try {
+				this.initiateThread.interrupt();
+				this.initiateThread.join();
+			} catch (InterruptedException e) {
+				logger.error(e);
+			}
+		}
+	}
+	
+	/**
+	 * 
+	 * Called by:
+	 * 	- PDP nodes to register themselves with the PAP, and
+	 * 	- Admin Console to make changes in the PDP Groups.
+	 * 
+	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
+	 */
+	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+		try {
+
+			XACMLRest.dumpRequest(request);
+
+			// since getParameter reads the content string, explicitly get the content before doing that.
+			// Simply getting the inputStream seems to protect it against being consumed by getParameter.
+			request.getInputStream();
+			
+			//
+			// Is this from the Admin Console?
+			//
+			String groupId = request.getParameter("groupId");
+			if (groupId != null) {
+				//
+				// this is from the Admin Console, so handle separately
+				//
+				doACPost(request, response, groupId);
+				return;
+			}
+			
+			//
+			//  Request is from a PDP.
+			//	It is coming up and asking for its config
+			//
+			
+			//
+			// Get the PDP's ID
+			//
+			String id = this.getPDPID(request);
+			logger.info("doPost from: " + id);
+			//
+			// Get the PDP Object
+			//
+			PDP pdp = this.papEngine.getPDP(id);
+			//
+			// Is it known?
+			//
+			if (pdp == null) {
+				logger.info("Unknown PDP: " + id);
+				try {
+					this.papEngine.newPDP(id, this.papEngine.getDefaultGroup(), id, "Registered on first startup");
+				} catch (NullPointerException | PAPException e) {
+					logger.error("Failed to create new PDP", e);
+					response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
+					return;
+				}
+				// get the PDP we just created
+				pdp = this.papEngine.getPDP(id);
+				if (pdp == null) {
+					String message = "Failed to create new PDP for id: " + id;
+					logger.error(message);
+					response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
+					return;
+				}
+			}
+			//
+			// Get the PDP's Group
+			//
+			PDPGroup group = this.papEngine.getPDPGroup(pdp);
+			if (group == null) {
+				response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "PDP not associated with any group, even the default");
+				return;
+			}
+			//
+			// Determine what group the PDP node is in and get
+			// its policy/pip properties.
+			//
+			Properties policies = group.getPolicyProperties();
+			Properties pipconfig = group.getPipConfigProperties();
+			//
+			// Get the current policy/pip configuration that the PDP has
+			//
+			Properties pdpProperties = new Properties();
+			pdpProperties.load(request.getInputStream());
+			logger.info("PDP Current Properties: " + pdpProperties.toString());
+			logger.info("Policies: " + (policies != null ? policies.toString() : "null"));
+			logger.info("Pip config: " + (pipconfig != null ? pipconfig.toString() : "null"));
+			//
+			// Validate the node's properties
+			//
+			boolean isCurrent = this.isPDPCurrent(policies, pipconfig, pdpProperties);
+			//
+			// Send back current configuration
+			//
+			if (isCurrent == false) {
+				//
+				// Tell the PDP we are sending back the current policies/pip config
+				//
+				logger.info("PDP configuration NOT current.");
+				if (policies != null) {
+					//
+					// Put URL's into the properties in case the PDP needs to
+					// retrieve them.
+					//
+					this.populatePolicyURL(request.getRequestURL(), policies);
+					//
+					// Copy the properties to the output stream
+					//
+					policies.store(response.getOutputStream(), "");
+				}
+				if (pipconfig != null) {
+					//
+					// Copy the properties to the output stream
+					//
+					pipconfig.store(response.getOutputStream(), "");
+				}
+				//
+				// We are good - and we are sending them information
+				//
+				response.setStatus(HttpServletResponse.SC_OK);
+//TODO - Correct?				
+				setPDPSummaryStatus(pdp, PDPStatus.Status.OUT_OF_SYNCH);
+			} else {
+				//
+				// Tell them they are good
+				//
+				response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+				
+ //TODO - Correct?
+				setPDPSummaryStatus(pdp, PDPStatus.Status.UP_TO_DATE);
+
+			}
+			//
+			// tell the AC that something changed
+			//
+			notifyAC();
+		} catch (PAPException e) {
+			logger.debug("POST exception: " + e, e);
+			response.sendError(500, e.getMessage());
+			return;
+		}
+	}
+
+	
+	/**
+	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
+	 */
+	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+		try {
+			XACMLRest.dumpRequest(request);
+			
+			// Is this from the Admin Console?
+			String groupId = request.getParameter("groupId");
+			if (groupId != null) {
+				// this is from the Admin Console, so handle separately
+				doACGet(request, response, groupId);
+				return;
+			}
+			//
+			// Get the PDP's ID
+			//
+			String id = this.getPDPID(request);
+			logger.info("doGet from: " + id);
+			//
+			// Get the PDP Object
+			//
+			PDP pdp = this.papEngine.getPDP(id);
+			//
+			// Is it known?
+			//
+			if (pdp == null) {
+				//
+				// Check if request came from localhost
+				//
+				String message = "Unknown PDP: " + id + " from " + request.getRemoteHost() + " us: " + request.getLocalAddr();
+				logger.info(message);
+				if (request.getRemoteHost().equals("localhost") ||
+					request.getRemoteHost().equals("127.0.0.1") ||
+					request.getRemoteHost().equals(request.getLocalAddr())) {
+					//
+					// Return status information - basically all the groups
+					//
+					Set<PDPGroup> groups = papEngine.getPDPGroups();
+					
+					// convert response object to JSON and include in the response
+		            ObjectMapper mapper = new ObjectMapper();
+		            mapper.writeValue(response.getOutputStream(),  groups);
+					response.setHeader("content-type", "application/json");
+					response.setStatus(HttpServletResponse.SC_OK);
+					return;
+				}
+				response.sendError(HttpServletResponse.SC_UNAUTHORIZED, message);
+				return;
+			}
+			//
+			// Get the PDP's Group
+			//
+			PDPGroup group = this.papEngine.getPDPGroup(pdp);
+			if (group == null) {
+				String message = "No group associated with pdp " + pdp.getId();
+				logger.warn(message);
+				response.sendError(HttpServletResponse.SC_UNAUTHORIZED, message);
+				return;
+			}
+			//
+			// Which policy do they want?
+			//
+			String policyId = request.getParameter("id");
+			if (policyId == null) {
+				String message = "Did not specify an id for the policy";
+				logger.warn(message);
+				response.sendError(HttpServletResponse.SC_NOT_FOUND, message);
+				return;
+			}
+			PDPPolicy policy = group.getPolicy(policyId);
+			if (policy == null) {
+				String message = "Unknown policy: " + policyId;
+				logger.warn(message);
+				response.sendError(HttpServletResponse.SC_NOT_FOUND, message);
+				return;
+			}
+			//
+			// Get its stream
+			//
+			try (InputStream is = policy.getStream(); OutputStream os = response.getOutputStream()) {
+				//
+				// Send the policy back
+				//
+				IOUtils.copy(is, os);
+				
+				response.setStatus(HttpServletResponse.SC_OK);
+			} catch (PAPException e) {
+				String message = "Failed to open policy id " + policyId;
+				logger.error(message);
+				response.sendError(HttpServletResponse.SC_NOT_FOUND, message);
+			}
+		}  catch (PAPException e) {
+			logger.error("GET exception: " + e, e);
+			response.sendError(500, e.getMessage());
+			return;
+		}
+	}
+
+	protected String	getPDPID(HttpServletRequest request) {
+		String pdpURL = request.getHeader(XACMLRestProperties.PROP_PDP_HTTP_HEADER_ID);
+		if (pdpURL == null || pdpURL.isEmpty()) {
+			//
+			// Should send back its port for identification
+			//
+			logger.warn("PDP did not send custom header");
+			pdpURL = "";
+		}
+		return  pdpURL;
+	}
+	
+	private boolean isPDPCurrent(Properties policies, Properties pipconfig, Properties pdpProperties) {
+		String localRootPolicies = policies.getProperty(XACMLProperties.PROP_ROOTPOLICIES);
+		String localReferencedPolicies = policies.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES);
+		if (localRootPolicies == null || localReferencedPolicies == null) {
+			logger.warn("Missing property on PAP server: RootPolicies="+localRootPolicies+"  ReferencedPolicies="+localReferencedPolicies);
+			return false;
+		}
+		//
+		// Compare the policies and pipconfig properties to the pdpProperties
+		//
+		try {
+			//
+			// the policy properties includes only xacml.rootPolicies and 
+			// xacml.referencedPolicies without any .url entries
+			//
+			Properties pdpPolicies = XACMLProperties.getPolicyProperties(pdpProperties, false);
+			Properties pdpPipConfig = XACMLProperties.getPipProperties(pdpProperties);
+			if (localRootPolicies.equals(pdpPolicies.getProperty(XACMLProperties.PROP_ROOTPOLICIES)) &&
+					localReferencedPolicies.equals(pdpPolicies.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES)) &&
+					pdpPipConfig.equals(pipconfig)) {
+				//
+				// The PDP is current
+				//
+				return true;
+			}
+		} catch (Exception e) {
+			// we get here if the PDP did not include either xacml.rootPolicies or xacml.pip.engines,
+			// or if there are policies that do not have a corresponding ".url" property.
+			// Either of these cases means that the PDP is not up-to-date, so just drop-through to return false.
+		}
+		return false;
+	}
+
+	private void populatePolicyURL(StringBuffer urlPath, Properties policies) {
+		String lists[] = new String[2];
+		lists[0] = policies.getProperty(XACMLProperties.PROP_ROOTPOLICIES);
+		lists[1] = policies.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES);
+		for (String list : lists) {
+			if (list != null && list.isEmpty() == false) {
+				for (String id : Splitter.on(',').trimResults().omitEmptyStrings().split(list)) {
+					String url = urlPath + "?id=" + id;
+					logger.info("Policy URL for " + id + ": " + url);
+					policies.setProperty(id + ".url", url);
+				}
+			}
+		}
+	}
+	
+	
+	/**
+	 * @see HttpServlet#doPut(HttpServletRequest request, HttpServletResponse response)
+	 */
+	protected void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+		XACMLRest.dumpRequest(request);
+		//
+		// since getParameter reads the content string, explicitly get the content before doing that.
+		// Simply getting the inputStream seems to protect it against being consumed by getParameter.
+		//
+		request.getInputStream();
+		//
+		// See if this is Admin Console registering itself with us
+		//
+		String acURLString = request.getParameter("adminConsoleURL");
+		if (acURLString != null) {
+			//
+			// remember this Admin Console for future updates
+			//
+			if ( ! adminConsoleURLStringList.contains(acURLString)) {
+				adminConsoleURLStringList.add(acURLString);
+			}
+			if (logger.isDebugEnabled()) {
+				logger.debug("Admin Console registering with URL: " + acURLString);
+			}
+			response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+			return;
+		}
+		//
+		// Is this some other operation from the Admin Console?
+		//
+		String groupId = request.getParameter("groupId");
+		if (groupId != null) {
+			//
+			// this is from the Admin Console, so handle separately
+			//
+			doACPut(request, response, groupId);
+			return;
+		}
+		//
+		// We do not expect anything from anywhere else.
+		// This method is here in case we ever need to support other operations.
+		//
+		response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Request does not have groupId");
+	}
+	
+	/**
+	 * @see HttpServlet#doDelete(HttpServletRequest request, HttpServletResponse response)
+	 */
+	protected void doDelete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+		XACMLRest.dumpRequest(request);
+		//
+		// Is this from the Admin Console?
+		//
+		String groupId = request.getParameter("groupId");
+		if (groupId != null) {
+			//
+			// this is from the Admin Console, so handle separately
+			//
+			doACDelete(request, response, groupId);
+			return;
+		}
+		//
+		// We do not expect anything from anywhere else.
+		// This method is here in case we ever need to support other operations.
+		//
+		response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Request does not have groupId");
+	}
+	//
+	// Admin Console request handling
+	//
+	
+	/**
+	 * Requests from the Admin Console to GET info about the Groups and PDPs
+	 * 
+	 * @param request
+	 * @param response
+	 * @param groupId
+	 * @throws ServletException
+	 * @throws java.io.IOException
+	 */
+	private void doACGet(HttpServletRequest request, HttpServletResponse response, String groupId) throws ServletException, IOException {
+		try {
+			String parameterDefault = request.getParameter("default");
+			String pdpId = request.getParameter("pdpId");
+			String pdpGroup = request.getParameter("getPDPGroup");
+			if ("".equals(groupId)) {
+				// request IS from AC but does not identify a group by name
+				if (parameterDefault != null) {
+					// Request is for the Default group (whatever its id)
+					PDPGroup group = papEngine.getDefaultGroup();
+					
+					// convert response object to JSON and include in the response
+		            ObjectMapper mapper = new ObjectMapper();
+		            mapper.writeValue(response.getOutputStream(),  group);
+		            
+					if (logger.isDebugEnabled()) {
+						logger.debug("GET Default group req from '" + request.getRequestURL() + "'");
+					}
+					response.setStatus(HttpServletResponse.SC_OK);
+					response.setHeader("content-type", "application/json");
+					response.getOutputStream().close();
+					return;
+					
+				} else if (pdpId != null) {
+					// Request is related to a PDP
+					if (pdpGroup == null) {
+						// Request is for the PDP itself
+						// Request is for the (unspecified) group containing a given PDP
+						PDP pdp = papEngine.getPDP(pdpId);
+						
+						// convert response object to JSON and include in the response
+			            ObjectMapper mapper = new ObjectMapper();
+			            mapper.writeValue(response.getOutputStream(),  pdp);
+			            
+						if (logger.isDebugEnabled()) {
+							logger.debug("GET pdp '" + pdpId + "' req from '" + request.getRequestURL() + "'");
+						}
+						response.setStatus(HttpServletResponse.SC_OK);
+						response.setHeader("content-type", "application/json");
+						response.getOutputStream().close();
+						return;
+					
+					} else {
+						// Request is for the (unspecified) group containing a given PDP
+						PDP pdp = papEngine.getPDP(pdpId);
+						PDPGroup group = papEngine.getPDPGroup(pdp);
+						
+						// convert response object to JSON and include in the response
+			            ObjectMapper mapper = new ObjectMapper();
+			            mapper.writeValue(response.getOutputStream(),  group);
+			            
+						if (logger.isDebugEnabled()) {
+							logger.debug("GET PDP '" + pdpId + "' Group req from '" + request.getRequestURL() + "'");
+						}
+						response.setStatus(HttpServletResponse.SC_OK);
+						response.setHeader("content-type", "application/json");
+						response.getOutputStream().close();
+						return;
+					}
+					
+				} else {
+					// request is for top-level properties about all groups
+					Set<PDPGroup> groups = papEngine.getPDPGroups();
+					
+					// convert response object to JSON and include in the response
+		            ObjectMapper mapper = new ObjectMapper();
+		            mapper.writeValue(response.getOutputStream(),  groups);
+					
+//TODO
+// In "notification" section, ALSO need to tell AC about other changes (made by other ACs)?'
+//TODO add new PDP notification (or just "config changed" notification) in appropriate place
+		            if (logger.isDebugEnabled()) {
+		            	logger.debug("GET All groups req");
+		            }
+					response.setStatus(HttpServletResponse.SC_OK);
+					response.setHeader("content-type", "application/json");
+					response.getOutputStream().close();
+					return;
+				}
+			}
+			
+			// for all other GET operations the group must exist before the operation can be done
+			PDPGroup group = papEngine.getGroup(groupId);
+			if (group == null) {
+				logger.error("Unknown groupId '" + groupId + "'");
+				response.sendError(HttpServletResponse.SC_NOT_FOUND, "Unknown groupId '" + groupId +"'");
+				return;
+			}
+			
+			
+			// Figure out which request this is based on the parameters
+			String policyId = request.getParameter("policyId");
+			
+			if (policyId != null) {
+//				// retrieve a policy
+//				PDPPolicy policy = papEngine.getPDPPolicy(policyId);
+//				
+//				// convert response object to JSON and include in the response
+//	            ObjectMapper mapper = new ObjectMapper();
+//	            mapper.writeValue(response.getOutputStream(),  pdp);
+//	            
+//	        	logger.debug("GET group '" + group.getId() + "' req from '" + request.getRequestURL() + "'");
+//				response.setStatus(HttpServletResponse.SC_OK);
+//				response.setHeader("content-type", "application/json");
+//				response.getOutputStream().close();
+//				return;
+				response.sendError(HttpServletResponse.SC_BAD_REQUEST, "GET Policy not implemented");
+				
+			} else {
+				// No other parameters, so return the identified Group
+				
+				// convert response object to JSON and include in the response
+	            ObjectMapper mapper = new ObjectMapper();
+	            mapper.writeValue(response.getOutputStream(),  group);
+	            
+	            if (logger.isDebugEnabled()) {
+	            	logger.debug("GET group '" + group.getId() + "' req from '" + request.getRequestURL() + "'");
+	            }
+				response.setStatus(HttpServletResponse.SC_OK);
+				response.setHeader("content-type", "application/json");
+				response.getOutputStream().close();
+				return;
+			}
+			
+			//
+			// Currently there are no other GET calls from the AC.
+			// The AC uses the "GET All Groups" operation to fill its local cache and uses that cache for all other GETs without calling the PAP.
+			// Other GETs that could be called:
+			//				Specific Group	(groupId=<groupId>)
+			//				A Policy		(groupId=<groupId> policyId=<policyId>)
+			//				A PDP			(groupId=<groupId> pdpId=<pdpId>)
+		
+	//TODO - implement other GET operations if needed
+	
+			logger.error("UNIMPLEMENTED ");
+			response.sendError(HttpServletResponse.SC_BAD_REQUEST, "UNIMPLEMENTED");
+		} catch (PAPException e) {
+			logger.error("AC Get exception: " + e, e);
+			response.sendError(500, e.getMessage());
+			return;
+		}
+		
+	}
+
+		
+	/**
+	 * Requests from the Admin Console for operations not on single specific objects
+	 * 
+	 * @param request
+	 * @param response
+	 * @param groupId
+	 * @throws ServletException
+	 * @throws java.io.IOException
+	 */
+	private void doACPost(HttpServletRequest request, HttpServletResponse response, String groupId) throws ServletException, IOException {
+		try {
+			String groupName = request.getParameter("groupName");
+			String groupDescription = request.getParameter("groupDescription");
+			if (groupName != null && groupDescription != null) {
+				// Args:	      group=<groupId> groupName=<name> groupDescription=<description>            <= create a new group
+				String unescapedName = URLDecoder.decode(groupName, "UTF-8");
+				String unescapedDescription = URLDecoder.decode(groupDescription, "UTF-8");
+				try {
+					papEngine.newGroup(unescapedName, unescapedDescription);
+				} catch (Exception e) {
+					logger.error("Unable to create new group: " + e.getLocalizedMessage());
+					response.sendError(500, "Unable to create new group '" + groupId + "'");
+					return;
+				}
+				response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+				if (logger.isDebugEnabled()) {
+					logger.debug("New Group '" + groupId + "' created");
+				}
+				// tell the Admin Consoles there is a change
+				notifyAC();
+				// new group by definition has no PDPs, so no need to notify them of changes
+				return;
+			}
+			
+			// for all remaining POST operations the group must exist before the operation can be done
+			PDPGroup group = papEngine.getGroup(groupId);
+			if (group == null) {
+				logger.error("Unknown groupId '" + groupId + "'");
+				response.sendError(HttpServletResponse.SC_NOT_FOUND, "Unknown groupId '" + groupId +"'");
+				return;
+			}
+			
+			// determine the operation needed based on the parameters in the request
+			if (request.getParameter("policyId") != null) {
+				//	Args:        group=<groupId> policy=<policyId>		<= copy file
+				// copy a policy from the request contents into a file in the group's directory on this machine
+				String policyId = request.getParameter("policyId");
+				try {
+					((StdPDPGroup) group).copyPolicyToFile(policyId, request.getInputStream());
+				} catch (Exception e) {
+					String message = "Policy '" + policyId + "' not copied to group '" + groupId +"': " + e;
+					logger.error(message);
+					response.sendError(500, message);
+					return;
+				}
+				// policy file copied ok
+				response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+				if (logger.isDebugEnabled()) {
+					logger.debug("policy '" + policyId + "' copied to directory for group '" + groupId + "'");
+				}
+				return;
+				
+			} else if (request.getParameter("default") != null) {
+				// Args:       group=<groupId> default=true               <= make default
+				// change the current default group to be the one identified in the request.
+				//
+				// This is a POST operation rather than a PUT "update group" because of the side-effect that the current default group is also changed.
+				// It should never be the case that multiple groups are currently marked as the default, but protect against that anyway.
+				try {
+					papEngine.SetDefaultGroup(group);
+				} catch (Exception e) {
+					logger.error("Unable to set group: " + e.getLocalizedMessage());
+					response.sendError(500, "Unable to set group '" + groupId + "' to default");
+					return;
+				}
+				
+				response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+				if (logger.isDebugEnabled()) {
+					logger.debug("Group '" + groupId + "' set to be default");
+				}
+				// Notify the Admin Consoles that something changed
+				// For now the AC cannot handle anything more detailed than the whole set of PDPGroups, so just notify on that
+//TODO - Future: FIGURE OUT WHAT LEVEL TO NOTIFY: 2 groups or entire set - currently notify AC to update whole configuration of all groups
+				notifyAC();
+				// This does not affect any PDPs in the existing groups, so no need to notify them of this change
+				return;
+				
+			} else if (request.getParameter("pdpId") != null) {
+				// Args:       group=<groupId> pdpId=<pdpId>               <= move PDP to group
+				String pdpId = request.getParameter("pdpId");
+				PDP pdp = papEngine.getPDP(pdpId);
+				
+				PDPGroup originalGroup = papEngine.getPDPGroup(pdp);
+				
+				papEngine.movePDP(pdp, group);
+				
+				response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+				if (logger.isDebugEnabled()) {
+					logger.debug("PDP '" + pdp.getId() +"' moved to group '" + group.getId() + "' set to be default");
+				}
+				
+				// update the status of both the original group and the new one
+				((StdPDPGroup)originalGroup).resetStatus();
+				((StdPDPGroup)group).resetStatus();
+				
+				// Notify the Admin Consoles that something changed
+				// For now the AC cannot handle anything more detailed than the whole set of PDPGroups, so just notify on that
+				notifyAC();
+				// Need to notify the PDP that it's config may have changed
+				pdpChanged(pdp);
+				return;
+				
+				
+			}
+		} catch (PAPException e) {
+			logger.error("AC POST exception: " + e, e);
+			response.sendError(500, e.getMessage());
+			return;
+		}
+	}
+
+	/**
+	 * Requests from the Admin Console to create new items or update existing ones
+	 * 
+	 * @param request
+	 * @param response
+	 * @param groupId
+	 * @throws ServletException
+	 * @throws java.io.IOException
+	 */
+	private void doACPut(HttpServletRequest request, HttpServletResponse response, String groupId) throws ServletException, IOException {
+		try {
+			
+			
+			// for PUT operations the group may or may not need to exist before the operation can be done
+			PDPGroup group = papEngine.getGroup(groupId);
+	
+			// determine the operation needed based on the parameters in the request
+
+			// for remaining operations the group must exist before the operation can be done
+			if (group == null) {
+				logger.error("Unknown groupId '" + groupId + "'");
+				response.sendError(HttpServletResponse.SC_NOT_FOUND, "Unknown groupId '" + groupId +"'");
+				return;
+			}
+			if (request.getParameter("policy") != null) {
+	//        group=<groupId> policy=<policyId> contents=policy file               <= Create new policy file in group dir, or replace it if it already exists (do not touch properties)
+	//TODO - currently this is done by the AC, but it should be done here by getting the policy file out of the contents and saving to disk
+				logger.error("PARTIALLY IMPLEMENTED!!!  ACTUAL CHANGES SHOULD BE MADE BY PAP SERVLET!!! ");
+				response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+				return;
+			} else if (request.getParameter("pdpId") != null) {
+				// ARGS:        group=<groupId> pdpId=<pdpId/URL>          <= create a new PDP or Update an Existing one
+				
+				String pdpId = request.getParameter("pdpId");
+				
+            	// get the request content into a String
+            	String json = null;
+    			// read the inputStream into a buffer (trick found online scans entire input looking for end-of-file)
+    		    java.util.Scanner scanner = new java.util.Scanner(request.getInputStream());
+    		    scanner.useDelimiter("\\A");
+    		    json =  scanner.hasNext() ? scanner.next() : "";
+    		    scanner.close();
+    		    logger.info("JSON request from AC: " + json);
+            	
+            	// convert Object sent as JSON into local object
+	            ObjectMapper mapper = new ObjectMapper();
+				
+	            Object objectFromJSON = mapper.readValue(json, StdPDP.class);
+
+				if (pdpId == null ||
+						objectFromJSON == null ||
+						! (objectFromJSON instanceof StdPDP) ||
+						((StdPDP)objectFromJSON).getId() == null ||
+						! ((StdPDP)objectFromJSON).getId().equals(pdpId)) {
+					logger.error("PDP new/update had bad input. pdpId=" + pdpId + " objectFromJSON="+objectFromJSON);
+					response.sendError(500, "Bad input, pdpid="+pdpId+" object="+objectFromJSON);
+				}
+				StdPDP pdp = (StdPDP) objectFromJSON;
+				
+				if (papEngine.getPDP(pdpId) == null) {
+					// this is a request to create a new PDP object
+					papEngine.newPDP(pdp.getId(), group, pdp.getName(), pdp.getDescription());
+				} else {
+					// this is a request to update the pdp
+					papEngine.updatePDP(pdp);
+				}
+
+				response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+				if (logger.isDebugEnabled()) {
+					logger.debug("PDP '" + pdpId + "' created/updated");
+				}
+				
+				// adjust the group's state including the new PDP
+				((StdPDPGroup)group).resetStatus();
+				
+				// tell the Admin Consoles there is a change
+				notifyAC();
+				// this might affect the PDP, so notify it of the change
+				pdpChanged(pdp);
+				return;
+			} else if (request.getParameter("pipId") != null) {
+	//                group=<groupId> pipId=<pipEngineId> contents=pip properties              <= add a PIP to pip config, or replace it if it already exists (lenient operation) 
+	//TODO
+				logger.error("UNIMPLEMENTED ");
+				response.sendError(HttpServletResponse.SC_BAD_REQUEST, "UNIMPLEMENTED");
+				return;
+			} else {
+				// Assume that this is an update of an existing PDP Group
+				// ARGS:        group=<groupId>         <= Update an Existing Group
+								
+            	// get the request content into a String
+            	String json = null;
+    			// read the inputStream into a buffer (trick found online scans entire input looking for end-of-file)
+    		    java.util.Scanner scanner = new java.util.Scanner(request.getInputStream());
+    		    scanner.useDelimiter("\\A");
+    		    json =  scanner.hasNext() ? scanner.next() : "";
+    		    scanner.close();
+    		    logger.info("JSON request from AC: " + json);
+            	
+            	// convert Object sent as JSON into local object
+	            ObjectMapper mapper = new ObjectMapper();
+	            
+	            Object objectFromJSON  = mapper.readValue(json, StdPDPGroup.class);
+
+				if (objectFromJSON == null ||
+						! (objectFromJSON instanceof StdPDPGroup) ||
+						! ((StdPDPGroup)objectFromJSON).getId().equals(group.getId())) {
+					logger.error("Group update had bad input. id=" + group.getId() + " objectFromJSON="+objectFromJSON);
+					response.sendError(500, "Bad input, id="+group.getId() +" object="+objectFromJSON);
+				}
+				
+				// The Path on the PAP side is not carried on the RESTful interface with the AC
+				// (because it is local to the PAP)
+				// so we need to fill that in before submitting the group for update
+				((StdPDPGroup)objectFromJSON).setDirectory(((StdPDPGroup)group).getDirectory());
+
+				papEngine.updateGroup((StdPDPGroup)objectFromJSON);
+
+
+				response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+				if (logger.isDebugEnabled()) {
+					logger.debug("Group '" + group.getId() + "' updated");
+				}
+				// tell the Admin Consoles there is a change
+				notifyAC();
+				// Group changed, which might include changing the policies
+				groupChanged(group);
+				return;
+			}
+		} catch (PAPException e) {
+			logger.error("AC PUT exception: " + e, e);
+			response.sendError(500, e.getMessage());
+			return;
+		}
+	}
+	
+	/**
+	 * Requests from the Admin Console to delete/remove items
+	 * 
+	 * @param request
+	 * @param response
+	 * @param groupId
+	 * @throws ServletException
+	 * @throws java.io.IOException
+	 */
+	private void doACDelete(HttpServletRequest request, HttpServletResponse response, String groupId) throws ServletException, IOException {
+		try {
+			// for all DELETE operations the group must exist before the operation can be done
+			PDPGroup group = papEngine.getGroup(groupId);
+			if (group == null) {
+				logger.error("Unknown groupId '" + groupId + "'");
+				response.sendError(HttpServletResponse.SC_NOT_FOUND, "Unknown groupId '" + groupId +"'");
+				return;
+			}
+			// determine the operation needed based on the parameters in the request
+			if (request.getParameter("policy") != null) {
+	//        group=<groupId> policy=<policyId>  [delete=<true|false>]       <= delete policy file from group
+	//TODO
+				logger.error("UNIMPLEMENTED ");
+				response.sendError(HttpServletResponse.SC_BAD_REQUEST, "UNIMPLEMENTED");
+				return;
+			} else if (request.getParameter("pdpId") != null) {
+				// ARGS:        group=<groupId> pdpId=<pdpId>                  <= delete PDP 
+				String pdpId = request.getParameter("pdpId");
+				PDP pdp = papEngine.getPDP(pdpId);
+				
+				papEngine.removePDP(pdp);
+				
+				// adjust the status of the group, which may have changed when we removed this PDP
+				((StdPDPGroup)group).resetStatus();
+				
+				response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+				notifyAC();
+
+				// update the PDP and tell it that it has NO Policies (which prevents it from serving PEP Requests)
+				pdpChanged(pdp);
+				return;
+			} else if (request.getParameter("pipId") != null) {
+	//        group=<groupId> pipId=<pipEngineId> <= delete PIP config for given engine
+	//TODO
+				logger.error("UNIMPLEMENTED ");
+				response.sendError(HttpServletResponse.SC_BAD_REQUEST, "UNIMPLEMENTED");
+				return;
+			} else {
+				// ARGS:      group=<groupId> movePDPsToGroupId=<movePDPsToGroupId>            <= delete a group and move all its PDPs to the given group
+				String moveToGroupId = request.getParameter("movePDPsToGroupId");
+				PDPGroup moveToGroup = null;
+				if (moveToGroupId != null) {
+					moveToGroup = papEngine.getGroup(moveToGroupId);
+				}
+				
+				// get list of PDPs in the group being deleted so we can notify them that they got changed
+				Set<PDP> movedPDPs = new HashSet<PDP>();
+				movedPDPs.addAll(group.getPdps());
+				
+				// do the move/remove
+				papEngine.removeGroup(group, moveToGroup);
+				
+				response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+				notifyAC();
+				// notify any PDPs in the removed set that their config may have changed
+				for (PDP pdp : movedPDPs) {
+					pdpChanged(pdp);
+				}
+				return;
+			}
+
+		} catch (PAPException e) {
+			logger.error("AC DELETE exception: " + e, e);
+			response.sendError(500, e.getMessage());
+			return;
+		}
+	}
+
+	//
+	// Heartbeat thread - periodically check on PDPs' status
+	//
+	
+	/**
+	 * Heartbeat with all known PDPs.
+	 * 
+	 * Implementation note:
+	 * 
+	 * The PDPs are contacted Sequentially, not in Parallel.
+	 * 
+	 * If we did this in parallel using multiple threads we would simultaneously use
+	 * 		- 1 thread and
+	 * 		- 1 connection
+	 * for EACH PDP.
+	 * This could become a resource problem since we already use multiple threads and connections for updating the PDPs
+	 * when user changes occur.
+	 * Using separate threads can also make it tricky dealing with timeouts on PDPs that are non-responsive.
+	 * 
+	 * The Sequential operation does a heartbeat request to each PDP one at a time.
+	 * This has the flaw that any PDPs that do not respond will hold up the entire heartbeat sequence until they timeout.
+	 * If there are a lot of non-responsive PDPs and the timeout is large-ish (the default is 20 seconds)
+	 * it could take a long time to cycle through all of the PDPs.
+	 * That means that this may not notice a PDP being down in a predictable time.
+	 * 
+	 * @author glenngriffin
+	 *
+	 */
+	private class Heartbeat implements Runnable {
+		private PAPEngine papEngine;
+		private Set<PDP> pdps = new HashSet<PDP>();
+		private int heartbeatInterval;
+		private int heartbeatTimeout;
+		
+		public volatile boolean isRunning = false;
+		
+		public synchronized boolean isRunning() {
+			return this.isRunning;
+		}
+		
+		public synchronized void terminate() {
+			this.isRunning = false;
+		}
+		
+		public Heartbeat(PAPEngine engine) {
+			this.papEngine = engine;
+			this.heartbeatInterval = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_HEARTBEAT_INTERVAL, "10000"));
+			this.heartbeatTimeout = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_HEARTBEAT_TIMEOUT, "10000"));
+		}
+
+		@Override
+		public void run() {
+			//
+			// Set ourselves as running
+			//
+			synchronized(this) {
+				this.isRunning = true;
+			}
+			HashMap<String, URL> idToURLMap = new HashMap<String, URL>();
+			try {
+				while (this.isRunning()) {
+					// Wait the given time
+					Thread.sleep(heartbeatInterval);
+					
+					// get the list of PDPs (may have changed since last time)
+					pdps.clear();
+					synchronized(papEngine) {
+						try {
+							for (PDPGroup g : papEngine.getPDPGroups()) {
+								for (PDP p : g.getPdps()) {
+									pdps.add(p);
+								}
+							}
+						} catch (PAPException e) {
+							logger.error("Heartbeat unable to read PDPs from PAPEngine: " + e.getMessage(), e);
+						}
+					}
+					//
+					// Check for shutdown
+					//
+					if (this.isRunning() == false) {
+						logger.info("isRunning is false, getting out of loop.");
+						break;
+					}
+					
+					// try to get the summary status from each PDP
+					boolean changeSeen = false;
+					for (PDP pdp : pdps) {
+						//
+						// Check for shutdown
+						//
+						if (this.isRunning() == false) {
+							logger.info("isRunning is false, getting out of loop.");
+							break;
+						}
+						// the id of the PDP is its url (though we add a query parameter)
+						URL pdpURL = idToURLMap.get(pdp.getId());
+						if (pdpURL == null) {
+							// haven't seen this PDP before
+							String fullURLString = null;
+							try {
+								fullURLString = pdp.getId() + "?type=hb";
+								pdpURL = new URL(fullURLString);
+								idToURLMap.put(pdp.getId(), pdpURL);
+							} catch (MalformedURLException e) {
+								logger.error("PDP id '" + fullURLString + "' is not a valid URL: " + e, e);
+								continue;
+							}
+						}
+						
+						// Do a GET with type HeartBeat
+						String newStatus = "";
+						
+						HttpURLConnection connection = null;
+						try {
+
+							//
+							// Open up the connection
+							//
+							connection = (HttpURLConnection)pdpURL.openConnection();
+							//
+							// Setup our method and headers
+							//
+				            connection.setRequestMethod("GET");
+				            connection.setConnectTimeout(heartbeatTimeout);
+				            //
+				            // Do the connect
+				            //
+				            connection.connect();
+				            if (connection.getResponseCode() == 204) {
+				            	newStatus = connection.getHeaderField(XACMLRestProperties.PROP_PDP_HTTP_HEADER_HB);
+								if (logger.isDebugEnabled()) {
+									logger.debug("Heartbeat '" + pdp.getId() + "' status='" + newStatus + "'");
+								}
+				            } else {
+				            	// anything else is an unexpected result
+				            	newStatus = PDPStatus.Status.UNKNOWN.toString();
+				            	logger.error("Heartbeat connect response code " + connection.getResponseCode() + ": " + pdp.getId());
+				            }
+			            } catch (UnknownHostException e) {
+			            	newStatus = PDPStatus.Status.NO_SUCH_HOST.toString();
+			            	logger.error("Heartbeat '" + pdp.getId() + "' NO_SUCH_HOST");
+						} catch (SocketTimeoutException e) {
+			            	newStatus = PDPStatus.Status.CANNOT_CONNECT.toString();
+			            	logger.error("Heartbeat '" + pdp.getId() + "' connection timeout: " + e );
+						} catch (ConnectException e) {
+			            	newStatus = PDPStatus.Status.CANNOT_CONNECT.toString();
+			            	logger.error("Heartbeat '" + pdp.getId() + "' cannot connect: " + e );
+						} catch (Exception e) {
+			            	newStatus = PDPStatus.Status.UNKNOWN.toString();
+			            	logger.error("Heartbeat '" + pdp.getId() + "' connect exception: " + e, e);
+						} finally {
+							// cleanup the connection
+							connection.disconnect();
+						}
+
+						if ( ! pdp.getStatus().getStatus().toString().equals(newStatus)) {
+							if (logger.isDebugEnabled()) {
+								logger.debug("previous status='" + pdp.getStatus().getStatus()+"'  new Status='" + newStatus + "'");
+							}
+			            	try {
+								setPDPSummaryStatus(pdp, newStatus);
+							} catch (PAPException e) {
+								logger.error("Unable to set state for PDP '" + pdp.getId() + "': " + e, e);
+							}
+							changeSeen = true;
+						}
+						
+					}
+					//
+					// Check for shutdown
+					//
+					if (this.isRunning() == false) {
+						logger.info("isRunning is false, getting out of loop.");
+						break;
+					}
+
+					// if any of the PDPs changed state, tell the ACs to update
+					if (changeSeen) {
+						notifyAC();
+					}
+					
+				}
+			} catch (InterruptedException e) {
+				logger.error("Heartbeat interrupted.  Shutting down");
+				this.terminate();
+			}
+		}
+	}
+	
+	
+	//
+	// HELPER to change Group status when PDP status is changed
+	//
+	// (Must NOT be called from a method that is synchronized on the papEngine or it may deadlock)
+	//
+	
+	private void setPDPSummaryStatus(PDP pdp, PDPStatus.Status newStatus) throws PAPException {
+		setPDPSummaryStatus(pdp, newStatus.toString());
+	}
+
+	private void setPDPSummaryStatus(PDP pdp, String newStatus) throws PAPException {
+    	synchronized(papEngine) {
+    		StdPDPStatus status = (StdPDPStatus)pdp.getStatus();
+    		status.setStatus(PDPStatus.Status.valueOf(newStatus));
+    		((StdPDP)pdp).setStatus(status);
+    		
+    		// now adjust the group
+    		StdPDPGroup group = (StdPDPGroup)papEngine.getPDPGroup(pdp);
+    		// if the PDP was just deleted it may transiently exist but not be in a group
+    		if (group != null) {
+    			group.resetStatus();
+    		}
+    	}
+	}
+	
+	
+	//
+	// Callback methods telling this servlet to notify PDPs of changes made by the PAP StdEngine
+	//	in the PDP group directories
+	//
+	
+	@Override
+	public void changed() {
+		// all PDPs in all groups need to be updated/sync'd
+		Set<PDPGroup> groups;
+		try {
+			groups = papEngine.getPDPGroups();
+		} catch (PAPException e) {
+			logger.error("getPDPGroups failed: " + e.getLocalizedMessage());
+			throw new RuntimeException("Unable to get Groups: " + e);
+		}
+		for (PDPGroup group : groups) {
+			groupChanged(group);
+		}
+	}
+
+	@Override
+	public void groupChanged(PDPGroup group) {
+		// all PDPs within one group need to be updated/sync'd
+		for (PDP pdp : group.getPdps()) {
+			pdpChanged(pdp);
+		}
+	}
+
+	@Override
+	public void pdpChanged(PDP pdp) {
+		// kick off a thread to do an event notification for each PDP.
+		// This needs to be on a separate thread so that PDPs that do not respond (down, non-existent, etc)
+		// do not block the PSP response to the AC, which would freeze the GUI until all PDPs sequentially respond or time-out.
+		Thread t = new Thread(new UpdatePDPThread(pdp));
+		t.start();
+	}
+	
+	private class UpdatePDPThread implements Runnable {
+		private PDP pdp;
+
+		// remember which PDP to notify
+		public UpdatePDPThread(PDP pdp) {
+			this.pdp = pdp;
+		}
+
+		public void run() {
+			// send the current configuration to one PDP
+			HttpURLConnection connection = null;
+			try {
+				
+				//
+				// the Id of the PDP is its URL
+				//
+				if (logger.isDebugEnabled()) {
+					logger.debug("creating url for id '" + pdp.getId() + "'");
+				}
+	//TODO - currently always send both policies and pips.  Do we care enough to add code to allow sending just one or the other?
+	//TODO		(need to change "cache=", implying getting some input saying which to change)
+				URL url = new URL(pdp.getId() + "?cache=all");
+				
+				//
+				// Open up the connection
+				//
+				connection = (HttpURLConnection)url.openConnection();
+				//
+				// Setup our method and headers
+				//
+	            connection.setRequestMethod("PUT");
+	//			connection.setRequestProperty("Accept", "text/x-java-properties");
+	            connection.setRequestProperty("Content-Type", "text/x-java-properties");
+	//            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.
+	            //
+	//TODO - is this needed for a PUT?  seems better to leave in for now?
+//	            connection.setInstanceFollowRedirects(false);
+	            //
+	            // PLD - MUST be able to handle re-directs.
+	            //
+	            connection.setInstanceFollowRedirects(true);
+				connection.setDoOutput(true);
+	//			connection.setDoInput(true);
+	    		try (OutputStream os = connection.getOutputStream()) {
+	
+	    			PDPGroup group = papEngine.getPDPGroup(pdp);
+	    			// if the PDP was just deleted, there is no group, but we want to send an update anyway
+	    			if (group == null) {
+	    				// create blank properties files
+	    				Properties policyProperties = new Properties();
+	    				policyProperties.put(XACMLProperties.PROP_ROOTPOLICIES, "");
+	    				policyProperties.put(XACMLProperties.PROP_REFERENCEDPOLICIES, "");
+	    				policyProperties.store(os, "");
+	    				
+	    				Properties pipProps = new Properties();
+						pipProps.setProperty(XACMLProperties.PROP_PIP_ENGINES, "");
+						pipProps.store(os, "");
+	    				
+	    			} else {
+	    				// send properties from the current group
+		    			group.getPolicyProperties().store(os, "");
+		    			Properties policyLocations = new Properties();
+		    			for (PDPPolicy policy : group.getPolicies()) {
+						   policyLocations.put(policy.getId() + ".url", XACMLPapServlet.papURL + "?id=" + policy.getId());
+		    			}
+		    			policyLocations.store(os, "");
+		    			group.getPipConfigProperties().store(os, "");
+	    			}
+		
+	    		} catch (Exception e) {
+	    			logger.error("Failed to send property file to " + pdp.getId(), e);
+	    			// Since this is a server-side error, it probably does not reflect a problem on the client,
+	    			// so do not change the PDP status.
+	    			return;
+	    		}
+	            //
+	            // Do the connect
+	            //
+	            connection.connect();
+	            if (connection.getResponseCode() == 204) {
+	            	logger.info("Success. We are configured correctly.");
+					setPDPSummaryStatus(pdp, PDPStatus.Status.UP_TO_DATE);
+	            } else if (connection.getResponseCode() == 200) {
+	            	logger.info("Success. PDP needs to update its configuration.");
+					setPDPSummaryStatus(pdp, PDPStatus.Status.OUT_OF_SYNCH);
+	            } else {
+	            	logger.warn("Failed: " + connection.getResponseCode() + "  message: " + connection.getResponseMessage());
+					setPDPSummaryStatus(pdp, PDPStatus.Status.UNKNOWN);
+	            }
+			} catch (Exception e) {
+				logger.error("Unable to sync config with PDP '" + pdp.getId() + "': " + e, e);
+				try {
+					setPDPSummaryStatus(pdp, PDPStatus.Status.UNKNOWN);
+				} catch (PAPException e1) {
+					logger.error("Unable to set status of PDP '" + pdp.getId() + "' to UNKNOWN: " + e, e);
+				}
+			} finally {
+				// cleanup the connection
+				connection.disconnect();
+				
+	            // tell the AC to update it's status info
+	            notifyAC();
+			}
+			
+		}
+	}
+
+	//
+	// RESTful Interface from PAP to ACs notifying them of changes
+	//
+	
+	private void notifyAC() {
+		// kick off a thread to do one event notification for all registered ACs
+		// This needs to be on a separate thread so that ACs can make calls back to PAP to get the updated Group data
+		// as part of processing this message on their end.
+		Thread t = new Thread(new NotifyACThread());
+		t.start();
+	}
+	
+	private class NotifyACThread implements Runnable {
+	
+		public void run() {
+			List<String> disconnectedACs = new ArrayList<String>();
+// logger.debug("LIST SIZE="+adminConsoleURLStringList.size());
+			
+			// There should be no Concurrent exception here because the list is a CopyOnWriteArrayList.
+			// The "for each" loop uses the collection's iterator under the covers, so it should be correct.
+			for (String acURL : adminConsoleURLStringList) {
+				HttpURLConnection connection = null;
+				try {
+					
+					acURL += "?PAPNotification=true";
+					
+//TODO - Currently we just tell AC that "Something changed" without being specific.  Do we want to tell it which group/pdp changed?
+//TODO - If so, put correct parameters into the Query string here
+					acURL += "&objectType=all" + "&action=update";
+	
+					if (logger.isDebugEnabled()) {
+						logger.debug("creating url for id '" + acURL + "'");
+					}
+//TODO - currently always send both policies and pips.  Do we care enough to add code to allow sending just one or the other?
+//TODO		(need to change "cache=", implying getting some input saying which to change)
+					
+					URL url = new URL(acURL );
+					
+					//
+					// Open up the connection
+					//
+					connection = (HttpURLConnection)url.openConnection();
+					//
+					// Setup our method and headers
+					//
+		            connection.setRequestMethod("PUT");
+		            connection.setRequestProperty("Content-Type", "text/x-java-properties");
+		            //
+		            // 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.
+		            //
+		//TODO - is this needed for a PUT?  seems better to leave in for now?
+		            connection.setInstanceFollowRedirects(false);
+					//
+					// Do not include any data in the PUT because this is just a
+					// notification to the AC.
+					// The AC will use GETs back to the PAP to get what it needs
+					// to fill in the screens.
+					//
+					
+		            //
+		            // Do the connect
+		            //
+		            connection.connect();
+		            if (connection.getResponseCode() == 204) {
+		            	logger.info("Success. We updated correctly.");
+		            } else {
+		            	logger.warn("Failed: " + connection.getResponseCode() + "  message: " + connection.getResponseMessage());
+		            }
+					
+				} catch (Exception e) {
+					logger.error("Unable to sync config AC '" + acURL + "': " + e, e);
+					disconnectedACs.add(acURL);
+				} finally {
+					// cleanup the connection
+					connection.disconnect();
+				}
+			}
+			
+			// remove any ACs that are no longer connected
+			if (disconnectedACs.size() > 0) {
+				adminConsoleURLStringList.removeAll(disconnectedACs);
+			}
+
+		}
+	}
+
+}
diff --git a/openaz-xacml-pap-rest/src/main/resources/log4j.properties b/openaz-xacml-pap-rest/src/main/resources/log4j.properties
new file mode 100755
index 0000000..b45fa2f
--- /dev/null
+++ b/openaz-xacml-pap-rest/src/main/resources/log4j.properties
@@ -0,0 +1,22 @@
+#
+# Use this properties for debugging and development.
+#
+#
+# Set root logger level to DEBUG and its only appender to A1.
+log4j.rootLogger=DEBUG, MAIN_LOG
+
+# A1 is set to be a ConsoleAppender.
+log4j.appender.MAIN_LOG=org.apache.log4j.ConsoleAppender
+
+# A1 uses PatternLayout.
+log4j.appender.MAIN_LOG.layout=org.apache.log4j.PatternLayout
+log4j.appender.MAIN_LOG.layout.ConversionPattern=%d{yyyy_MM_dd_HH_mm_ss_SSS} [%t] %-5p %l- %m%n
+
+#
+# This is specifically for Xacml request/response logging
+#
+log4j.logger.xacml.request=INFO, REQUEST_LOG
+
+log4j.appender.REQUEST_LOG=org.apache.log4j.ConsoleAppender
+log4j.appender.REQUEST_LOG.layout=org.apache.log4j.PatternLayout
+log4j.appender.REQUEST_LOG.layout.ConversionPattern=%d{yyyy_MM_dd_HH_mm_ss_SSS} %m%n
\ No newline at end of file
diff --git a/openaz-xacml-pap-rest/target/classes/com/att/research/xacml/rest/XACMLPapServlet$1.class b/openaz-xacml-pap-rest/target/classes/com/att/research/xacml/rest/XACMLPapServlet$1.class
new file mode 100644
index 0000000..352e4c6
--- /dev/null
+++ b/openaz-xacml-pap-rest/target/classes/com/att/research/xacml/rest/XACMLPapServlet$1.class
Binary files differ
diff --git a/openaz-xacml-pap-rest/target/classes/com/att/research/xacml/rest/XACMLPapServlet$Heartbeat.class b/openaz-xacml-pap-rest/target/classes/com/att/research/xacml/rest/XACMLPapServlet$Heartbeat.class
new file mode 100644
index 0000000..aac4b91
--- /dev/null
+++ b/openaz-xacml-pap-rest/target/classes/com/att/research/xacml/rest/XACMLPapServlet$Heartbeat.class
Binary files differ
diff --git a/openaz-xacml-pap-rest/target/classes/com/att/research/xacml/rest/XACMLPapServlet$NotifyACThread.class b/openaz-xacml-pap-rest/target/classes/com/att/research/xacml/rest/XACMLPapServlet$NotifyACThread.class
new file mode 100644
index 0000000..3d756fd
--- /dev/null
+++ b/openaz-xacml-pap-rest/target/classes/com/att/research/xacml/rest/XACMLPapServlet$NotifyACThread.class
Binary files differ
diff --git a/openaz-xacml-pap-rest/target/classes/com/att/research/xacml/rest/XACMLPapServlet$UpdatePDPThread.class b/openaz-xacml-pap-rest/target/classes/com/att/research/xacml/rest/XACMLPapServlet$UpdatePDPThread.class
new file mode 100644
index 0000000..ffd1592
--- /dev/null
+++ b/openaz-xacml-pap-rest/target/classes/com/att/research/xacml/rest/XACMLPapServlet$UpdatePDPThread.class
Binary files differ
diff --git a/openaz-xacml-pap-rest/target/classes/com/att/research/xacml/rest/XACMLPapServlet.class b/openaz-xacml-pap-rest/target/classes/com/att/research/xacml/rest/XACMLPapServlet.class
new file mode 100644
index 0000000..d8d63b5
--- /dev/null
+++ b/openaz-xacml-pap-rest/target/classes/com/att/research/xacml/rest/XACMLPapServlet.class
Binary files differ
diff --git a/openaz-xacml-pap-rest/target/classes/log4j.properties b/openaz-xacml-pap-rest/target/classes/log4j.properties
new file mode 100644
index 0000000..b45fa2f
--- /dev/null
+++ b/openaz-xacml-pap-rest/target/classes/log4j.properties
@@ -0,0 +1,22 @@
+#
+# Use this properties for debugging and development.
+#
+#
+# Set root logger level to DEBUG and its only appender to A1.
+log4j.rootLogger=DEBUG, MAIN_LOG
+
+# A1 is set to be a ConsoleAppender.
+log4j.appender.MAIN_LOG=org.apache.log4j.ConsoleAppender
+
+# A1 uses PatternLayout.
+log4j.appender.MAIN_LOG.layout=org.apache.log4j.PatternLayout
+log4j.appender.MAIN_LOG.layout.ConversionPattern=%d{yyyy_MM_dd_HH_mm_ss_SSS} [%t] %-5p %l- %m%n
+
+#
+# This is specifically for Xacml request/response logging
+#
+log4j.logger.xacml.request=INFO, REQUEST_LOG
+
+log4j.appender.REQUEST_LOG=org.apache.log4j.ConsoleAppender
+log4j.appender.REQUEST_LOG.layout=org.apache.log4j.PatternLayout
+log4j.appender.REQUEST_LOG.layout.ConversionPattern=%d{yyyy_MM_dd_HH_mm_ss_SSS} %m%n
\ No newline at end of file
diff --git a/openaz-xacml-pap-rest/target/maven-archiver/pom.properties b/openaz-xacml-pap-rest/target/maven-archiver/pom.properties
new file mode 100644
index 0000000..022f696
--- /dev/null
+++ b/openaz-xacml-pap-rest/target/maven-archiver/pom.properties
@@ -0,0 +1,5 @@
+#Generated by Maven
+#Tue Apr 07 07:42:37 EDT 2015
+version=0.0.1-SNAPSHOT
+groupId=org.openliberty.openaz
+artifactId=openaz-xacml-pap-rest
diff --git a/openaz-xacml-pap-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/openaz-xacml-pap-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
new file mode 100644
index 0000000..4cfb3ef
--- /dev/null
+++ b/openaz-xacml-pap-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
@@ -0,0 +1,5 @@
+com/att/research/xacml/rest/XACMLPapServlet$Heartbeat.class
+com/att/research/xacml/rest/XACMLPapServlet$1.class
+com/att/research/xacml/rest/XACMLPapServlet.class
+com/att/research/xacml/rest/XACMLPapServlet$UpdatePDPThread.class
+com/att/research/xacml/rest/XACMLPapServlet$NotifyACThread.class
diff --git a/openaz-xacml-pap-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/openaz-xacml-pap-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
new file mode 100644
index 0000000..9a51391
--- /dev/null
+++ b/openaz-xacml-pap-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
@@ -0,0 +1 @@
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pap-rest/src/main/java/com/att/research/xacml/rest/XACMLPapServlet.java
diff --git a/openaz-xacml-pap-rest/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/openaz-xacml-pap-rest/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/openaz-xacml-pap-rest/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
diff --git a/openaz-xacml-pap-rest/target/openaz-xacml-pap-rest-0.0.1-SNAPSHOT.jar b/openaz-xacml-pap-rest/target/openaz-xacml-pap-rest-0.0.1-SNAPSHOT.jar
new file mode 100644
index 0000000..d8cdce7
--- /dev/null
+++ b/openaz-xacml-pap-rest/target/openaz-xacml-pap-rest-0.0.1-SNAPSHOT.jar
Binary files differ
diff --git a/openaz-xacml-pap-rest/xacml.pap.properties b/openaz-xacml-pap-rest/xacml.pap.properties
new file mode 100755
index 0000000..05fc0c5
--- /dev/null
+++ b/openaz-xacml-pap-rest/xacml.pap.properties
@@ -0,0 +1,35 @@
+#
+# This is our factory that will create our engine
+#
+xacml.PAP.papEngineFactory=com.att.research.xacml.std.pap.StdEngineFactory
+
+#
+# Where we store our PAP PDP Group/Node information
+#
+xacml.pap.pdps=pdps
+#
+# Need the PAP's url (how PDPs will reach it) configured here
+# because we need it to generate the URLs of the Policy Files
+# sent to the PDPs in the configuration when the PAP is first brought up.
+# (In other cases, such as the PDP calling the PAP, we could generate this URL, 
+# but for startup there is no other way to get it.)
+#
+#
+xacml.rest.pap.url=http://localhost:9090/pap/
+
+#
+# Upon startup, have the PAP servlet send latest configuration information to all
+# the PDP nodes it knows about.
+#
+xacml.rest.pap.initiate.pdp=true
+#
+# Heartbeat from PAP to PDPs
+#
+# How much time (in milliseconds) between heartbeats
+# (i.e. the time between completing the heartbeat with all PDPs and starting the next cycle)
+#
+xacml.rest.pap.heartbeat.interval=10000
+#
+# Heartbeat connection timeout (in milliseconds)
+#
+xacml.rest.pap.heartbeat.timeout=10000
\ No newline at end of file
diff --git a/openaz-xacml-pdp-rest/WebContent/META-INF/MANIFEST.MF b/openaz-xacml-pdp-rest/WebContent/META-INF/MANIFEST.MF
new file mode 100755
index 0000000..58630c0
--- /dev/null
+++ b/openaz-xacml-pdp-rest/WebContent/META-INF/MANIFEST.MF
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0

+

diff --git a/openaz-xacml-pdp-rest/WebContent/WEB-INF/lib/sqljdbc4.jar b/openaz-xacml-pdp-rest/WebContent/WEB-INF/lib/sqljdbc4.jar
new file mode 100755
index 0000000..d6b7f6d
--- /dev/null
+++ b/openaz-xacml-pdp-rest/WebContent/WEB-INF/lib/sqljdbc4.jar
Binary files differ
diff --git a/openaz-xacml-pdp-rest/config/xacml.pip.properties b/openaz-xacml-pdp-rest/config/xacml.pip.properties
new file mode 100755
index 0000000..0c16eb3
--- /dev/null
+++ b/openaz-xacml-pdp-rest/config/xacml.pip.properties
@@ -0,0 +1,219 @@
+# PIP Engine Definition
+#
+xacml.pip.engines=csv1,csv2,hyper1,sql1,ldap1
+
+csv1.classname=com.att.research.xacml.std.pip.engines.csv.CSVEngine
+csv1.name=Master
+csv1.description=Sean Lahman Basebase stats - Player names, DOB, and biographical info
+csv1.issuer=com:att:research:xacml:test:csv
+csv1.source=../XACML-TEST/testsets/pip/configurable-csv/adminDB/Master.txt
+csv1.maxsize=4000000
+csv1.delimiter=,
+csv1.quote="
+csv1.skip=0
+
+csv1.resolvers=data
+
+csv1.resolver.data.classname=com.att.research.xacml.std.pip.engines.csv.ConfigurableCSVResolver
+csv1.resolver.data.name=Player Resolver
+csv1.resolver.data.description=This resolver finds player information in the Master table.
+csv1.resolver.data.fields=firstname,lastname,deathyear,deathmonth,deathday,debut,finalgame
+csv1.resolver.data.field.firstname.column=16
+csv1.resolver.data.field.firstname.id=com:att:research:xacml:test:csv:subject:firstname
+csv1.resolver.data.field.firstname.datatype=http://www.w3.org/2001/XMLSchema#string
+csv1.resolver.data.field.firstname.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.lastname.column=17
+csv1.resolver.data.field.lastname.id=com:att:research:xacml:test:csv:subject:lastname
+csv1.resolver.data.field.lastname.datatype=http://www.w3.org/2001/XMLSchema#string
+csv1.resolver.data.field.lastname.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.deathyear.column=10
+csv1.resolver.data.field.deathyear.id=com:att:research:xacml:test:csv:subject:deathyear
+csv1.resolver.data.field.deathyear.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv1.resolver.data.field.deathyear.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.deathmonth.column=11
+csv1.resolver.data.field.deathmonth.id=com:att:research:xacml:test:csv:subject:deathmonth
+csv1.resolver.data.field.deathmonth.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv1.resolver.data.field.deathmonth.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.deathday.column=12
+csv1.resolver.data.field.deathday.id=com:att:research:xacml:test:csv:subject:deathday
+csv1.resolver.data.field.deathday.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv1.resolver.data.field.deathday.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.debut.column=25
+csv1.resolver.data.field.debut.id=com:att:research:xacml:test:csv:subject:debut
+csv1.resolver.data.field.debut.datatype=http://www.w3.org/2001/XMLSchema#date
+csv1.resolver.data.field.debut.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.finalgame.column=26
+csv1.resolver.data.field.finalgame.id=com:att:research:xacml:test:csv:subject:finalgame
+csv1.resolver.data.field.finalgame.datatype=http://www.w3.org/2001/XMLSchema#date
+csv1.resolver.data.field.finalgame.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.parameters=playerid
+csv1.resolver.data.parameter.playerid.column=1
+csv1.resolver.data.parameter.playerid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id
+csv1.resolver.data.parameter.playerid.datatype=http://www.w3.org/2001/XMLSchema#string
+csv1.resolver.data.parameter.playerid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv2.classname=com.att.research.xacml.std.pip.engines.csv.CSVEngine
+csv2.name=Appearances
+csv2.description=Sean Lahman Basebase stats - Player appearances for a team in a given year.
+#csv2.issuer=
+csv2.source=../XACML-TEST/testsets/pip/configurable-csv/adminDB/Appearances.txt
+csv2.maxsize=4000000
+csv2.delimiter=,
+csv2.quote="
+csv2.skip=0
+
+csv2.resolvers=data
+
+csv2.resolver.data.classname=com.att.research.xacml.std.pip.engines.csv.ConfigurableCSVResolver
+csv2.resolver.data.name=Appearance Resolver
+csv2.resolver.data.description=This resolver returns all the appearances for a player from the appearance table.
+csv2.resolver.data.fields=appearance
+csv2.resolver.data.field.appearance.column=0
+csv2.resolver.data.field.appearance.id=com:att:research:xacml:test:csv:subject:appearance
+csv2.resolver.data.field.appearance.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv2.resolver.data.field.appearance.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+csv2.resolver.data.field.appearance.issuer=com:att:research:xacml:test:csv
+
+csv2.resolver.data.parameters=playerid
+csv2.resolver.data.parameter.playerid.column=3
+csv2.resolver.data.parameter.playerid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id
+csv2.resolver.data.parameter.playerid.datatype=http://www.w3.org/2001/XMLSchema#string
+csv2.resolver.data.parameter.playerid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+#csv1.resolver.data.parameter.playerid.issuer=
+
+hyper1.classname=com.att.research.xacml.std.pip.engines.csv.HyperCSVEngine
+hyper1.name=World Marriage Age Limits
+hyper1.description=Minimum age for female/male marriages with or without their parental consent.
+hyper1.source=../XACML-TEST/testsets/pip/configurable-csv-hyper/marriage.csv
+hyper1.target=marriage
+hyper1.definition=country VARCHAR(80) PRIMARY KEY, wofemale INT, womale INT, wfemale INT, wmale INT, year INT, source VARCHAR(20)
+
+hyper1.resolvers=age_consent
+
+hyper1.resolver.age_consent.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver
+hyper1.resolver.age_consent.name=Ages
+hyper1.resolver.age_consent.description=This returns all the age's for consent or no consent for a country.
+hyper1.resolver.age_consent.select=SELECT wofemale,womale,wfemale,wmale FROM marriage WHERE country=?
+hyper1.resolver.age_consent.fields=wofemale,womale,wfemale,wmale
+
+hyper1.resolver.age_consent.field.wofemale.id=com:att:research:xacml:test:csv:country:no-consent:female
+hyper1.resolver.age_consent.field.wofemale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.wofemale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.wofemale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.field.womale.id=com:att:research:xacml:test:csv:country:no-consent:male
+hyper1.resolver.age_consent.field.womale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.womale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.womale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.field.wfemale.id=com:att:research:xacml:test:csv:country:consent:female
+hyper1.resolver.age_consent.field.wfemale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.wfemale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.wfemale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.field.wmale.id=com:att:research:xacml:test:csv:country:consent:male
+hyper1.resolver.age_consent.field.wmale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.wmale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.wmale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.parameters=country
+hyper1.resolver.age_consent.parameter.country.id=com:att:research:xacml:test:csv:country:name
+hyper1.resolver.age_consent.parameter.country.datatype=http://www.w3.org/2001/XMLSchema#string
+hyper1.resolver.age_consent.parameter.country.category=com:att:research:xacml:test:csv:category:country
+#hyper1.resolver.age_consent.parameter.country.issuer=
+
+sql1.classname=com.att.research.xacml.std.pip.engines.jdbc.JDBCEngine
+sql1.name=World
+sql1.description=World Database from MySQL website. Copyright Statistics Finland, http://www.stat.fi/worldinfigures.
+# This will be the default issuer for the resolvers. NOTE: Issuer only used for attributes provided by the engine.
+sql1.issuer=com:att:research:xacml:test:sql
+#
+# This is the configuration for JDBC. You will have to setup the database and run the data\world*.sql script to
+# create the tables and load the data. 
+#
+sql1.type=jdbc
+sql1.jdbc.driver=org.postgresql.Driver
+sql1.jdbc.url=jdbc:postgresql://localhost:5432/world
+sql1.jdbc.conn.user=sa
+sql1.jdbc.conn.password=
+#
+# This is the configuration for JNDI datasource.
+#
+#sql1.type=jndi
+#sql1.datasource=jdbc/xacml
+
+sql1.resolvers=langer
+
+sql1.resolver.langer.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver
+sql1.resolver.langer.name=Language
+sql1.resolver.langer.description=This returns the language for a city.
+sql1.resolver.langer.select=SELECT language FROM city INNER JOIN countrylanguage ON city.countrycode = countrylanguage.countrycode WHERE name=?
+sql1.resolver.langer.fields=language
+sql1.resolver.langer.field.language.id=com:att:research:xacml:test:sql:resource:city:language
+sql1.resolver.langer.field.language.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.langer.field.language.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+#You can override the default issuer that is set in the JDBCEngine definition if you want.
+#sql1.resolver.langer.field.language.issuer=com:att:research:xacml:test:sql
+sql1.resolver.langer.parameters=name
+sql1.resolver.langer.parameter.name.id=urn:oasis:names:tc:xacml:1.0:resource:resource-id
+sql1.resolver.langer.parameter.name.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.langer.parameter.name.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+
+
+ldap1.classname=com.att.research.xacml.std.pip.engines.ldap.LDAPEngine
+ldap1.name=LDAP PIP
+ldap1.description=The LDAP containing the seven seas sample LDIF data.
+ldap1.issuer=com:att:research:xacml:test:ldap
+ldap1.java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory
+#
+# NOTE: You will have to setup a local LDAP server and load the data\apache-ds-tutorial.ldif before
+# this example will work.
+#
+ldap1.java.naming.provider.url=ldap://localhost:10389
+#ldap.java.naming.security.principal=
+#ldap.java.naming.security.credentials=
+ldap1.scope=subtree
+
+ldap1.resolvers=dn,ship
+
+ldap1.resolver.dn.classname=com.att.research.xacml.std.pip.engines.ldap.ConfigurableLDAPResolver
+ldap1.resolver.dn.name=Domain Names
+ldap1.resolver.dn.description=Find all the dn's for the subject id
+ldap1.resolver.dn.base=o=sevenseas
+ldap1.resolver.dn.base.parameters=
+ldap1.resolver.dn.filter=(|(uid=${uid})(mail=${uid}))
+ldap1.resolver.dn.filter.parameters=uid
+ldap1.resolver.dn.filter.parameters.uid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id
+ldap1.resolver.dn.filter.parameters.uid.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.dn.filter.parameters.uid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+#ldap1.resolver.dn.filter.parameters.uid.issuer=com:att:research:xacml:test:ldap
+ldap1.resolver.dn.filter.view=dn
+ldap1.resolver.dn.filter.view.dn.id=com:att:research:xacml:test:ldap:subject:dn
+ldap1.resolver.dn.filter.view.dn.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.dn.filter.view.dn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+ldap1.resolver.dn.filter.view.dn.issuer=com:att:research:xacml:test:ldap
+
+ldap1.resolver.ship.classname=com.att.research.xacml.std.pip.engines.ldap.ConfigurableLDAPResolver
+ldap1.resolver.ship.name=Ship Resolver
+ldap1.resolver.ship.description=This resolves a subject's dn to a ship.
+ldap1.resolver.ship.base=o=sevenseas
+ldap1.resolver.ship.base.parameters=
+ldap1.resolver.ship.filter=uniquemember=${dn}
+ldap1.resolver.ship.filter.parameters=dn
+ldap1.resolver.ship.filter.parameters.dn.id=com:att:research:xacml:test:ldap:subject:dn
+ldap1.resolver.ship.filter.parameters.dn.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.ship.filter.parameters.dn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+ldap1.resolver.ship.filter.parameters.dn.issuer=com:att:research:xacml:test:ldap
+ldap1.resolver.ship.filter.view=cn
+ldap1.resolver.ship.filter.view.cn.id=com:att:research:xacml:test:ldap:subject:ship
+ldap1.resolver.ship.filter.view.cn.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.ship.filter.view.cn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+ldap1.resolver.ship.filter.view.cn.issuer=com:att:research:xacml:test:ldap
+
diff --git a/openaz-xacml-pdp-rest/config/xacml.policy.properties b/openaz-xacml-pdp-rest/config/xacml.policy.properties
new file mode 100755
index 0000000..d42c84c
--- /dev/null
+++ b/openaz-xacml-pdp-rest/config/xacml.policy.properties
@@ -0,0 +1,8 @@
+xacml.rootPolicies=annotation,ldap,csv,csvhyper,sql
+xacml.referencedPolicies=
+
+annotation.file=../XACML-TEST/testsets/annotation/AnnotationPolicy.v1.xml
+ldap.file=../XACML-TEST/testsets/pip/configurable-ldap/LDAP-Seven-Seas-v1.xml
+csv.file=../XACML-TEST/testsets/pip/configurable-csv/CSV-Baseball-Hall-Of-Fame-v1.xml
+csvhyper.file=../XACML-TEST/testsets/pip/configurable-csv-hyper/CSV-Legal-Age-Marriage-v1.xml
+sql.file=../XACML-TEST/testsets/pip/configurable-sql/SQL-World-Languages-v1.xml
diff --git a/openaz-xacml-pdp-rest/pom.xml b/openaz-xacml-pdp-rest/pom.xml
new file mode 100755
index 0000000..edb97b4
--- /dev/null
+++ b/openaz-xacml-pdp-rest/pom.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>openaz</artifactId>
+        <groupId>org.openliberty.openaz</groupId>
+        <version>0.0.1-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>openaz-xacml-pdp-rest</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.openliberty.openaz</groupId>
+            <artifactId>openaz-xacml</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.openliberty.openaz</groupId>
+            <artifactId>openaz-xacml-rest</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.openliberty.openaz</groupId>
+            <artifactId>openaz-xacml-pdp</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-logging</groupId>
+            <artifactId>commons-logging</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.h2database</groupId>
+            <artifactId>h2</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>postgresql</groupId>
+            <artifactId>postgresql</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.hsqldb</groupId>
+            <artifactId>hsqldb</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpLoader.java b/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpLoader.java
new file mode 100755
index 0000000..6b44cda
--- /dev/null
+++ b/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpLoader.java
@@ -0,0 +1,470 @@
+/*
+ *                        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.xacml.rest;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLConnection;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Properties;
+import java.util.Set;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.att.research.xacml.api.pap.PAPException;
+import com.att.research.xacml.api.pap.PDPStatus;
+import com.att.research.xacml.api.pap.PDPStatus.Status;
+import com.att.research.xacml.api.pdp.PDPEngine;
+import com.att.research.xacml.api.pdp.PDPEngineFactory;
+import com.att.research.xacml.api.pip.PIPEngine;
+import com.att.research.xacml.api.pip.PIPException;
+import com.att.research.xacml.api.pip.PIPFinder;
+import com.att.research.xacml.api.pip.PIPFinderFactory;
+import com.att.research.xacml.std.pap.StdPDPPIPConfig;
+import com.att.research.xacml.std.pap.StdPDPPolicy;
+import com.att.research.xacml.std.pap.StdPDPStatus;
+import com.att.research.xacml.util.FactoryException;
+import com.att.research.xacml.util.XACMLProperties;
+import com.att.research.xacmlatt.pdp.policy.PolicyDef;
+import com.att.research.xacmlatt.pdp.policy.dom.DOMPolicyDef;
+import com.att.research.xacmlatt.pdp.std.StdPolicyFinderFactory;
+import com.google.common.base.Splitter;
+
+/**
+ * Does the work for loading policy and PIP configurations sent from the PAP servlet.
+ * 
+ * 
+ * @author pameladragosh
+ *
+ */
+public class XACMLPdpLoader {
+	private static final Log logger	= LogFactory.getLog(XACMLPdpLoader.class);
+	
+	public static synchronized PDPEngine loadEngine(StdPDPStatus status, Properties policyProperties, Properties pipProperties) {
+		logger.info("loadEngine: " + policyProperties + " "+ pipProperties);
+		//
+		// First load our policies
+		//
+		try {
+			//
+			// Were we given some properties?
+			//
+			if (policyProperties == null) {
+				//
+				// On init we have no incoming configuration, so just
+				// Load our current saved configuration
+				//
+				policyProperties = new Properties();
+				try (InputStream is = Files.newInputStream(getPDPPolicyCache())) {
+					policyProperties.load(is);
+				}
+			}
+			
+			//
+			// Get our policy cache up-to-date
+			//
+			// Side effects of this include:
+			//	- downloading of policies from remote locations, and
+			//	- creating new "<PolicyId>.file" properties for files existing local
+			//
+			XACMLPdpLoader.cachePolicies(policyProperties);
+			//
+			// Validate the policies
+			//
+			XACMLPdpLoader.validatePolicies(policyProperties, status);
+			if (logger.isDebugEnabled()) {
+				logger.debug("Status: " + status);
+			}
+		} catch (Exception e) {
+			String error = "Failed to load Policy Cache properties file: " + e.getMessage();
+			logger.error(error, e);
+			status.addLoadError(error);
+			status.setStatus(PDPStatus.Status.LOAD_ERRORS);
+		}
+		//
+		// Load our PIP configuration
+		//
+		try {
+			//
+			// Were we given some properties to use?
+			//
+			if (pipProperties == null) {
+				//
+				// Load our current saved configuration
+				//
+				pipProperties = new Properties();
+				try (InputStream is = Files.newInputStream(getPIPConfig())) {
+					pipProperties.load(is);				
+				}
+			}
+			//
+			// Validate our PIP configurations
+			//
+			XACMLPdpLoader.validatePipConfiguration(pipProperties, status);
+			if (logger.isDebugEnabled()) {
+				logger.debug("Status: " + status);
+			}
+		} catch (Exception e) {
+			String error = "Failed to load/validate Pip Config properties file: " + e.getMessage();
+			logger.error(error, e);
+			status.addLoadError(error);
+			status.setStatus(PDPStatus.Status.LOAD_ERRORS);
+		}
+		//
+		// Were they validated?
+		//
+		if (status.getStatus() == Status.LOAD_ERRORS) {
+			logger.error("there were load errors");
+			return null;
+		}
+		//
+		// Reset our official properties the PDP factory
+		// uses to configure the PDP engine.
+		//
+		XACMLRest.loadXacmlProperties(policyProperties, pipProperties);
+		//
+		// Dump ALL our properties that we are trying to load
+		//
+		try {
+			logger.info(XACMLProperties.getProperties().toString());
+		} catch (IOException e) {
+			logger.error("Failed to get XACML Properties", e);
+		}
+		//
+		// Now load the PDP engine
+		//
+		PDPEngineFactory factory	= null;
+		PDPEngine engine	= null;
+		try {
+			factory	= PDPEngineFactory.newInstance();
+			engine	= factory.newEngine();
+			logger.info("Loaded new PDP engine.");
+			status.setStatus(Status.UP_TO_DATE);
+		} catch (FactoryException e) {
+			String error = "Failed to create new PDP Engine";
+			logger.error(error, e);
+			status.addLoadError(error);
+		}
+		return engine;
+	}
+	
+	public static synchronized void validatePolicies(Properties properties, StdPDPStatus status) throws PAPException {
+		Set<String> rootPolicies = XACMLProperties.getRootPolicyIDs(properties);
+		Set<String> refPolicies = XACMLProperties.getReferencedPolicyIDs(properties);
+		
+		for (String id : rootPolicies) {
+			loadPolicy(properties, status, id, true);
+		}
+		// remember which policies were root policies
+		status.addAllLoadedRootPolicies(status.getLoadedPolicies());
+		
+		for (String id : refPolicies) {
+			loadPolicy(properties, status, id, false);
+		}
+		
+		logger.info("Loaded " + status.getLoadedPolicies().size() + " policies, failed to load " + status.getFailedPolicies().size() + " policies, " +
+				status.getLoadedRootPolicies().size() + " root policies");
+		if (status.getLoadedRootPolicies().size() == 0) {
+			logger.warn("NO ROOT POLICIES LOADED!!!  Cannot serve PEP Requests.");
+			status.addLoadWarning("NO ROOT POLICIES LOADED!!!  Cannot serve PEP Requests.");
+		}
+	}
+	
+	public static synchronized void loadPolicy(Properties properties, StdPDPStatus status, String id, boolean isRoot) throws PAPException {
+		PolicyDef policy = null;
+		String location = null;
+		URI locationURI = null;
+		boolean isFile = false;
+		try {
+			location = properties.getProperty(id + ".file");
+			if (location == null) {
+				location = properties.getProperty(id + ".url");
+				if (location != null) {
+					//
+					// Construct the URL
+					//
+					locationURI = URI.create(location);
+					URL url = locationURI.toURL();
+					URLConnection urlConnection = url.openConnection();
+					urlConnection.setRequestProperty(XACMLRestProperties.PROP_PDP_HTTP_HEADER_ID, XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_ID));
+					//
+					// Now construct the output file name
+					//
+					Path outFile = Paths.get(getPDPConfig().toAbsolutePath().toString(), id);
+					//
+					// Copy it to disk
+					//
+					try (FileOutputStream fos = new FileOutputStream(outFile.toFile())) {
+						IOUtils.copy(urlConnection.getInputStream(), fos);
+					}
+					//
+					// Now try to load
+					//
+					isFile = true;
+					try (InputStream fis = Files.newInputStream(outFile)) {
+						policy = DOMPolicyDef.load(fis);
+					}
+					//
+					// Save it
+					//
+					properties.setProperty(id + ".file", outFile.toAbsolutePath().toString());
+				}
+			} else {
+				isFile = true;
+				locationURI = Paths.get(location).toUri();
+				try (InputStream is = Files.newInputStream(Paths.get(location))) {
+					policy = DOMPolicyDef.load(is);
+				}
+			}
+			if (policy != null) {
+				status.addLoadedPolicy(new StdPDPPolicy(id, isRoot, locationURI, properties));
+				logger.info("Loaded policy: " + policy.getIdentifier() + " version: " + policy.getVersion().stringValue());
+			} else {
+				String error = "Failed to load policy " + location;
+				logger.error(error);
+				status.setStatus(PDPStatus.Status.LOAD_ERRORS);
+				status.addLoadError(error);
+				status.addFailedPolicy(new StdPDPPolicy(id, isRoot));
+			}
+		} catch (Exception e) {
+			logger.error("Failed to load policy '" + id + "' from location '" + location + "'", e);
+			status.setStatus(PDPStatus.Status.LOAD_ERRORS);
+			status.addFailedPolicy(new StdPDPPolicy(id, isRoot));
+			//
+			// Is it a file?
+			//
+			if (isFile) {
+				//
+				// Let's remove it
+				//
+				try {
+					logger.error("Corrupted policy file, deleting: " + location);
+					Files.delete(Paths.get(location));
+				} catch (IOException e1) {
+					logger.error(e1);
+				}
+			}
+			throw new PAPException("Failed to load policy '" + id + "' from location '" + location + "'");
+		}
+	}
+	
+	public static synchronized void validatePipConfiguration(Properties properties, StdPDPStatus status) throws PAPException {
+		try {
+			PIPFinderFactory factory = PIPFinderFactory.newInstance(properties);
+			if (factory == null) {
+				throw new FactoryException("Could not create PIP Finder Factory: " + properties.getProperty(XACMLProperties.PROP_PIPFINDERFACTORY));
+			}
+			PIPFinder finder = factory.getFinder(properties);
+			//
+			// Check for this, although it should always return something
+			//
+			if (finder == null) {
+				logger.error("pip finder factory returned a null engine.");
+				throw new PIPException("Could not create PIP Finder");
+			} else {
+				logger.info("Loaded PIP finder");
+			}
+			for (PIPEngine engine : finder.getPIPEngines()) {
+				logger.info("Configured PIP Engine: " + engine.getName());
+				StdPDPPIPConfig config = new StdPDPPIPConfig();
+				config.setName(engine.getName());
+				status.addLoadedPipConfig(config);
+			}
+		} catch (FactoryException | PIPException e) {
+			logger.error("validate PIP configuration failed: " + e.getLocalizedMessage());
+			status.addLoadError(e.getLocalizedMessage());
+			status.setStatus(Status.LOAD_ERRORS);
+			throw new PAPException(e);
+		}
+	}
+	
+	/**
+	 * Iterates the policies defined in the props object to ensure they are loaded locally.
+	 * Policies are searched for in the following order:
+	 * 	- see if the current properties has a "&lt;PolicyID&gt;.file" entry and that file exists in the local directory
+	 * 	- if not, see if the file exists in the local directory; if so create a ".file" property for it.
+	 * 	- if not, get the "&lt;PolicyID&gt;.url" property and try to GET the policy from that location (and set the ".file" property)
+	 * 
+	 *  If the ".file" property is created, then true is returned to tell the caller that the props object changed.
+	 * 
+	 * @param props
+	 * @return true/false if anything was changed in the props object
+	 * @throws PAPException 
+	 */
+	public static synchronized boolean cachePolicies(Properties props) throws PAPException {
+		boolean changed = false;
+		String[] lists = new String[2];
+		lists[0] = props.getProperty(XACMLProperties.PROP_ROOTPOLICIES);
+		lists[1] = props.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES);
+		for (String list : lists) {
+			//
+			// Check for a null or empty parameter
+			//
+			if (list == null || list.length() == 0) {
+				continue;
+			}
+			Iterable<String> policies = Splitter.on(',').trimResults().omitEmptyStrings().split(list);
+			for (String policy : policies) {
+				boolean policyExists = false;
+				
+				// First look for ".file" property and verify the file exists
+				String propLocation	= props.getProperty(policy + StdPolicyFinderFactory.PROP_FILE);
+				if (propLocation != null) {
+					//
+					// Does it exist?
+					//
+					policyExists = Files.exists(Paths.get(propLocation));
+					if (policyExists == false) {
+						logger.warn("Policy file " + policy + " expected at " + propLocation + " does NOT exist.");
+					}
+				}
+				
+				// If ".file" property does not exist, try looking for the local file anyway 
+				//	(it might exist without having a ".file" property set for it)
+				if (policyExists == false) {
+					//
+					// Now construct the output file name
+					//
+					Path outFile = Paths.get(getPDPConfig().toAbsolutePath().toString(), policy);
+					//
+					// Double check to see if we pulled it at some point
+					//
+					policyExists = Files.exists(outFile);
+					if (policyExists) {
+						//
+						// Set the property so the PDP engine doesn't have
+						// to pull it from the URL but rather the FILE.
+						//
+						logger.info("Policy does exist: " + outFile.toAbsolutePath().toString());
+						props.setProperty(policy + StdPolicyFinderFactory.PROP_FILE, outFile.toAbsolutePath().toString());
+						//
+						// Indicate that there were changes made to the properties
+						//
+						changed = true;
+					} else {
+						
+						// File does not exist locally, so we need to get it from the location given in the ".url" property (which MUST exist)
+						
+						//
+						// There better be a URL to retrieve it
+						//
+						propLocation	= props.getProperty(policy + StdPolicyFinderFactory.PROP_URL);
+						if (propLocation != null) {
+							//
+							// Get it
+							//
+							URL url = null;
+							try {
+								//
+								// Create the URL
+								//
+								url						= new URL(propLocation);
+								logger.info("Pulling " + url.toString());
+								//
+								// Open the connection
+								//
+								URLConnection urlConnection	= url.openConnection();
+								urlConnection.setRequestProperty(XACMLRestProperties.PROP_PDP_HTTP_HEADER_ID, XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_ID));
+								//
+								// Copy it to disk
+								//
+								try (InputStream is = urlConnection.getInputStream(); OutputStream os = new FileOutputStream(outFile.toFile())) {
+									IOUtils.copy(is, os);
+								}
+								//
+								// Now save it in the properties as a .file
+								//
+								logger.info("Pulled policy: " + outFile.toAbsolutePath().toString());
+								props.setProperty(policy + StdPolicyFinderFactory.PROP_FILE, outFile.toAbsolutePath().toString());
+								//
+								// Indicate that there were changes made to the properties
+								//
+								changed = true;
+							} catch (Exception e) {
+								if (e instanceof MalformedURLException) {
+									logger.error("Policy '" + policy + "' had bad URL in new configuration, URL='" + propLocation + "'");
+								} else {
+									logger.error("Error while retrieving policy " + policy + " from URL " + url.toString() + ", e="+e);
+								}
+							}
+						} else {
+							logger.error("Policy " + policy + " does NOT exist and does NOT have a URL");
+						}
+					}
+				}
+			}
+		}
+		return changed;
+	}
+
+	public static synchronized Path	getPDPPolicyCache() throws PAPException {
+		Path config = getPDPConfig();
+		Path policyProperties = Paths.get(config.toAbsolutePath().toString(), "xacml.policy.properties");
+		if (Files.notExists(policyProperties)) {
+			logger.warn(policyProperties.toAbsolutePath().toString() + " does NOT exist.");
+			//
+			// Try to create the file
+			//
+			try {
+				Files.createFile(policyProperties);
+			} catch (IOException e) {
+				logger.error("Failed to create policy properties file: " + policyProperties.toAbsolutePath().toString());
+				throw new PAPException("Failed to create policy properties file: " + policyProperties.toAbsolutePath().toString());
+			}
+		}
+		return policyProperties;
+	}
+	
+	public static synchronized Path	getPIPConfig() throws PAPException {
+		Path config = getPDPConfig();
+		Path pipConfigProperties = Paths.get(config.toAbsolutePath().toString(), "xacml.pip.properties");
+		if (Files.notExists(pipConfigProperties)) {
+			logger.warn(pipConfigProperties.toAbsolutePath().toString() + " does NOT exist.");
+			//
+			// Try to create the file
+			//
+			try {
+				Files.createFile(pipConfigProperties);
+			} catch (IOException e) {
+				logger.error("Failed to create pip properties file: " + pipConfigProperties.toAbsolutePath().toString());
+				throw new PAPException("Failed to create pip properties file: " + pipConfigProperties.toAbsolutePath().toString());
+			}
+		}
+		return pipConfigProperties;
+	}
+	
+	public static synchronized Path getPDPConfig() throws PAPException {
+		Path config = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_CONFIG));
+		if (Files.notExists(config)) {
+			logger.warn(config.toAbsolutePath().toString() + " does NOT exist.");
+			//
+			// Try to create the directory
+			//
+			try {
+				Files.createDirectories(config);
+			} catch (IOException e) {
+				logger.error("Failed to create config directory: " + config.toAbsolutePath().toString(), e);
+				throw new PAPException("Failed to create config directory: " + config.toAbsolutePath().toString());
+			}
+		}
+		return config;
+	}
+
+}
diff --git a/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpRegisterThread.java b/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpRegisterThread.java
new file mode 100755
index 0000000..3d232cf
--- /dev/null
+++ b/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpRegisterThread.java
@@ -0,0 +1,210 @@
+/*
+ *                        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.xacml.rest;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.file.Files;
+import java.util.Properties;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.att.research.xacml.rest.XACMLPdpServlet.PutRequest;
+import com.att.research.xacml.util.XACMLProperties;
+
+public class XACMLPdpRegisterThread implements Runnable {
+	private static final Log logger	= LogFactory.getLog(XACMLPdpRegisterThread.class);
+	
+	public volatile boolean isRunning = false;
+	
+	public synchronized boolean isRunning() {
+		return this.isRunning;
+	}
+	
+	public synchronized void terminate() {
+		this.isRunning = false;
+	}
+	
+	/**
+	 * 
+	 * This is our thread that runs on startup to tell the PAP server we are up-and-running.
+	 * 
+	 */
+	@Override
+	public void run() {
+		synchronized(this) {
+			this.isRunning = true;
+		}
+		boolean registered = false;
+		boolean interrupted = false;
+		int seconds;
+		try {
+			seconds = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_REGISTER_SLEEP));
+		} catch (NumberFormatException e) {
+			logger.error("REGISTER_SLEEP: ", e);
+			seconds = 5;
+		}
+		if (seconds < 5) {
+			seconds = 5;
+		}
+		int retries;
+		try {
+			retries = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_REGISTER_RETRIES));
+		} catch (NumberFormatException e) {
+			logger.error("REGISTER_SLEEP: ", e);
+			retries = -1;
+		}
+		while (! registered && ! interrupted && this.isRunning()) {
+			HttpURLConnection connection = null;
+			try {
+				//
+				// Get the PAP Servlet URL
+				//
+				URL url = new URL(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_URL));
+				logger.info("Registering with " + url.toString());
+				boolean finished = false;
+				while (! finished) {
+					//
+					// Open up the connection
+					//
+					connection = (HttpURLConnection)url.openConnection();
+					//
+					// Setup our method and headers
+					//
+		            connection.setRequestMethod("POST");
+					connection.setRequestProperty("Accept", "text/x-java-properties");
+		            connection.setRequestProperty("Content-Type", "text/x-java-properties");
+		            connection.setRequestProperty(XACMLRestProperties.PROP_PDP_HTTP_HEADER_ID, XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_ID));
+		            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);
+		    		try {
+		    			//
+		    			// Send our current policy configuration
+		    			//
+		    			String lists = XACMLProperties.PROP_ROOTPOLICIES + "=" + XACMLProperties.getProperty(XACMLProperties.PROP_ROOTPOLICIES);
+		    			lists = lists + "\n" + XACMLProperties.PROP_REFERENCEDPOLICIES + "=" + XACMLProperties.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES) + "\n";
+		    			try (InputStream listsInputStream = new ByteArrayInputStream(lists.getBytes());
+		    					InputStream pipInputStream = Files.newInputStream(XACMLPdpLoader.getPIPConfig());
+		    					OutputStream os = connection.getOutputStream()) {
+		    				IOUtils.copy(listsInputStream, os);
+
+			    			//
+			    			// Send our current PIP configuration
+			    			//
+			    			IOUtils.copy(pipInputStream, os);
+		    			}
+		    		} catch (Exception e) {
+		    			logger.error("Failed to send property file", e);
+		    		}
+		            //
+		            // Do the connect
+		            //
+		            connection.connect();
+		            if (connection.getResponseCode() == 204) {
+		            	logger.info("Success. We are configured correctly.");
+		            	finished = true;
+		            	registered = true;
+		            } else if (connection.getResponseCode() == 200) {
+		            	logger.info("Success. We have a new configuration.");
+		            	Properties properties = new Properties();
+		            	properties.load(connection.getInputStream());
+		            	logger.info("New properties: " + properties.toString());
+		            	//
+		            	// Queue it
+		            	//
+		            	// The incoming properties does NOT include urls
+		            	PutRequest req = new PutRequest(XACMLProperties.getPolicyProperties(properties, false), XACMLProperties.getPipProperties(properties));
+		            	XACMLPdpServlet.queue.offer(req);
+		            	//
+		            	// We are now registered
+		            	//
+		            	finished = true;
+		            	registered=true;
+		            } else if (connection.getResponseCode() >= 300 && connection.getResponseCode()  <= 399) {
+		            	//
+		            	// Re-direction
+		            	//
+		            	String newLocation = connection.getHeaderField("Location");
+		            	if (newLocation == null || newLocation.isEmpty()) {
+		            		logger.warn("Did not receive a valid re-direction location");
+		            		finished = true;
+		            	} else {
+		            		logger.info("New Location: " + newLocation);
+		            		url = new URL(newLocation);
+		            	}
+		            } else {
+		            	logger.warn("Failed: " + connection.getResponseCode() + "  message: " + connection.getResponseMessage());
+		            	finished = true;
+		            }
+				}
+			} catch (Exception e) {
+				logger.error(e);
+			} finally {
+				// cleanup the connection
+ 				if (connection != null) {
+					try {
+						// For some reason trying to get the inputStream from the connection
+						// throws an exception rather than returning null when the InputStream does not exist.
+						InputStream is = null;
+						try {
+							is = connection.getInputStream();
+						} catch (Exception e1) {
+							// ignore this
+						}
+						if (is != null) {
+							is.close();
+						}
+
+					} catch (IOException ex) {
+						logger.error("Failed to close connection: " + ex, ex);
+					}
+					connection.disconnect();
+				}
+			}
+			//
+			// Wait a little while to try again
+			//
+			try {
+				if (registered == false) {
+					if (retries > 0) {
+						retries--;
+					} else if (retries == 0) {
+						break;
+					}
+					Thread.sleep(seconds * 1000);
+				}
+			} catch (InterruptedException e) {
+				interrupted = true;
+				this.terminate();
+			}
+		}
+		synchronized(this) {
+			this.isRunning = false;
+		}
+		logger.info("Thread exiting...(registered=" + registered + ", interrupted=" + interrupted + ", isRunning=" + this.isRunning() + ", retries=" + retries + ")");
+	}
+
+}
diff --git a/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpServlet.java b/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpServlet.java
new file mode 100755
index 0000000..f670579
--- /dev/null
+++ b/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpServlet.java
@@ -0,0 +1,690 @@
+/*
+ *                        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.xacml.rest;
+
+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.nio.file.Files;
+import java.util.Properties;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+
+import javax.servlet.Servlet;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.annotation.WebInitParam;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+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.Request;
+import com.att.research.xacml.api.Response;
+import com.att.research.xacml.api.pap.PDPStatus.Status;
+import com.att.research.xacml.api.pdp.PDPEngine;
+import com.att.research.xacml.api.pdp.PDPException;
+import com.att.research.xacml.std.dom.DOMRequest;
+import com.att.research.xacml.std.dom.DOMResponse;
+import com.att.research.xacml.std.json.JSONRequest;
+import com.att.research.xacml.std.json.JSONResponse;
+import com.att.research.xacml.std.pap.StdPDPStatus;
+import com.att.research.xacml.util.XACMLProperties;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+/**
+ * Servlet implementation class XacmlPdpServlet
+ * 
+ * This is an implementation of the XACML 3.0 RESTful Interface with added features to support
+ * simple PAP RESTful API for policy publishing and PIP configuration changes.
+ * 
+ * If you are running this the first time, then we recommend you look at the xacml.pdp.properties file.
+ * This properties file has all the default parameter settings. If you are running the servlet as is,
+ * then we recommend setting up you're container to run it on port 8080 with context "/pdp". Wherever
+ * the default working directory is set to, a "config" directory will be created that holds the policy
+ * and pip cache. This setting is located in the xacml.pdp.properties file.
+ * 
+ * When you are ready to customize, you can create a separate xacml.pdp.properties on you're local file
+ * system and setup the parameters as you wish. Just set the Java VM System variable to point to that file:
+ * 
+ * -Dxacml.properties=/opt/app/xacml/etc/xacml.pdp.properties
+ * 
+ * Or if you only want to change one or two properties, simply set the Java VM System variable for that property.
+ * 
+ * -Dxacml.rest.pdp.register=false
+ *
+ * @author pameladragosh
+ *
+ */
+@WebServlet(
+		description = "Implements the XACML PDP RESTful API and client PAP API.", 
+		urlPatterns = { "/" }, 
+		loadOnStartup=1,
+		initParams = { 
+				@WebInitParam(name = "XACML_PROPERTIES_NAME", value = "xacml.pdp.properties", description = "The location of the PDP xacml.pdp.properties file holding configuration information.")
+		})
+public class XACMLPdpServlet extends HttpServlet implements Runnable {
+	private static final long serialVersionUID = 1L;
+	//
+	// Our application debug log
+	//
+	private static final Log logger	= LogFactory.getLog(XACMLPdpServlet.class);
+	//
+	// This logger is specifically only for Xacml requests and their corresponding response.
+	// It's output ideally should be sent to a separate file from the application logger.
+	//
+	private static final Log requestLogger = LogFactory.getLog("xacml.request");
+	//
+	// This thread may getting invoked on startup, to let the PAP know
+	// that we are up and running.
+	//
+	private Thread registerThread = null;
+	private XACMLPdpRegisterThread registerRunnable = null;
+	//
+	// This is our PDP engine pointer. There is a synchronized lock used
+	// for access to the pointer. In case we are servicing PEP requests while
+	// an update is occurring from the PAP.
+	//
+	private PDPEngine pdpEngine	= null;
+	private static final Object pdpEngineLock = new Object();
+	//
+	// This is our PDP's status. What policies are loaded (or not) and
+	// what PIP configurations are loaded (or not).
+	// There is a synchronized lock used for access to the object.
+	//
+	private static volatile StdPDPStatus status = new StdPDPStatus();
+	private static final Object pdpStatusLock = new Object();
+	//
+	// Queue of PUT requests
+	//
+	public static class PutRequest {
+		public Properties policyProperties = null;
+		public Properties pipConfigProperties = null;
+		
+		PutRequest(Properties policies, Properties pips) {
+			this.policyProperties = policies;
+			this.pipConfigProperties = pips;
+		}
+	}
+	public static volatile BlockingQueue<PutRequest> queue = new LinkedBlockingQueue<PutRequest>(2);
+	//
+	// This is our configuration thread that attempts to load
+	// a new configuration request.
+	//
+	private Thread configThread = null;
+	private volatile boolean configThreadTerminate = false;
+
+    /**
+     * Default constructor. 
+     */
+    public XACMLPdpServlet() {
+    }
+
+	/**
+	 * @see Servlet#init(ServletConfig)
+	 */
+	public void init(ServletConfig config) throws ServletException {
+		//
+		// Initialize
+		//
+		XACMLRest.xacmlInit(config);
+		//
+		// Load our engine - this will use the latest configuration
+		// that was saved to disk and set our initial status object.
+		//
+		PDPEngine engine = XACMLPdpLoader.loadEngine(XACMLPdpServlet.status, null, null);
+		if (engine != null) {
+			synchronized(pdpEngineLock) {
+				pdpEngine = engine;
+			}
+		}
+		//
+		// Kick off our thread to register with the PAP servlet.
+		//
+		if (Boolean.parseBoolean(XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_REGISTER))) {
+			this.registerRunnable = new XACMLPdpRegisterThread();
+			this.registerThread = new Thread(this.registerRunnable);
+			this.registerThread.start();
+		}
+		//
+		// This is our thread that manages incoming configuration
+		// changes.
+		//
+		this.configThread = new Thread(this);
+		this.configThread.start();
+	}
+
+	/**
+	 * @see Servlet#destroy()
+	 */
+	public void destroy() {
+		super.destroy();
+		logger.info("Destroying....");
+		//
+		// Make sure the register thread is not running
+		//
+		if (this.registerRunnable != null) {
+			try {
+				this.registerRunnable.terminate();
+				if (this.registerThread != null) {
+					this.registerThread.interrupt();
+					this.registerThread.join();
+				}
+			} catch (InterruptedException e) {
+				logger.error(e);
+			}
+		}
+		//
+		// Make sure the configure thread is not running
+		//
+		this.configThreadTerminate = true;
+		try {
+			this.configThread.interrupt();
+			this.configThread.join();
+		} catch (InterruptedException e) {
+			logger.error(e);
+		}
+		logger.info("Destroyed.");
+	}
+
+	/**
+	 * PUT - The PAP engine sends configuration information using HTTP PUT request.
+	 * 
+	 * One parameter is expected:
+	 * 
+	 * config=[policy|pip|all]
+	 * 
+	 * 	policy - Expect a properties file that contains updated lists of the root and referenced policies that the PDP should
+	 * 			 be using for PEP requests.
+	 * 
+	 * 		Specifically should AT LEAST contain the following properties:
+	 * 		xacml.rootPolicies
+	 * 		xacml.referencedPolicies
+	 * 
+	 * 		In addition, any relevant information needed by the PDP to load or retrieve the policies to store in its cache.
+	 *
+	 * 		EXAMPLE:
+	 *	 		xacml.rootPolicies=PolicyA.1, PolicyB.1
+ 	 *
+	 *			PolicyA.1.url=http://localhost:9090/PAP?id=b2d7b86d-d8f1-4adf-ba9d-b68b2a90bee1&version=1
+	 *			PolicyB.1.url=http://localhost:9090/PAP/id=be962404-27f6-41d8-9521-5acb7f0238be&version=1
+	 *	
+	 *			xacml.referencedPolicies=RefPolicyC.1, RefPolicyD.1
+	 *
+	 *			RefPolicyC.1.url=http://localhost:9090/PAP?id=foobar&version=1
+	 *			RefPolicyD.1.url=http://localhost:9090/PAP/id=example&version=1
+	 *	
+	 * pip - Expect a properties file that contain PIP engine configuration properties.
+	 * 
+	 *  		Specifically should AT LEAST the following property:
+	 * 			xacml.pip.engines
+	 * 
+	 * 		In addition, any relevant information needed by the PDP to load and configure the PIPs.
+	 * 
+	 * 		EXAMPLE:
+	 * 			xacml.pip.engines=foo,bar
+	 * 
+	 * 			foo.classname=com.foo
+	 * 			foo.sample=abc
+	 * 			foo.example=xyz
+	 * 			......
+	 * 
+	 * 			bar.classname=com.bar
+	 * 			......
+	 * 
+	 * all - Expect ALL new configuration properties for the PDP
+	 * 
+	 * @see HttpServlet#doPut(HttpServletRequest request, HttpServletResponse response)
+	 */
+	protected void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+		//
+		// Dump our request out
+		//
+		if (logger.isDebugEnabled()) {
+			XACMLRest.dumpRequest(request);
+		}
+		//
+		// What is being PUT?
+		//
+		String cache = request.getParameter("cache");
+		//
+		// Should be a list of policy and pip configurations in Java properties format
+		//
+		if (cache != null && request.getContentType().equals("text/x-java-properties")) {
+			if (request.getContentLength() > Integer.parseInt(XACMLProperties.getProperty("MAX_CONTENT_LENGTH", "32767"))) {
+				String message = "Content-Length larger than server will accept.";
+				logger.info(message);
+				response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
+				return;
+			}
+			this.doPutConfig(cache, request, response);
+		} else {
+			String message = "Invalid cache: '" + cache + "' or content-type: '" + request.getContentType() + "'";
+			logger.error(message);
+			response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
+			return;
+		}
+	}
+	
+	protected void doPutConfig(String config, HttpServletRequest request, HttpServletResponse response)  throws ServletException, IOException {
+		try {
+			// prevent multiple configuration changes from stacking up
+			if (XACMLPdpServlet.queue.remainingCapacity() <= 0) {
+				logger.error("Queue capacity reached");
+				response.sendError(HttpServletResponse.SC_CONFLICT, "Multiple configuration changes waiting processing.");
+				return;
+			}
+			//
+			// Read the properties data into an object.
+			//
+			Properties newProperties = new Properties();
+			newProperties.load(request.getInputStream());
+			// should have something in the request
+			if (newProperties.size() == 0) {
+				logger.error("No properties in PUT");
+				response.sendError(HttpServletResponse.SC_BAD_REQUEST, "PUT must contain at least one property");
+				return;
+			}
+			//
+			// Which set of properties are they sending us? Whatever they send gets
+			// put on the queue (if there is room).
+			//
+			if (config.equals("policies")) {
+				newProperties = XACMLProperties.getPolicyProperties(newProperties, true);
+				if (newProperties.size() == 0) {
+					logger.error("No policy properties in PUT");
+					response.sendError(HttpServletResponse.SC_BAD_REQUEST, "PUT with cache=policies must contain at least one policy property");
+					return;
+				}
+				XACMLPdpServlet.queue.offer(new PutRequest(newProperties, null));
+			} else if (config.equals("pips")) {
+				newProperties = XACMLProperties.getPipProperties(newProperties);
+				if (newProperties.size() == 0) {
+					logger.error("No pips properties in PUT");
+					response.sendError(HttpServletResponse.SC_BAD_REQUEST, "PUT with cache=pips must contain at least one pip property");
+					return;
+				}
+				XACMLPdpServlet.queue.offer(new PutRequest(null, newProperties));
+			} else if (config.equals("all")) {
+				Properties newPolicyProperties = XACMLProperties.getPolicyProperties(newProperties, true);
+				if (newPolicyProperties.size() == 0) {
+					logger.error("No policy properties in PUT");
+					response.sendError(HttpServletResponse.SC_BAD_REQUEST, "PUT with cache=all must contain at least one policy property");
+					return;
+				}
+				Properties newPipProperties = XACMLProperties.getPipProperties(newProperties);
+				if (newPipProperties.size() == 0) {
+					logger.error("No pips properties in PUT");
+					response.sendError(HttpServletResponse.SC_BAD_REQUEST, "PUT with cache=all must contain at least one pip property");
+					return;
+				}
+				XACMLPdpServlet.queue.offer(new PutRequest(newPolicyProperties, newPipProperties));
+			} else {
+				//
+				// Invalid value
+				//
+				logger.error("Invalid config value: " + config);
+				response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Config must be one of 'policies', 'pips', 'all'");
+				return;
+			}
+		} catch (Exception e) {
+			logger.error("Failed to process new configuration.", e);
+			response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
+			return;
+		}
+	}
+	
+	/**
+	 * Parameters: type=hb|config|Status
+	 * 
+	 * 1. HeartBeat Status 
+	 * HeartBeat
+	 * 		OK - All Policies are Loaded, All PIPs are Loaded
+	 *  	LOADING_IN_PROGRESS - Currently loading a new policy set/pip configuration
+	 *  	LAST_UPDATE_FAILED - Need to track the items that failed during last update
+	 *  	LOAD_FAILURE - ??? Need to determine what information is sent and how 
+	 * 2. Configuration
+	 * 3. Status
+	 * 		return the StdPDPStatus object in the Response content
+	 * 
+	 * 
+	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
+	 */
+	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+		XACMLRest.dumpRequest(request);
+		//
+		// What are they requesting?
+		//
+		boolean returnHB = false;
+		response.setHeader("Cache-Control", "no-cache");
+		String type = request.getParameter("type");
+		// type might be null, so use equals on string constants
+		if ("config".equals(type)) {
+			response.setContentType("text/x-java-properties");
+			try {
+    			String lists = XACMLProperties.PROP_ROOTPOLICIES + "=" + XACMLProperties.getProperty(XACMLProperties.PROP_ROOTPOLICIES, "");
+    			lists = lists + "\n" + XACMLProperties.PROP_REFERENCEDPOLICIES + "=" + XACMLProperties.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES, "") + "\n";
+    			try (InputStream listInputStream = new ByteArrayInputStream(lists.getBytes());
+    					InputStream pipInputStream = Files.newInputStream(XACMLPdpLoader.getPIPConfig());
+    					OutputStream os = response.getOutputStream()) {
+    				IOUtils.copy(listInputStream, os);
+    				IOUtils.copy(pipInputStream, os);
+				}
+                response.setStatus(HttpServletResponse.SC_OK);
+			} catch (Exception e) {
+				logger.error("Failed to copy property file", e);
+				response.sendError(400, "Failed to copy Property file");
+			}
+			
+		} else if ("hb".equals(type)) {
+			returnHB = true;
+			response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+			
+		} else if ("Status".equals(type)) {
+			// convert response object to JSON and include in the response
+			synchronized(pdpStatusLock) {
+				ObjectMapper mapper = new ObjectMapper();
+	            mapper.writeValue(response.getOutputStream(),  status);
+			}
+            response.setStatus(HttpServletResponse.SC_OK);
+            
+		} else {
+			response.sendError(HttpServletResponse.SC_BAD_REQUEST, "type not 'config' or 'hb'");
+		}
+		if (returnHB) {
+			synchronized(pdpStatusLock) {
+				response.addHeader(XACMLRestProperties.PROP_PDP_HTTP_HEADER_HB, status.getStatus().toString());
+			}
+		}
+	}
+
+	/**
+	 * POST - We expect XACML requests to be posted by PEP applications. They can be in the form of XML or JSON according
+	 * to the XACML 3.0 Specifications for both.
+	 * 
+	 * 
+	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
+	 */
+	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+		//
+		// no point in doing any work if we know from the get-go that we cannot do anything with the request
+		//
+		if (status.getLoadedRootPolicies().size() == 0) {
+			logger.warn("Request from PEP at " + request.getRequestURI() + " for service when PDP has No Root Policies loaded");
+			response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
+			return;
+		}
+		
+		XACMLRest.dumpRequest(request);
+		//
+		// Set our no-cache header
+		//
+		response.setHeader("Cache-Control", "no-cache");
+		//
+		// They must send a Content-Type
+		//
+		if (request.getContentType() == null) {
+			logger.warn("Must specify a Content-Type");
+			response.sendError(HttpServletResponse.SC_BAD_REQUEST, "no content-type given");
+			return;
+		}
+		//
+		// Limit the Content-Length to something reasonable
+		//
+		if (request.getContentLength() > Integer.parseInt(XACMLProperties.getProperty("MAX_CONTENT_LENGTH", "32767"))) {
+			String message = "Content-Length larger than server will accept.";
+			logger.info(message);
+			response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
+			return;
+		}
+		if (request.getContentLength() <= 0) {
+			String message = "Content-Length is negative";
+			logger.info(message);
+			response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
+			return;
+		}
+		ContentType contentType = null;
+		try {
+			contentType = ContentType.parse(request.getContentType());
+		}
+		catch (Exception e) {
+			String message = "Parsing Content-Type: " + request.getContentType() + ", error=" + e.getMessage();
+			logger.error(message, e);
+			response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
+			return;
+		}
+		//
+		// What exactly did they send us?
+		//
+		String incomingRequestString = null;
+		Request pdpRequest = null;
+		if (contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_JSON.getMimeType()) ||
+				contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_XML.getMimeType()) ||
+				contentType.getMimeType().equalsIgnoreCase("application/xacml+xml") ) {
+			//
+			// Read in the string
+			//
+			StringBuilder buffer = new StringBuilder();
+			BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream()));
+			String line;
+			while((line = reader.readLine()) != null){
+				buffer.append(line);
+			}
+			incomingRequestString = buffer.toString();
+			logger.info(incomingRequestString);
+		    //
+			// Parse into a request
+			//
+			try {
+				if (contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_JSON.getMimeType())) {
+					pdpRequest = JSONRequest.load(incomingRequestString);
+				} else if (	contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_XML.getMimeType()) ||
+							contentType.getMimeType().equalsIgnoreCase("application/xacml+xml")) {
+					pdpRequest = DOMRequest.load(incomingRequestString);
+				}
+			}
+			catch(Exception e) {
+				logger.error("Could not parse request", e);
+				response.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
+				return;
+			}
+		} else {
+			String message = "unsupported content type" + request.getContentType();
+			logger.error(message);
+			response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
+			return;
+		}
+		//
+		// Did we successfully get and parse a request?
+		//
+		if (pdpRequest == null || pdpRequest.getRequestAttributes() == null || pdpRequest.getRequestAttributes().size() <= 0) {
+			String message = "Zero Attributes found in the request";
+			logger.error(message);
+			response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
+			return;
+		}
+		//
+		// Run it
+		//
+		try {
+			//
+	        // Get the pointer to the PDP Engine
+	        //
+			PDPEngine myEngine = null;
+			synchronized(pdpEngineLock) {
+				myEngine = this.pdpEngine;
+			}
+			if (myEngine == null) {
+				String message = "No engine loaded.";
+				logger.error(message);
+				response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
+				return;
+			}
+			//
+			// Send the request and save the response
+			//
+			long lTimeStart, lTimeEnd;
+			Response pdpResponse	= null;
+
+//TODO - Make this unnecessary
+//TODO	It seems that the PDP Engine is not thread-safe, so when a configuration change occurs in the middle of processing
+//TODO	a PEP Request, that Request fails (it throws a NullPointerException in the decide() method).
+//TODO	Using synchronize will slow down processing of PEP requests, possibly by a significant amount.
+//TODO	Since configuration changes are rare, it would be A Very Good Thing if we could eliminate this sychronized block.
+//TODO
+//TODO	This problem was found by starting one PDP then
+//TODO		RestLoadTest switching between 2 configurations, 1 second apart
+//TODO			both configurations contain the datarouter policy
+//TODO			both configurations already have all policies cached in the PDPs config directory
+//TODO		RestLoadTest started with the Datarouter test requests, 5 threads, no interval
+//TODO	With that configuration this code (without the synchronized) throws a NullPointerException
+//TODO	within a few seconds.
+//
+synchronized(pdpEngineLock) {
+	myEngine = this.pdpEngine;
+			try {
+				lTimeStart = System.currentTimeMillis();
+				pdpResponse	= myEngine.decide(pdpRequest);
+				lTimeEnd = System.currentTimeMillis();
+			} catch (PDPException e) {
+				String message = "Exception during decide: " + e.getMessage();
+				logger.error(message);
+				response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
+				return;
+			}
+}
+			requestLogger.info(lTimeStart + "=" + incomingRequestString);
+			if (logger.isDebugEnabled()) {
+				logger.debug("Request time: " + (lTimeEnd - lTimeStart) + "ms");
+			}
+			//
+			// Convert Response to appropriate Content-Type
+			//
+			if (pdpResponse == null) {
+				requestLogger.info(lTimeStart + "=" + "{}");
+				throw new Exception("Failed to get response from PDP engine.");
+			}
+			//
+			// Set our content-type
+			//
+			response.setContentType(contentType.getMimeType());
+			//
+			// Convert the PDP response object to a String to
+			// return to our caller as well as dump to our loggers.
+			//
+			String outgoingResponseString = "";
+			if (contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_JSON.getMimeType())) {
+				//
+				// Get it as a String. This is not very efficient but we need to log our
+				// results for auditing.
+				//
+				outgoingResponseString = JSONResponse.toString(pdpResponse, logger.isDebugEnabled());
+				if (logger.isDebugEnabled()) {
+					logger.debug(outgoingResponseString);
+					//
+					// Get rid of whitespace
+					//
+					outgoingResponseString = JSONResponse.toString(pdpResponse, false);
+				}
+			} else if (	contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_XML.getMimeType()) ||
+						contentType.getMimeType().equalsIgnoreCase("application/xacml+xml")) {
+				//
+				// Get it as a String. This is not very efficient but we need to log our
+				// results for auditing.
+				//
+				outgoingResponseString = DOMResponse.toString(pdpResponse, logger.isDebugEnabled());
+				if (logger.isDebugEnabled()) {
+					logger.debug(outgoingResponseString);
+					//
+					// Get rid of whitespace
+					//
+					outgoingResponseString = DOMResponse.toString(pdpResponse, false);
+				}
+			}
+			//
+			// lTimeStart is used as an ID within the requestLogger to match up
+			// request's with responses.
+			//
+			requestLogger.info(lTimeStart + "=" + outgoingResponseString);
+			response.getWriter().print(outgoingResponseString);
+		}
+		catch (Exception e) {
+			String message = "Exception executing request: " + e;
+			logger.error(message, e);
+			response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
+			return;
+		}
+		response.setStatus(HttpServletResponse.SC_OK);
+	}
+
+	@Override
+	public void run() {
+		//
+		// Keep running until we are told to terminate
+		//
+		try {
+			while (! this.configThreadTerminate) {
+				PutRequest request = XACMLPdpServlet.queue.take();
+				StdPDPStatus newStatus = new StdPDPStatus();
+
+//TODO - This is related to the problem discussed in the doPost() method about the PDPEngine not being thread-safe.
+//TODO	See that discussion, and when the PDPEngine is made thread-safe it should be ok to move the loadEngine out of
+//TODO	the synchronized block.
+//TODO	However, since configuration changes should be rare we may not care about changing this.
+PDPEngine newEngine = null;
+				synchronized(pdpStatusLock) {
+					XACMLPdpServlet.status.setStatus(Status.UPDATING_CONFIGURATION);
+newEngine = XACMLPdpLoader.loadEngine(newStatus, request.policyProperties, request.pipConfigProperties);
+				}
+//				PDPEngine newEngine = XACMLPdpLoader.loadEngine(newStatus, request.policyProperties, request.pipConfigProperties);
+				if (newEngine != null) {
+					synchronized(XACMLPdpServlet.pdpEngineLock) {
+						this.pdpEngine = newEngine;
+						try {
+							logger.info("Saving configuration.");
+							if (request.policyProperties != null) {
+								try (OutputStream os = Files.newOutputStream(XACMLPdpLoader.getPDPPolicyCache())) {
+									request.policyProperties.store(os, "");
+								}
+							}
+							if (request.pipConfigProperties != null) {
+								try (OutputStream os = Files.newOutputStream(XACMLPdpLoader.getPIPConfig())) {
+									request.pipConfigProperties.store(os, "");
+								}
+							}
+							newStatus.setStatus(Status.UP_TO_DATE);
+							
+						} catch (Exception e) {
+							logger.error("Failed to store new properties.");
+							newStatus.setStatus(Status.LOAD_ERRORS);
+							newStatus.addLoadWarning("Unable to save configuration: " + e.getMessage());
+						}
+					}					
+				} else {
+					newStatus.setStatus(Status.LAST_UPDATE_FAILED);
+				}
+				synchronized(pdpStatusLock) {
+					XACMLPdpServlet.status.set(newStatus);
+				}
+			}
+		} catch (InterruptedException e) {
+			logger.error("interrupted");
+		}
+	}	
+}
diff --git a/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/impl/XACMLPdpPIPFinderFactory.java b/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/impl/XACMLPdpPIPFinderFactory.java
new file mode 100755
index 0000000..550d1b2
--- /dev/null
+++ b/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/impl/XACMLPdpPIPFinderFactory.java
@@ -0,0 +1,75 @@
+/*
+ *                        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.xacml.rest.impl;
+
+import java.util.Properties;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.att.research.xacml.api.pip.PIPException;
+import com.att.research.xacml.api.pip.PIPFinder;
+import com.att.research.xacml.api.pip.PIPFinderFactory;
+import com.att.research.xacml.std.pip.finders.ConfigurableEngineFinder;
+import com.att.research.xacml.util.XACMLProperties;
+
+public class XACMLPdpPIPFinderFactory extends PIPFinderFactory {
+	private ConfigurableEngineFinder pipFinder;
+	
+	private static Log logger	= LogFactory.getLog(XACMLPdpPIPFinderFactory.class);
+	
+	public XACMLPdpPIPFinderFactory() {
+	}
+
+	public XACMLPdpPIPFinderFactory(Properties properties) {
+	}
+
+	@Override
+	public PIPFinder getFinder() throws PIPException {
+		if (pipFinder == null) {
+			synchronized(this) {
+				if (pipFinder == null) {
+					if (logger.isDebugEnabled()) {
+						logger.debug("Creating default configurable engine finder");
+					}
+					pipFinder					= new ConfigurableEngineFinder();
+					Properties xacmlProperties	= null;
+					try {
+						xacmlProperties	= XACMLProperties.getProperties();
+					} catch (Exception ex) {
+						logger.error("Exception getting XACML properties: " + ex.getMessage(), ex);
+						return null;
+					}
+					if (xacmlProperties != null) {
+						((ConfigurableEngineFinder)pipFinder).configure(xacmlProperties);
+					}
+				}
+			}
+		}
+		return pipFinder;
+	}
+
+	@Override
+	public PIPFinder getFinder(Properties properties) throws PIPException {
+		if (pipFinder == null) {
+			synchronized(this) {
+				if (pipFinder == null) {
+					if (logger.isDebugEnabled()) {
+						logger.debug("Creating configurable engine finder using: " + properties);
+					}
+					pipFinder					= new ConfigurableEngineFinder();
+					((ConfigurableEngineFinder)pipFinder).configure(properties);
+				}
+			}
+		}
+		return this.pipFinder;
+	}
+}
diff --git a/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/impl/XACMLPdpPolicyFinderFactory.java b/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/impl/XACMLPdpPolicyFinderFactory.java
new file mode 100755
index 0000000..421839a
--- /dev/null
+++ b/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/impl/XACMLPdpPolicyFinderFactory.java
@@ -0,0 +1,197 @@
+/*
+ *                        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.xacml.rest.impl;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.util.FactoryException;
+import com.att.research.xacml.util.XACMLProperties;
+import com.att.research.xacmlatt.pdp.policy.Policy;
+import com.att.research.xacmlatt.pdp.policy.PolicyDef;
+import com.att.research.xacmlatt.pdp.policy.PolicyFinder;
+import com.att.research.xacmlatt.pdp.policy.PolicyFinderFactory;
+import com.att.research.xacmlatt.pdp.policy.dom.DOMPolicyDef;
+import com.att.research.xacmlatt.pdp.std.StdPolicyFinder;
+import com.google.common.base.Splitter;
+
+public class XACMLPdpPolicyFinderFactory extends PolicyFinderFactory {
+	public static final String	PROP_FILE		= ".file";
+	public static final String	PROP_URL		= ".url";
+	
+	private static Log logger							= LogFactory.getLog(XACMLPdpPolicyFinderFactory.class);
+	private List<PolicyDef> rootPolicies;
+	private List<PolicyDef> referencedPolicies;
+	private boolean needsInit					= true;
+	
+	private Properties properties = null;
+	
+	public XACMLPdpPolicyFinderFactory() {
+		//
+		// Here we differ from the StdPolicyFinderFactory in that we initialize right away.
+		// We do not wait for a policy request to happen to look for and load policies.
+		//
+		this.init();
+	}
+
+	public XACMLPdpPolicyFinderFactory(Properties properties) {
+		//
+		// Save our properties
+		//
+		this.properties = properties;
+		//
+		// Here we differ from the StdPolicyFinderFactory in that we initialize right away.
+		// We do not wait for a policy request to happen to look for and load policies.
+		//
+		this.init();
+	}
+
+	/**
+	 * Loads the <code>PolicyDef</code> for the given <code>String</code> identifier by looking first
+	 * for a ".file" property associated with the ID and using that to load from a <code>File</code> and
+	 * looking for a ".url" property associated with the ID and using that to load from a <code>URL</code>.
+	 * 
+	 * @param policyId the <code>String</code> identifier for the policy
+	 * @return a <code>PolicyDef</code> loaded from the given identifier
+	 */
+	protected PolicyDef loadPolicyDef(String policyId) {
+		String propLocation = null;
+		if (this.properties == null) {
+			propLocation	= XACMLProperties.getProperty(policyId + PROP_FILE);
+		} else {
+			propLocation	= this.properties.getProperty(policyId + PROP_FILE);
+		}
+		if (propLocation != null) {
+			File fileLocation	= new File(propLocation);
+			if (!fileLocation.exists()) {
+				XACMLPdpPolicyFinderFactory.logger.error("Policy file " + fileLocation.getAbsolutePath() + " does not exist.");
+			} else if (!fileLocation.canRead()) {
+				XACMLPdpPolicyFinderFactory.logger.error("Policy file " + fileLocation.getAbsolutePath() + " cannot be read.");
+			} else {
+				try {
+					XACMLPdpPolicyFinderFactory.logger.info("Loading policy file " + fileLocation);
+					PolicyDef policyDef	= DOMPolicyDef.load(fileLocation);
+					if (policyDef != null) {
+						return policyDef;
+					}
+				} catch (DOMStructureException ex) {
+					XACMLPdpPolicyFinderFactory.logger.error("Error loading policy file " + fileLocation.getAbsolutePath() + ": " + ex.getMessage(), ex);
+					return new Policy(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+				}
+			}
+		}
+		if (this.properties == null) {
+			propLocation = XACMLProperties.getProperty(policyId + PROP_URL);
+		} else {
+			propLocation = this.properties.getProperty(policyId + PROP_URL);
+		}
+		if (propLocation != null) {
+			 InputStream is = null;
+			try {
+				URL url						= new URL(propLocation);
+				URLConnection urlConnection	= url.openConnection();
+				XACMLPdpPolicyFinderFactory.logger.info("Loading policy file " + url.toString());
+				is = urlConnection.getInputStream();
+				PolicyDef policyDef			= DOMPolicyDef.load(is);
+				if (policyDef != null) {
+					return policyDef;
+				}
+			} catch (MalformedURLException ex) {
+				XACMLPdpPolicyFinderFactory.logger.error("Invalid URL " + propLocation + ": " + ex.getMessage(), ex);
+			} catch (IOException ex) {
+				XACMLPdpPolicyFinderFactory.logger.error("IOException opening URL " + propLocation + ": " + ex.getMessage(), ex);
+			} catch (DOMStructureException ex) {
+				XACMLPdpPolicyFinderFactory.logger.error("Invalid Policy " + propLocation + ": " + ex.getMessage(), ex);
+				return new Policy(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+			} finally {
+				if (is != null) {
+					try {
+						is.close();
+					} catch (IOException e) {
+						XACMLPdpPolicyFinderFactory.logger.error("Exception closing InputStream for GET of url " + propLocation + " : " + e.getMessage() + "  (May be memory leak)", e);
+					}
+				}
+			}
+		}
+		
+		XACMLPdpPolicyFinderFactory.logger.error("No known location for Policy " + policyId);
+		return null;
+	}
+	
+	/**
+	 * Finds the identifiers for all of the policies referenced by the given property name in the
+	 * <code>XACMLProperties</code> and loads them using the requested loading method.
+	 * 
+	 * @param propertyName the <code>String</code> name of the property containing the list of policy identifiers
+	 * @return a <code>List</code> of <code>PolicyDef</code>s loaded from the given property name
+	 */
+	protected List<PolicyDef> getPolicyDefs(String propertyName) {
+		String policyIds	= XACMLProperties.getProperty(propertyName);
+		if (policyIds == null || policyIds.length() == 0) {
+			return null;
+		}
+		
+		Iterable<String> policyIdArray	= Splitter.on(',').trimResults().omitEmptyStrings().split(policyIds);
+		if (policyIdArray == null) {
+			return null;
+		}
+		
+		List<PolicyDef> listPolicyDefs	= new ArrayList<PolicyDef>();
+		for (String policyId : policyIdArray) {
+			PolicyDef policyDef	= this.loadPolicyDef(policyId);	
+			if (policyDef != null) {
+				listPolicyDefs.add(policyDef);
+			}
+		}
+		return listPolicyDefs;
+	}
+	
+	protected synchronized void init() {
+		if (this.needsInit) {
+			if (XACMLPdpPolicyFinderFactory.logger.isDebugEnabled()) {
+				XACMLPdpPolicyFinderFactory.logger.debug("Initializing");
+			}
+			this.rootPolicies		= this.getPolicyDefs(XACMLProperties.PROP_ROOTPOLICIES);
+			this.referencedPolicies	= this.getPolicyDefs(XACMLProperties.PROP_REFERENCEDPOLICIES);
+			if (XACMLPdpPolicyFinderFactory.logger.isDebugEnabled()) {
+				XACMLPdpPolicyFinderFactory.logger.debug("Root Policies: " + this.rootPolicies);
+				XACMLPdpPolicyFinderFactory.logger.debug("Referenced Policies: " + this.referencedPolicies);
+			}
+			this.needsInit	= false;
+		}
+	}
+	
+	@Override
+	public PolicyFinder getPolicyFinder() throws FactoryException {
+		//
+		// Force using any properties that were passed upon construction
+		//
+		return new StdPolicyFinder(this.rootPolicies, this.referencedPolicies, this.properties);
+	}
+
+	@Override
+	public PolicyFinder getPolicyFinder(Properties properties) throws FactoryException {
+		return new StdPolicyFinder(this.rootPolicies, this.referencedPolicies, properties);
+	}
+
+}
diff --git a/openaz-xacml-pdp-rest/src/main/resources/log4j.properties b/openaz-xacml-pdp-rest/src/main/resources/log4j.properties
new file mode 100755
index 0000000..b45fa2f
--- /dev/null
+++ b/openaz-xacml-pdp-rest/src/main/resources/log4j.properties
@@ -0,0 +1,22 @@
+#
+# Use this properties for debugging and development.
+#
+#
+# Set root logger level to DEBUG and its only appender to A1.
+log4j.rootLogger=DEBUG, MAIN_LOG
+
+# A1 is set to be a ConsoleAppender.
+log4j.appender.MAIN_LOG=org.apache.log4j.ConsoleAppender
+
+# A1 uses PatternLayout.
+log4j.appender.MAIN_LOG.layout=org.apache.log4j.PatternLayout
+log4j.appender.MAIN_LOG.layout.ConversionPattern=%d{yyyy_MM_dd_HH_mm_ss_SSS} [%t] %-5p %l- %m%n
+
+#
+# This is specifically for Xacml request/response logging
+#
+log4j.logger.xacml.request=INFO, REQUEST_LOG
+
+log4j.appender.REQUEST_LOG=org.apache.log4j.ConsoleAppender
+log4j.appender.REQUEST_LOG.layout=org.apache.log4j.PatternLayout
+log4j.appender.REQUEST_LOG.layout.ConversionPattern=%d{yyyy_MM_dd_HH_mm_ss_SSS} %m%n
\ No newline at end of file
diff --git a/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpLoader.class b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpLoader.class
new file mode 100644
index 0000000..43eeb50
--- /dev/null
+++ b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpLoader.class
Binary files differ
diff --git a/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpRegisterThread.class b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpRegisterThread.class
new file mode 100644
index 0000000..b43d395
--- /dev/null
+++ b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpRegisterThread.class
Binary files differ
diff --git a/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpServlet$PutRequest.class b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpServlet$PutRequest.class
new file mode 100644
index 0000000..9809046
--- /dev/null
+++ b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpServlet$PutRequest.class
Binary files differ
diff --git a/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpServlet.class b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpServlet.class
new file mode 100644
index 0000000..59e6daa
--- /dev/null
+++ b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpServlet.class
Binary files differ
diff --git a/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/impl/XACMLPdpPIPFinderFactory.class b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/impl/XACMLPdpPIPFinderFactory.class
new file mode 100644
index 0000000..54de986
--- /dev/null
+++ b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/impl/XACMLPdpPIPFinderFactory.class
Binary files differ
diff --git a/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/impl/XACMLPdpPolicyFinderFactory.class b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/impl/XACMLPdpPolicyFinderFactory.class
new file mode 100644
index 0000000..f9825d8
--- /dev/null
+++ b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/impl/XACMLPdpPolicyFinderFactory.class
Binary files differ
diff --git a/openaz-xacml-pdp-rest/target/classes/log4j.properties b/openaz-xacml-pdp-rest/target/classes/log4j.properties
new file mode 100644
index 0000000..b45fa2f
--- /dev/null
+++ b/openaz-xacml-pdp-rest/target/classes/log4j.properties
@@ -0,0 +1,22 @@
+#
+# Use this properties for debugging and development.
+#
+#
+# Set root logger level to DEBUG and its only appender to A1.
+log4j.rootLogger=DEBUG, MAIN_LOG
+
+# A1 is set to be a ConsoleAppender.
+log4j.appender.MAIN_LOG=org.apache.log4j.ConsoleAppender
+
+# A1 uses PatternLayout.
+log4j.appender.MAIN_LOG.layout=org.apache.log4j.PatternLayout
+log4j.appender.MAIN_LOG.layout.ConversionPattern=%d{yyyy_MM_dd_HH_mm_ss_SSS} [%t] %-5p %l- %m%n
+
+#
+# This is specifically for Xacml request/response logging
+#
+log4j.logger.xacml.request=INFO, REQUEST_LOG
+
+log4j.appender.REQUEST_LOG=org.apache.log4j.ConsoleAppender
+log4j.appender.REQUEST_LOG.layout=org.apache.log4j.PatternLayout
+log4j.appender.REQUEST_LOG.layout.ConversionPattern=%d{yyyy_MM_dd_HH_mm_ss_SSS} %m%n
\ No newline at end of file
diff --git a/openaz-xacml-pdp-rest/target/maven-archiver/pom.properties b/openaz-xacml-pdp-rest/target/maven-archiver/pom.properties
new file mode 100644
index 0000000..5eebb03
--- /dev/null
+++ b/openaz-xacml-pdp-rest/target/maven-archiver/pom.properties
@@ -0,0 +1,5 @@
+#Generated by Maven
+#Tue Apr 07 07:42:37 EDT 2015
+version=0.0.1-SNAPSHOT
+groupId=org.openliberty.openaz
+artifactId=openaz-xacml-pdp-rest
diff --git a/openaz-xacml-pdp-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/openaz-xacml-pdp-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
new file mode 100644
index 0000000..667efe3
--- /dev/null
+++ b/openaz-xacml-pdp-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
@@ -0,0 +1,6 @@
+com/att/research/xacml/rest/impl/XACMLPdpPolicyFinderFactory.class
+com/att/research/xacml/rest/XACMLPdpServlet$PutRequest.class
+com/att/research/xacml/rest/XACMLPdpServlet.class
+com/att/research/xacml/rest/XACMLPdpLoader.class
+com/att/research/xacml/rest/impl/XACMLPdpPIPFinderFactory.class
+com/att/research/xacml/rest/XACMLPdpRegisterThread.class
diff --git a/openaz-xacml-pdp-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/openaz-xacml-pdp-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
new file mode 100644
index 0000000..12a596f
--- /dev/null
+++ b/openaz-xacml-pdp-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
@@ -0,0 +1,5 @@
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpLoader.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/impl/XACMLPdpPolicyFinderFactory.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpServlet.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/impl/XACMLPdpPIPFinderFactory.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpRegisterThread.java
diff --git a/openaz-xacml-pdp-rest/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/openaz-xacml-pdp-rest/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/openaz-xacml-pdp-rest/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
diff --git a/openaz-xacml-pdp-rest/target/openaz-xacml-pdp-rest-0.0.1-SNAPSHOT.jar b/openaz-xacml-pdp-rest/target/openaz-xacml-pdp-rest-0.0.1-SNAPSHOT.jar
new file mode 100644
index 0000000..8eca8bd
--- /dev/null
+++ b/openaz-xacml-pdp-rest/target/openaz-xacml-pdp-rest-0.0.1-SNAPSHOT.jar
Binary files differ
diff --git a/openaz-xacml-pdp-rest/xacml.pdp.properties b/openaz-xacml-pdp-rest/xacml.pdp.properties
new file mode 100755
index 0000000..34e6b77
--- /dev/null
+++ b/openaz-xacml-pdp-rest/xacml.pdp.properties
@@ -0,0 +1,53 @@
+# Default XACML Properties File for PDP RESTful servlet
+#
+# Standard API Factories
+#
+xacml.dataTypeFactory=com.att.research.xacml.std.StdDataTypeFactory
+xacml.pdpEngineFactory=com.att.research.xacmlatt.pdp.ATTPDPEngineFactory
+xacml.pepEngineFactory=com.att.research.xacml.std.pep.StdEngineFactory
+# NOT USED SEE BELOW xacml.pipFinderFactory=com.att.research.xacml.std.pip.StdPIPFinderFactory
+xacml.traceEngineFactory=com.att.research.xacml.std.trace.LoggingTraceEngineFactory
+#
+# AT&T PDP Implementation Factories
+#
+xacml.att.evaluationContextFactory=com.att.research.xacmlatt.pdp.std.StdEvaluationContextFactory
+xacml.att.combiningAlgorithmFactory=com.att.research.xacmlatt.pdp.std.StdCombiningAlgorithmFactory
+xacml.att.functionDefinitionFactory=com.att.research.xacmlatt.pdp.std.StdFunctionDefinitionFactory
+# NOT USED SEE BELOW xacml.att.policyFinderFactory=com.att.research.xacmlatt.pdp.std.StdPolicyFinderFactory
+
+#
+# AT&T RESTful PDP Implementation Factories
+#
+xacml.pipFinderFactory=com.att.research.xacml.rest.impl.XACMLPdpPIPFinderFactory
+xacml.att.policyFinderFactory=com.att.research.xacml.rest.XACMLPdpPolicyFinderFactory
+#
+# PDP RESTful API properties
+# 
+# Set this to the address where the XACML-PAP-REST servlet is running
+#
+xacml.rest.pap.url=http://localhost:9090/pap/
+#
+# Give the running PDP an ID for the PAP. The url that its running as is a good choice.
+# The PAP identifies PDP's using the URL of the PDP.
+#
+xacml.rest.pdp.id=http://localhost:8080/pdp/
+#
+# Set the directory where the PDP holds its Policy Cache and PIP Configuration
+#
+xacml.rest.pdp.config=config
+#
+# Initialize register with PAP servlet
+#
+xacml.rest.pdp.register=true
+#
+# Sleep period in seconds between register attempts
+#
+xacml.rest.pdp.register.sleep=15
+#
+# number of attempts to register. -1 means keep trying forever.
+#
+xacml.rest.pdp.register.retries=-1
+#
+# max number of bytes in a POST of a XML/JSON request
+#
+xacml.rest.pdp.maxcontent=32767
\ No newline at end of file
diff --git a/openaz-xacml-pdp/logging.properties b/openaz-xacml-pdp/logging.properties
new file mode 100755
index 0000000..ef56def
--- /dev/null
+++ b/openaz-xacml-pdp/logging.properties
@@ -0,0 +1,9 @@
+handlers = java.util.logging.ConsoleHandler, java.util.logging.FileHandler
+
+.level = ALL
+
+java.util.logging.ConsoleHandler.level = INFO
+java.util.logging.FileHandler.level = INFO
+java.util.logging.FileHandler.pattern=%h/xacml_log%u.log
+java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
+java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
diff --git a/openaz-xacml-pdp/pom.xml b/openaz-xacml-pdp/pom.xml
new file mode 100755
index 0000000..e55bdf4
--- /dev/null
+++ b/openaz-xacml-pdp/pom.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>openaz</artifactId>
+        <groupId>org.openliberty.openaz</groupId>
+        <version>0.0.1-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>openaz-xacml-pdp</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>openaz-xacml</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-codec</groupId>
+            <artifactId>commons-codec</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-logging</groupId>
+            <artifactId>commons-logging</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/ATTPDPEngine.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/ATTPDPEngine.java
new file mode 100755
index 0000000..c3c0bfb
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/ATTPDPEngine.java
@@ -0,0 +1,255 @@
+/*
+ *                        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;
+
+import java.net.URI;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Properties;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.att.research.xacml.api.AttributeCategory;
+import com.att.research.xacml.api.Decision;
+import com.att.research.xacml.api.Request;
+import com.att.research.xacml.api.Response;
+import com.att.research.xacml.api.Result;
+import com.att.research.xacml.api.Status;
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.api.pdp.PDPEngine;
+import com.att.research.xacml.api.pdp.PDPException;
+import com.att.research.xacml.api.pdp.ScopeResolver;
+import com.att.research.xacml.api.trace.TraceEngine;
+import com.att.research.xacml.api.trace.TraceEngineFactory;
+import com.att.research.xacml.api.trace.Traceable;
+import com.att.research.xacml.std.StdIndividualDecisionRequestGenerator;
+import com.att.research.xacml.std.StdMutableResponse;
+import com.att.research.xacml.std.StdMutableResult;
+import com.att.research.xacml.std.StdResult;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.trace.StdTraceEvent;
+import com.att.research.xacml.util.FactoryException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContextFactory;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.policy.PolicyDef;
+import com.att.research.xacmlatt.pdp.policy.PolicyFinderResult;
+
+/**
+ * ATTPDPEngine implements the {@link com.att.research.xacml.api.pdp.PDPEngine} interface using the XACML 3.0 specification.
+ * 
+ * @author car
+ * @version $Revision: 1.3 $
+ */
+public class ATTPDPEngine implements PDPEngine, Traceable {
+	private static final Status		STATUS_ADVICE_NA		= new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Advice not allowed in combined decision");
+	private static final Status		STATUS_OBLIGATIONS_NA	= new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Obligations not allowed in combined decision");
+	private static final Status		STATUS_COMBINE_FAILED	= new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Individual decisions do not match");
+	private static final Result		RESULT_ECTX_NULL		= new StdMutableResult(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Null EvaluationContext"));
+
+	/*
+	 * These are the profiles that this reference implementation of the PDP engine supports
+	 */
+	private static final Set<URI> PROFILES			= new HashSet<URI>();
+	static {
+		PROFILES.add(XACML3.ID_PROFILE_MULTIPLE_COMBINED_DECISION.getUri());
+		PROFILES.add(XACML3.ID_PROFILE_MULTIPLE_REFERENCE.getUri());
+		PROFILES.add(XACML3.ID_PROFILE_MULTIPLE_REPEATED_ATTRIBUTE_CATEGORIES.getUri());
+		PROFILES.add(XACML3.ID_PROFILE_MULTIPLE_SCOPE.getUri());
+		PROFILES.add(XACML3.ID_PROFILE_MULTIPLE_XPATH_EXPRESSION.getUri());
+	}
+	
+	private EvaluationContextFactory evaluationContextFactory;
+	private Decision defaultDecision				= Decision.INDETERMINATE;
+	private ScopeResolver scopeResolver;
+	private TraceEngine traceEngine;
+	private Log logger								= LogFactory.getLog(this.getClass());
+	
+	protected TraceEngine getTraceEngine() {
+		if (this.traceEngine == null) {
+			synchronized(this) {
+				if (this.traceEngine == null) {
+					try {
+						this.traceEngine	= TraceEngineFactory.newInstance().getTraceEngine();
+					} catch (FactoryException ex) {
+						this.logger.error("FactoryException creating TraceEngine instance: " + ex.toString(), ex);
+						throw new IllegalStateException("FactoryException creating TraceEngine instance", ex);
+					}
+				}
+			}
+		}
+		return this.traceEngine;
+	}
+	
+	public ATTPDPEngine(EvaluationContextFactory evaluationContextFactoryIn, ScopeResolver scopeResolverIn) {
+		this.evaluationContextFactory	= evaluationContextFactoryIn;
+		this.scopeResolver				= scopeResolverIn;
+	}
+	
+	public ATTPDPEngine(EvaluationContextFactory evaluationContextFactoryIn, Decision defaultDecisionIn, ScopeResolver scopeResolverIn) {
+		this(evaluationContextFactoryIn, scopeResolverIn);
+		this.defaultDecision	= defaultDecisionIn;
+	}
+	
+	public ATTPDPEngine(EvaluationContextFactory evaluationContextFactoryIn, Decision defaultDecisionIn, ScopeResolver scopeResolverIn, Properties properties) {
+		this(evaluationContextFactoryIn, defaultDecisionIn, scopeResolverIn);
+	}
+	
+	protected Result processRequest(EvaluationContext evaluationContext) {
+		try {
+			PolicyFinderResult<PolicyDef> policyFinderResult	= evaluationContext.getRootPolicyDef();
+			if (policyFinderResult.getStatus() != null && !policyFinderResult.getStatus().isOk()) {
+				return new StdMutableResult(policyFinderResult.getStatus());
+			}
+			PolicyDef policyDefRoot					= policyFinderResult.getPolicyDef();
+			if (policyDefRoot == null) {
+				switch(this.defaultDecision) {
+				case DENY:
+				case NOTAPPLICABLE:
+				case PERMIT:
+					return new StdMutableResult(this.defaultDecision, new StdStatus(StdStatusCode.STATUS_CODE_OK, "No applicable policy"));
+				case INDETERMINATE:
+				case INDETERMINATE_DENY:
+				case INDETERMINATE_DENYPERMIT:
+				case INDETERMINATE_PERMIT:
+					return new StdMutableResult(this.defaultDecision, new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "No applicable policy"));
+				}
+			}
+			Result result	= policyDefRoot.evaluate(evaluationContext);
+			if (result.getStatus().isOk()) {
+				Collection<AttributeCategory> listRequestAttributesIncludeInResult	= evaluationContext.getRequest().getRequestAttributesIncludedInResult();
+				if (listRequestAttributesIncludeInResult != null && listRequestAttributesIncludeInResult.size() > 0) {
+					StdMutableResult stdMutableResult	= new StdMutableResult(result);
+					stdMutableResult.addAttributeCategories(listRequestAttributesIncludeInResult);
+					result	= new StdResult(stdMutableResult);
+				}
+			}
+			return result;
+		} catch (EvaluationException ex) {
+			return new StdMutableResult(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, ex.getMessage()));
+		}
+	}
+	
+	@Override
+	public Response decide(Request pepRequest) throws PDPException {
+		/*
+		 * Validate the request
+		 */
+		TraceEngine traceEngineThis	= this.getTraceEngine();
+		if (traceEngineThis.isTracing()) {
+			traceEngineThis.trace(new StdTraceEvent<Request>("Input Request", this, pepRequest));
+		}
+		Status statusRequest	= pepRequest.getStatus();
+		if (statusRequest != null && !statusRequest.isOk()) {
+			return new StdMutableResponse(statusRequest);
+		}
+		
+		/*
+		 * Split the original request up into individual decision requests
+		 */
+		StdIndividualDecisionRequestGenerator stdIndividualDecisionRequestGenerator	= new StdIndividualDecisionRequestGenerator(this.scopeResolver, pepRequest);
+		/*
+		 * Determine if we are combining multiple results into a single result
+		 */
+		boolean bCombineResults	= pepRequest.getCombinedDecision();
+		StdMutableResult stdResultCombined	= null;
+		
+		/*
+		 * Iterate over all of the individual decision requests and process them, combining them into the final response
+		 */
+		StdMutableResponse stdResponse	= new StdMutableResponse();
+		Iterator<Request> iterRequestsIndividualDecision	= stdIndividualDecisionRequestGenerator.getIndividualDecisionRequests();
+		if (iterRequestsIndividualDecision == null || !iterRequestsIndividualDecision.hasNext()) {
+			return new StdMutableResponse(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "No individual decision requests"));
+		}
+		
+		while (iterRequestsIndividualDecision.hasNext()) {
+			Request requestIndividualDecision	= iterRequestsIndividualDecision.next();
+			if (traceEngineThis.isTracing()) {
+				traceEngineThis.trace(new StdTraceEvent<Request>("Individual Request", this, requestIndividualDecision));
+			}
+			Result resultIndividualDecision		= null;
+			if (requestIndividualDecision.getStatus() != null && !requestIndividualDecision.getStatus().isOk()) {
+				resultIndividualDecision	= new StdMutableResult(requestIndividualDecision.getStatus());
+			} else {
+				EvaluationContext evaluationContext	= this.evaluationContextFactory.getEvaluationContext(requestIndividualDecision);
+				if (evaluationContext == null) {
+					resultIndividualDecision	= RESULT_ECTX_NULL;
+				} else {
+					resultIndividualDecision	= this.processRequest(evaluationContext);
+				}
+			}
+			
+			assert(resultIndividualDecision != null);
+			if (traceEngineThis.isTracing()) {
+				traceEngineThis.trace(new StdTraceEvent<Result>("Individual Result", this, resultIndividualDecision));
+			}
+			if (bCombineResults) {
+				Decision decision	= resultIndividualDecision.getDecision();
+				Status status		= resultIndividualDecision.getStatus();
+				if (resultIndividualDecision.getAssociatedAdvice().size() > 0) {
+					decision	= Decision.INDETERMINATE;
+					status		= STATUS_ADVICE_NA;
+				} else if (resultIndividualDecision.getObligations().size() > 0) {
+					decision	= Decision.INDETERMINATE;
+					status		= STATUS_OBLIGATIONS_NA;
+				}
+				
+				if (stdResultCombined == null) {
+					stdResultCombined	= new StdMutableResult(decision, status);
+				} else {
+					if (stdResultCombined.getDecision() != resultIndividualDecision.getDecision()) {
+						stdResultCombined.setDecision(Decision.INDETERMINATE);
+						stdResultCombined.setStatus(STATUS_COMBINE_FAILED);
+					}
+				}
+				stdResultCombined.addPolicyIdentifiers(resultIndividualDecision.getPolicyIdentifiers());
+				stdResultCombined.addPolicySetIdentifiers(resultIndividualDecision.getPolicySetIdentifiers());
+				stdResultCombined.addAttributeCategories(resultIndividualDecision.getAttributes());
+				if (traceEngineThis.isTracing()) {
+					traceEngineThis.trace(new StdTraceEvent<Result>("Combined result", this, stdResultCombined));
+				}
+			} else {
+				stdResponse.add(resultIndividualDecision);
+			}
+		}
+		
+		if (bCombineResults) {
+			stdResponse.add(stdResultCombined);
+		}
+		return stdResponse;
+	}
+
+	@Override
+	public Collection<URI> getProfiles() {
+		return Collections.unmodifiableCollection(PROFILES);
+	}
+
+	@Override
+	public boolean hasProfile(URI uriProfile) {
+		return PROFILES.contains(uriProfile);
+	}
+
+	@Override
+	public String getTraceId() {
+		return this.getClass().getCanonicalName();
+	}
+
+	@Override
+	public Traceable getCause() {
+		return null;
+	}
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/ATTPDPEngineFactory.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/ATTPDPEngineFactory.java
new file mode 100755
index 0000000..7bd165a
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/ATTPDPEngineFactory.java
@@ -0,0 +1,56 @@
+/*
+ *                        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;
+
+import java.util.Properties;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.att.research.xacml.api.pdp.PDPEngine;
+import com.att.research.xacml.api.pdp.PDPEngineFactory;
+import com.att.research.xacml.util.FactoryException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContextFactory;
+
+/**
+ * ATTPDPEngineFactory extends {@link com.att.research.xacml.api.pdp.PDPEngineFactory} by implementing the abstract
+ * <code>newEngine</code> method to create a {@link ATTPDPEngine} instance and initialize it
+ * with policies and PIP instances based on configuration information provided to the factory.
+ * 
+ * @author car
+ * @version $Revision: 1.4 $
+ */
+public class ATTPDPEngineFactory extends PDPEngineFactory {
+	private Log logger	= LogFactory.getLog(this.getClass());
+	
+	public ATTPDPEngineFactory() {
+	}
+
+	@Override
+	public PDPEngine newEngine() throws FactoryException {
+		EvaluationContextFactory evaluationContextFactory	= EvaluationContextFactory.newInstance();
+		if (evaluationContextFactory == null) {
+			this.logger.error("Null EvaluationContextFactory");
+			throw new FactoryException("Null EvaluationContextFactory");
+		}
+		return new ATTPDPEngine(evaluationContextFactory, this.getDefaultBehavior(), this.getScopeResolver());
+	}
+
+	@Override
+	public PDPEngine newEngine(Properties properties) throws FactoryException {
+		EvaluationContextFactory evaluationContextFactory	= EvaluationContextFactory.newInstance(properties);
+		if (evaluationContextFactory == null) {
+			this.logger.error("Null EvaluationContextFactory");
+			throw new FactoryException("Null EvaluationContextFactory");
+		}
+		return new ATTPDPEngine(evaluationContextFactory, this.getDefaultBehavior(), this.getScopeResolver(), properties);
+	}	
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/Evaluatable.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/Evaluatable.java
new file mode 100755
index 0000000..24adb1d
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/Evaluatable.java
@@ -0,0 +1,23 @@
+/*
+ *                        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.eval;
+
+/**
+ * Evaluatable is the interface objects implement to indicate they can be evaluated with an {@link com.att.research.xacmlatt.pdp.eval.EvaluationContext}
+ * and return an {@link com.att.research.xacmlatt.pdp.eval.EvaluationResult}.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public interface Evaluatable {
+	public EvaluationResult evaluate(EvaluationContext evaluationContext) throws EvaluationException;
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationContext.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationContext.java
new file mode 100755
index 0000000..321fff1
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationContext.java
@@ -0,0 +1,73 @@
+/*
+ *                        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.eval;
+
+import com.att.research.xacml.api.IdReferenceMatch;
+import com.att.research.xacml.api.Request;
+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.api.trace.TraceEngine;
+import com.att.research.xacmlatt.pdp.policy.Policy;
+import com.att.research.xacmlatt.pdp.policy.PolicyDef;
+import com.att.research.xacmlatt.pdp.policy.PolicyFinderResult;
+import com.att.research.xacmlatt.pdp.policy.PolicySet;
+
+/**
+ * EvaluationContext provides the interface that the PDP uses to evaluate its set of Policies and PolicySets against
+ * a {@link com.att.research.xacml.api.Request}.
+ * 
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public interface EvaluationContext extends PIPFinder, TraceEngine {
+	/**
+	 * Gets the original <code>Request</code> provided to the <code>ATTPDPEngine</code>'s <code>decide</code> method.
+	 * 
+	 * @return the <code>Request</code> provided to the <code>ATTPDPEngine</code>'s <code>decide</code> method.
+	 */
+	public Request getRequest();
+	
+	/**
+	 * Gets the root {@link com.att.research.xacmlatt.pdp.policy.PolicyDef} from the policy store
+	 * configured by the particular implementation of the <code>PolicyFinderFactory</code> class.
+	 * 
+	 * @return a <code>PolicyFinderResult</code> with the root <code>PolicyDef</code>
+	 */
+	public abstract PolicyFinderResult<PolicyDef> getRootPolicyDef();
+	
+	/**
+	 * Gets the {@link com.att.research.xacmlatt.pdp.policy.Policy} that matches the given {@link com.att.research.xacml.api.IdReferenceMatch}.
+	 * 
+	 * @param idReferenceMatch the <code>IdReferenceMatch</code> to search for
+	 * @return a <code>PolicyFinderResult</code> with the <code>Policy</code> matching the given <code>IdReferenceMatch</code>
+	 */
+	public abstract PolicyFinderResult<Policy> getPolicy(IdReferenceMatch idReferenceMatch);
+	
+	/**
+	 * Gets the {@link com.att.research.xacmlatt.pdp.policy.PolicySet} that matches the given {@link com.att.research.xacml.api.IdReferenceMatch}.
+	 * 
+	 * @param idReferenceMatch the <code>IdReferenceMatch</code> to search for
+	 * @return a <code>PolicyFinderResult</code> with the <code>PolicySet</code> matching the given <code>IdReferenceMatch</code>.
+	 */
+	public abstract PolicyFinderResult<PolicySet> getPolicySet(IdReferenceMatch idReferenceMatch);
+	
+	/**
+	 * Gets the {@link com.att.research.xacml.api.pip.PIPResponse} containing {@link com.att.research.xacml.api.Attribute}s that
+	 * match the given {@link com.att.research.xacml.api.pip.PIPRequest} from this <code>EvaluationContext</code>.
+	 * 
+	 * @param pipRequest the <code>PIPRequest</code> specifying which <code>Attribute</code>s to retrieve
+	 * @return the <code>PIPResponse</code> containing the {@link com.att.research.xacml.api.Status} and <code>Attribute</code>s
+	 * @throws EvaluationException if there is an error retrieving the <code>Attribute</code>s
+	 */
+	public PIPResponse getAttributes(PIPRequest pipRequest) throws PIPException;
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationContextException.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationContextException.java
new file mode 100755
index 0000000..d814961
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationContextException.java
@@ -0,0 +1,42 @@
+/*
+ *                        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.eval;
+
+/**
+ * EvaluationContextException extends <code>Exception</code> to represent errors thrown by
+ * methods in the {@link EvaluationContext} and {@link EvaluationContextFactory}.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class EvaluationContextException extends Exception {
+	private static final long serialVersionUID = -8270506903118536839L;
+
+	public EvaluationContextException() {
+	}
+
+	public EvaluationContextException(String message) {
+		super(message);
+	}
+
+	public EvaluationContextException(Throwable cause) {
+		super(cause);
+	}
+
+	public EvaluationContextException(String message, Throwable cause) {
+		super(message, cause);
+	}
+
+	public EvaluationContextException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
+		super(message, cause, enableSuppression, writableStackTrace);
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationContextFactory.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationContextFactory.java
new file mode 100755
index 0000000..4f54deb
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationContextFactory.java
@@ -0,0 +1,79 @@
+/*
+ *                        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.eval;
+
+import java.util.Properties;
+
+import com.att.research.xacml.api.Request;
+import com.att.research.xacml.api.pip.PIPFinder;
+import com.att.research.xacml.util.FactoryException;
+import com.att.research.xacml.util.FactoryFinder;
+import com.att.research.xacmlatt.pdp.policy.PolicyFinder;
+import com.att.research.xacmlatt.pdp.util.ATTPDPProperties;
+
+/**
+ * EvaluationContextFactory provides methods for creating {@link EvaluationContext} objects
+ * based on configuration information found in standard places.  (TODO: Detail what these are)
+ * 
+ * @author car
+ * @version $Revision: 1.3 $
+ */
+public abstract class EvaluationContextFactory {
+	private static final String	FACTORYID					= ATTPDPProperties.PROP_EVALUATIONCONTEXTFACTORY;
+	private static final String DEFAULT_FACTORY_CLASSNAME	= "com.att.research.xacmlatt.pdp.std.StdEvaluationContextFactory";
+	
+	protected EvaluationContextFactory() {
+	}
+	
+	protected EvaluationContextFactory(Properties properties) {
+	}
+	
+	public static EvaluationContextFactory newInstance() throws FactoryException {
+		return FactoryFinder.find(FACTORYID, DEFAULT_FACTORY_CLASSNAME, EvaluationContextFactory.class);
+	}
+	
+	public static EvaluationContextFactory newInstance(Properties properties) throws FactoryException {
+		return FactoryFinder.find(FACTORYID, DEFAULT_FACTORY_CLASSNAME, EvaluationContextFactory.class, properties);
+	}
+	
+	public static EvaluationContextFactory newInstance(String className, ClassLoader classLoader) throws FactoryException {
+		return FactoryFinder.newInstance(className, EvaluationContextFactory.class, classLoader, false);
+	}
+
+	public static EvaluationContextFactory newInstance(String className) throws FactoryException {
+		return FactoryFinder.newInstance(className, EvaluationContextFactory.class, null, true);
+	}
+	
+	/**
+	 * Gets a new {@link com.att.research.xacml.pdp.eval.EvaluationContext} for the given {@link com.att.research.xacml.api.Request}.
+	 * 
+	 * @param request the <code>Request</code> for the new <code>EvaluationContext</code>
+	 * @return a new <code>EvaluationContext</code> for the given <code>Request</code>
+	 */
+	public abstract EvaluationContext getEvaluationContext(Request request);
+
+	/**
+	 * Sets the {@link com.att.research.xacmlatt.pdp.policy.PolicyFinder} for this <code>EvaluationContextFactory</code> to an
+	 * explicit instance instead of the default or configured value.
+	 * 
+	 * @param policyFinder the <code>PolicyFinder</code> to use in creating new <code>EvaluationContext</code>s.
+	 */
+	public abstract void setPolicyFinder(PolicyFinder policyFinder);
+	
+	/**
+	 * Sets the {@link com.att.research.xacml.api.pip.PIPFinder} for this <code>EvaluationContextFactory</code> to an
+	 * explicit instance instaed of the default or configured value.
+	 * 
+	 * @param pipFinder the <code>PIPFinder</code> to use in creating new <code>EvaluationContext</code>s.
+	 */
+	public abstract void setPIPFinder(PIPFinder pipFinder);
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationException.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationException.java
new file mode 100755
index 0000000..0a0b49a
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationException.java
@@ -0,0 +1,43 @@
+/*
+ *                        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.eval;
+
+/**
+ * EvaluationException extends <code>Exception</code> to represent errors returned by methods of the
+ * {@link Evaluatable} interface and the {@link Matchable} interface.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class EvaluationException extends Exception {
+	private static final long serialVersionUID = 302250127793947492L;
+
+	public EvaluationException() {
+	}
+
+	public EvaluationException(String message) {
+		super(message);
+	}
+
+	public EvaluationException(Throwable cause) {
+		super(cause);
+	}
+
+	public EvaluationException(String message, Throwable cause) {
+		super(message, cause);
+	}
+
+	public EvaluationException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
+		super(message, cause, enableSuppression, writableStackTrace);
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationResult.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationResult.java
new file mode 100755
index 0000000..78828e5
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationResult.java
@@ -0,0 +1,80 @@
+/*
+ *                        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.eval;
+
+import java.util.Collection;
+
+import com.att.research.xacml.api.Advice;
+import com.att.research.xacml.api.AttributeCategory;
+import com.att.research.xacml.api.Decision;
+import com.att.research.xacml.api.IdReference;
+import com.att.research.xacml.api.Obligation;
+import com.att.research.xacml.api.Status;
+import com.att.research.xacml.std.StdMutableResult;
+
+/**
+ * EvaluationResult extends {@link com.att.research.xacml.std.StdMutableResult} with methods useful within a PDP implementation
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class EvaluationResult extends StdMutableResult {
+	public EvaluationResult() {
+		super();
+	}
+	
+	public EvaluationResult(Decision decisionIn, Status statusIn) {
+		super(decisionIn, statusIn);
+	}
+	
+	public EvaluationResult(Status statusIn) {
+		super(statusIn);
+	}
+	
+	public EvaluationResult(Decision decisionIn) {
+		super(decisionIn);
+	}
+	
+	public EvaluationResult(Decision decisionIn, 
+			Collection<Obligation> obligationsIn, 
+			Collection<Advice> adviceIn, 
+			Collection<AttributeCategory> attributesIn, 
+			Collection<IdReference> policyIdentifiersIn, 
+			Collection<IdReference> policySetIdentifiersIn) {
+		super(decisionIn, obligationsIn, adviceIn, attributesIn, policyIdentifiersIn, policySetIdentifiersIn);
+	}
+	
+	/**
+	 * Creates an <code>EvaluationResult</code> generally from a {@link com.att.research.xacmlatt.pdp.policy.Rule} <code>evaluation</code>
+	 * call.
+	 * 
+	 * @param decisionIn the <code>Decision</code>
+	 * @param obligationsIn the <code>Collection</code> of <code>Obligation</code>s
+	 * @param adviceIn the <code>Collection</code> of <code>Advice</code> objects
+	 */
+	public EvaluationResult(Decision decisionIn, Collection<Obligation> obligationsIn, Collection<Advice> adviceIn) {
+		super(decisionIn, obligationsIn, adviceIn, null, null, null);
+	}
+	
+	public void merge(EvaluationResult evaluationResult) {
+		if (this.getStatus() == null) {
+			this.setStatus(evaluationResult.getStatus());
+		} else {
+			this.getStatus().merge(evaluationResult.getStatus());
+		}
+		this.addObligations(evaluationResult.getObligations());
+		this.addAdvice(evaluationResult.getAssociatedAdvice());
+		this.addAttributeCategories(evaluationResult.getAttributes());
+		this.addPolicyIdentifiers(evaluationResult.getPolicyIdentifiers());
+		this.addPolicySetIdentifiers(evaluationResult.getPolicySetIdentifiers());
+	}
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/MatchResult.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/MatchResult.java
new file mode 100755
index 0000000..4398b79
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/MatchResult.java
@@ -0,0 +1,71 @@
+/*
+ *                        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.eval;
+
+import com.att.research.xacml.api.Status;
+import com.att.research.xacml.std.StdStatus;
+
+/**
+ * MatchResult is the value returned by the {@link Matchable} interface.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class MatchResult {
+	public static enum MatchCode {
+		INDETERMINATE,
+		MATCH,
+		NOMATCH
+	}
+	
+	public static MatchResult	MM_MATCH	= new MatchResult(MatchCode.MATCH);
+	public static MatchResult	MM_NOMATCH	= new MatchResult(MatchCode.NOMATCH);
+	
+	private MatchCode	matchCode;
+	private Status		status;
+	
+	public MatchResult(MatchCode matchCodeIn, Status statusIn) {
+		this.matchCode	= matchCodeIn;
+		this.status		= statusIn;
+	}
+	
+	public MatchResult(MatchCode matchCodeIn) {
+		this(matchCodeIn, StdStatus.STATUS_OK);
+	}
+	
+	public MatchResult(Status statusIn) {
+		this(MatchCode.INDETERMINATE, statusIn);
+	}
+	
+	public MatchCode getMatchCode() {
+		return this.matchCode;
+	}
+	
+	public Status getStatus() {
+		return this.status;
+	}
+	
+	@Override
+	public String toString() {
+		StringBuilder stringBuilder	= new StringBuilder("{");
+		
+		stringBuilder.append("matchCode=");
+		stringBuilder.append(this.getMatchCode());
+		Status thisStatus	= this.getStatus();
+		if (thisStatus != null) {
+			stringBuilder.append(", status=");
+			stringBuilder.append(thisStatus.toString());
+		}
+		stringBuilder.append('}');
+		return stringBuilder.toString();
+	}
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/Matchable.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/Matchable.java
new file mode 100755
index 0000000..0550b07
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/Matchable.java
@@ -0,0 +1,30 @@
+/*
+ *                        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.eval;
+
+/**
+ * Matchable is the interface objects implement to indicate they are part of a XACML Target matching tree.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public interface Matchable {
+	/**
+	 * Matches this <code>Matchable</code> in the given {@link com.att.research.xacmlatt.pdp.eval.EvaluationContext} and
+	 * returns a {@link com.att.research.xacmlatt.pdp.eval.MatchResult}.
+	 * 
+	 * @param evaluationContext the <code>EvaluationContext</code> to use in matching
+	 * @return a <code>MatchResult</code> indicating whether this <code>Matchable</code> matches against the given <code>EvaluationContext</code>.
+	 * @throws EvaluationException if there is an error testing the match.
+	 */
+	public MatchResult match(EvaluationContext evaluationContext) throws EvaluationException;
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/package-info.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/package-info.java
new file mode 100755
index 0000000..eb01ff5
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/package-info.java
@@ -0,0 +1,19 @@
+/*
+ *                        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.eval;
+
+/**
+ * com.att.research.xacmlatt.pdp.eval contains interfaces and classes used in evaluating and matching XACML policy components.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/package-info.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/package-info.java
new file mode 100755
index 0000000..b6c251b
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/package-info.java
@@ -0,0 +1,20 @@
+/*
+ *                        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;
+
+/**
+ * com.att.research.xacmlatt.pdp contains a reference implementation of the {@link com.att.research.xacml.pdp.PDPEngine} interface
+ * developed at AT&T Laboratories.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AdviceExpression.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AdviceExpression.java
new file mode 100755
index 0000000..9ef9adc
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AdviceExpression.java
@@ -0,0 +1,201 @@
+/*
+ *                        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.policy;
+
+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.AttributeAssignment;
+import com.att.research.xacml.api.Decision;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacml.std.StdMutableAdvice;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.util.StringUtils;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+
+/**
+ * AdviceExpression extends {@link PolicyComponent} to implement the XACML AdviceExpression element.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class AdviceExpression extends PolicyComponent {
+	private List<AttributeAssignmentExpression>	listAttributeAssignmentExpressions	= new ArrayList<AttributeAssignmentExpression>();
+	private Identifier adviceId;
+	private RuleEffect appliesTo;
+	
+	protected List<AttributeAssignmentExpression> getAttributeAssignmentExpressionList() {
+		return this.listAttributeAssignmentExpressions;
+	}
+	
+	protected void clearAttributeAssignmentExpressionList() {
+		this.getAttributeAssignmentExpressionList().clear();
+	}
+	
+	public AdviceExpression(StatusCode statusCodeIn, String statusMessageIn) {
+		super(statusCodeIn, statusMessageIn);
+	}
+
+	public AdviceExpression(StatusCode statusCodeIn) {
+		super(statusCodeIn);
+	}
+
+	public AdviceExpression() {
+	}
+	
+	public AdviceExpression(Identifier adviceIdIn, RuleEffect ruleEffectIn, Collection<AttributeAssignmentExpression> attributeAssignmentExpressions) {
+		this.adviceId	= adviceIdIn;
+		this.appliesTo	= ruleEffectIn;
+		if (attributeAssignmentExpressions != null) {
+			this.listAttributeAssignmentExpressions.addAll(attributeAssignmentExpressions);
+		}
+	}
+	
+	public Identifier getAdviceId() {
+		return this.adviceId;
+	}
+	
+	public void setAdviceId(Identifier identifier) {
+		this.adviceId	= identifier;
+	}
+	
+	public RuleEffect getAppliesTo() {
+		return this.appliesTo;
+	}
+	
+	public void setAppliesTo(RuleEffect ruleEffect) {
+		this.appliesTo	= ruleEffect;
+	}
+	
+	public Iterator<AttributeAssignmentExpression> getAttributeAssignmentExpressions() {
+		return this.getAttributeAssignmentExpressionList().iterator();
+	}
+	
+	public void setAttributeAssignmentExpressions(Collection<AttributeAssignmentExpression> attributeAssignmentExpressions) {
+		this.clearAttributeAssignmentExpressionList();
+		if (attributeAssignmentExpressions != null) {
+			
+		}
+	}
+	
+	public void addAttributeAssignmentExpression(AttributeAssignmentExpression attributeAssignmentExpression) {
+		this.getAttributeAssignmentExpressionList().add(attributeAssignmentExpression);
+	}
+	
+	public void addAttributeAssignmentExpressions(Collection<AttributeAssignmentExpression> attributeAssignmentExpressions) {
+		this.getAttributeAssignmentExpressionList().addAll(attributeAssignmentExpressions);
+	}
+	
+	/**
+	 * Evaluates the <code>AttributeAssignmentExpression</code>s in this <code>AdviceExpression</code> to generate an
+	 * {@link com.att.research.xacml.api.Advice} object.
+	 * 
+	 * @param evaluationContext the {@link com.att.research.xacmlatt.pdp.eval.EvaluationContext} in which to evaluate the <code>AttributeAssignmentExpression</code>s
+	 * @param policyDefaults the {@link PolicyDefaults} for the evaluation
+	 * @return a new <code>Advice</code> evaluated from this <code>AdviceExpression</code>
+	 * @throws com.att.research.xacmlatt.pdp.eval.EvaluationException if there is an error in the evaluation
+	 */
+	public Advice evaluate(EvaluationContext evaluationContext, PolicyDefaults policyDefaults) throws EvaluationException {
+		if (!this.validate()) {
+			return null;
+		}
+		
+		List<AttributeAssignment> attributeAssignments	= new ArrayList<AttributeAssignment>();
+		Iterator<AttributeAssignmentExpression> iterAttributeAssignmentExpressions	= this.getAttributeAssignmentExpressions();
+		if (iterAttributeAssignmentExpressions != null) {
+			while (iterAttributeAssignmentExpressions.hasNext()) {
+				AttributeAssignmentResult attributeAssignmentResult	= iterAttributeAssignmentExpressions.next().evaluate(evaluationContext, policyDefaults);
+				if (attributeAssignmentResult.isOk() && attributeAssignmentResult.getNumAttributeAssignments() > 0) {
+					Iterator<AttributeAssignment> iterAttributeAssignments	= attributeAssignmentResult.getAttributeAssignments();
+					while (iterAttributeAssignments.hasNext()) {
+						attributeAssignments.add(iterAttributeAssignments.next());
+					}
+				}
+			}
+		}
+		
+		return new StdMutableAdvice(this.getAdviceId(), attributeAssignments);
+	}
+	
+	/**
+	 * Evaluates a <code>Collection</code> of <code>AdviceExpression</code>s in the given <code>EvaluationContext</code> and returns
+	 * a <code>List</code> of <code>Advice</code>s.
+	 * 
+	 * @param evaluationContext
+	 * @param policyDefaults
+	 * @param listAdviceExpressions
+	 * @return
+	 * @throws com.att.research.xacmlatt.pdp.eval.EvaluationException
+	 */
+	public static List<Advice> evaluate(EvaluationContext evaluationContext, PolicyDefaults policyDefaults, Decision decision, Collection<AdviceExpression> listAdviceExpressions) throws EvaluationException {
+		List<Advice> listAdvices	= new ArrayList<Advice>();
+		Iterator<AdviceExpression> iterAdviceExpressions	= listAdviceExpressions.iterator();
+		while (iterAdviceExpressions.hasNext()) {
+			AdviceExpression adviceExpression	= iterAdviceExpressions.next();
+			adviceExpression.validateComponent();
+			if ( ! adviceExpression.isOk()) {
+				throw new EvaluationException(adviceExpression.getStatusMessage());
+			}
+			if (decision == null || adviceExpression.getAppliesTo().getDecision().equals(decision)) {
+				Advice advice	= adviceExpression.evaluate(evaluationContext, policyDefaults);
+				if (advice != null) {
+					listAdvices.add(advice);
+				}
+			}
+		}
+		return listAdvices;
+	}
+
+	@Override
+	protected boolean validateComponent() {
+		if (this.getAdviceId() == null) {
+			this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing AdviceId");
+			return false;
+		} else if (this.getAppliesTo() == null) {
+			this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing AppliesTo");
+			return false;
+		} else {
+			this.setStatus(StdStatusCode.STATUS_CODE_OK, null);
+			return true;
+		}
+	}
+	
+	@Override
+	public String toString() {
+		StringBuilder stringBuilder	= new StringBuilder("{");
+		
+		stringBuilder.append("super=");
+		stringBuilder.append(super.toString());
+		
+		Object objectToDump;
+		if ((objectToDump = this.getAdviceId()) != null) {
+			stringBuilder.append(",adviceId=");
+			stringBuilder.append(objectToDump.toString());
+		}
+		if ((objectToDump = this.getAppliesTo()) != null) {
+			stringBuilder.append(",appliesTo=");
+			stringBuilder.append(objectToDump.toString());
+		}
+		if ((objectToDump = StringUtils.toString(this.getAttributeAssignmentExpressions())) != null) {
+			stringBuilder.append(",attributeAssignmentExpressions=");
+			stringBuilder.append((String)objectToDump);
+		}
+		
+		stringBuilder.append('}');
+		return stringBuilder.toString();
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AllOf.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AllOf.java
new file mode 100755
index 0000000..721750a
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AllOf.java
@@ -0,0 +1,136 @@
+/*
+ *                        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.policy;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.util.StringUtils;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.eval.MatchResult;
+import com.att.research.xacmlatt.pdp.eval.Matchable;
+
+/**
+ * AnyOf extends {@link com.att.research.xacmlatt.pdp.policy.PolicyComponent} and implements the {@link com.att.research.xacmlatt.pdp.policy.Matchable}
+ * interface to represent XACML AllOf elements in a XACML Target.
+ * 
+ * @author car
+ * @version $Revision
+ */
+public class AllOf extends PolicyComponent implements Matchable {
+	private List<Match>	matches;
+	
+	protected List<Match> getMatchList(boolean bNoNulls) {
+		if (this.matches == null && bNoNulls) {
+			this.matches	= new ArrayList<Match>();
+		}
+		return this.matches;
+	}
+	
+	protected void clearMatchList() {
+		if (this.matches != null) {
+			this.matches.clear();
+		}
+	}
+	
+	public AllOf(StatusCode statusCodeIn, String statusMessageIn) {
+		super(statusCodeIn, statusMessageIn);
+	}
+
+	public AllOf(StatusCode statusCodeIn) {
+		super(statusCodeIn);
+	}
+
+	public AllOf() {
+	}
+	
+	public Iterator<Match> getMatches() {
+		return (this.matches == null ? null : this.matches.iterator());
+	}
+	
+	public void setMatches(Collection<Match> matchesIn) {
+		this.clearMatchList();
+		if (matchesIn != null) {
+			this.addMatches(matchesIn);
+		}
+	}
+	
+	public void addMatch(Match match) {
+		List<Match> matchList	= this.getMatchList(true);
+		matchList.add(match);
+	}
+	
+	public void addMatches(Collection<Match> matchesIn) {
+		List<Match> matchList	= this.getMatchList(true);
+		matchList.addAll(matchesIn);
+	}
+
+	@Override
+	public MatchResult match(EvaluationContext evaluationContext) throws EvaluationException {
+		if (!this.validate()) {
+			return new MatchResult(new StdStatus(this.getStatusCode(), this.getStatusMessage()));
+		}
+		Iterator<Match> iterMatches	= this.getMatches();
+		assert(iterMatches != null && iterMatches.hasNext());
+		
+		MatchResult matchResultFallThrough	= MatchResult.MM_MATCH;
+		while (iterMatches.hasNext()) {
+			MatchResult matchResultMatch	= iterMatches.next().match(evaluationContext);
+			assert(matchResultMatch != null);
+			switch(matchResultMatch.getMatchCode()) {
+			case INDETERMINATE:
+				if (matchResultFallThrough.getMatchCode() != MatchResult.MatchCode.INDETERMINATE) {
+					matchResultFallThrough	= matchResultMatch;
+				}
+				break;
+			case MATCH:
+				break;
+			case NOMATCH:
+				return matchResultMatch;
+			}
+		}
+		return matchResultFallThrough;
+	}
+
+	@Override
+	protected boolean validateComponent() {
+		Iterator<Match>	iterMatches	= this.getMatches();
+		if (iterMatches == null || !iterMatches.hasNext()) {
+			this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing matches");
+			return false;
+		} else {
+			this.setStatus(StdStatusCode.STATUS_CODE_OK, null);
+			return true;
+		}
+	}
+	
+	@Override
+	public String toString() {
+		StringBuilder stringBuilder	= new StringBuilder("{");
+		stringBuilder.append("super=");
+		stringBuilder.append(super.toString());
+
+		String stringMatches	= StringUtils.toString(this.getMatches());
+		if (stringMatches != null) {
+			stringBuilder.append(",matches=");
+			stringBuilder.append(stringMatches);
+		}
+		stringBuilder.append('}');
+		return stringBuilder.toString();
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AnyOf.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AnyOf.java
new file mode 100755
index 0000000..749904f
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AnyOf.java
@@ -0,0 +1,150 @@
+/*
+ *                        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.policy;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.util.StringUtils;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.eval.MatchResult;
+import com.att.research.xacmlatt.pdp.eval.Matchable;
+
+/**
+ * AnyOf extends {@link com.att.research.xacmlatt.pdp.policy.PolicyComponent} and implements the {@link com.att.research.xacmlatt.pdp.policy.Matchable}
+ * interface to represent XACML AnyOf elements in a XACML Target.
+ * 
+ * @author car
+ * @version $Revision
+ */
+public class AnyOf extends PolicyComponent implements Matchable {
+	private List<AllOf>	allOfs;
+	
+	protected List<AllOf> getAllOfList(boolean bNoNull) {
+		if (this.allOfs == null && bNoNull) {
+			this.allOfs	= new ArrayList<AllOf>();
+		}
+		return this.allOfs;
+	}
+	
+	protected void clearAllOfList() {
+		if (this.allOfs != null) {
+			this.allOfs.clear();
+		}
+	}
+	
+	public AnyOf(StatusCode statusCodeIn, String statusMessageIn) {
+		super(statusCodeIn, statusMessageIn);
+	}
+
+	public AnyOf(StatusCode statusCodeIn) {
+		super(statusCodeIn);
+	}
+
+	public AnyOf() {
+	}
+	
+	public AnyOf(Collection<AllOf> allOfsIn) {
+		if (allOfsIn != null) {
+			this.addAllOfs(allOfsIn);
+		}
+	}
+	
+	public Iterator<AllOf> getAllOfs() {
+		return (this.allOfs == null ? null : this.allOfs.iterator());
+	}
+	
+	public void setAllOfs(Collection<AllOf> allOfsIn) {
+		this.clearAllOfList();
+		if (allOfsIn != null) {
+			this.addAllOfs(allOfsIn);
+		}
+	}
+	
+	public void addAllOf(AllOf allOf) {
+		List<AllOf> listAllOfs	= this.getAllOfList(true);
+		listAllOfs.add(allOf);
+	}
+	
+	public void addAllOfs(Collection<AllOf> allOfs) {
+		List<AllOf> listAllOfs	= this.getAllOfList(true);
+		listAllOfs.addAll(allOfs);
+	}
+
+	@Override
+	public MatchResult match(EvaluationContext evaluationContext) throws EvaluationException {
+		if (!this.validate()) {
+			return new MatchResult(new StdStatus(this.getStatusCode(), this.getStatusMessage()));
+		}
+		Iterator<AllOf> iterAllOfs	= this.getAllOfs();
+		if (iterAllOfs == null || !iterAllOfs.hasNext()) {
+			return MatchResult.MM_NOMATCH;
+		}
+		
+		/*
+		 * Assume "No Match" until we find a match or an indeterminate result
+		 */
+		MatchResult matchResultFallThrough	= MatchResult.MM_NOMATCH;
+		while (iterAllOfs.hasNext()) {
+			MatchResult matchResultAllOf	= iterAllOfs.next().match(evaluationContext);
+			assert(matchResultAllOf != null);
+			switch(matchResultAllOf.getMatchCode()) {
+			case INDETERMINATE:
+				/*
+				 * Keep the first indeterminate value to return if no other match is found
+				 */
+				if (matchResultFallThrough.getMatchCode() != MatchResult.MatchCode.INDETERMINATE) {
+					matchResultFallThrough	= matchResultAllOf;
+				}
+				break;
+			case MATCH:
+				return matchResultAllOf;
+			case NOMATCH:
+				break;
+			}
+		}
+		return matchResultFallThrough;
+	}
+
+	@Override
+	protected boolean validateComponent() {
+		Iterator<AllOf>	iterAllOfs	= this.getAllOfs();
+		if (iterAllOfs == null || !iterAllOfs.hasNext()) {
+			this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing AllOf elements in AnyOf");
+			return false;
+		} else {
+			this.setStatus(StdStatusCode.STATUS_CODE_OK, null);
+			return true;
+		}
+	}
+	
+	@Override
+	public String toString() {
+		StringBuilder stringBuilder	= new StringBuilder("{");
+		stringBuilder.append("super=");
+		stringBuilder.append(super.toString());
+		
+		String iterToDump	= StringUtils.toString(this.getAllOfs());
+		if (iterToDump != null) {
+			stringBuilder.append(",allOfs=");
+			stringBuilder.append(iterToDump);
+		}
+		stringBuilder.append('}');
+		return stringBuilder.toString();
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AttributeAssignmentExpression.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AttributeAssignmentExpression.java
new file mode 100755
index 0000000..047fff8
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AttributeAssignmentExpression.java
@@ -0,0 +1,166 @@
+/*
+ *                        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.policy;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.AttributeAssignment;
+import com.att.research.xacml.api.AttributeValue;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacml.std.StdMutableAttributeAssignment;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+
+/**
+ * AttributeAssignmentExpression extends {@link PolicyComponent} to represent a
+ * XACML AttributeAssignmentExpression element.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class AttributeAssignmentExpression extends PolicyComponent {
+	private static final AttributeAssignmentResult AAR_NULL_EXPRESSION			= new AttributeAssignmentResult(new StdStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Null expression"));
+	private static final AttributeAssignmentResult AAR_NULL_EXPRESSION_RESULT	= new AttributeAssignmentResult(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Null expression result"));
+	
+	private Expression expression;
+	private Identifier attributeId;
+	private Identifier category;
+	private String issuer;
+	
+	public AttributeAssignmentExpression(StatusCode statusCodeIn, String statusMessageIn) {
+		super(statusCodeIn, statusMessageIn);
+	}
+
+	public AttributeAssignmentExpression(StatusCode statusCodeIn) {
+		super(statusCodeIn);
+	}
+
+	public AttributeAssignmentExpression() {
+	}
+	
+	public AttributeAssignmentExpression(Identifier categoryIn, Identifier attributeIdIn, String issuerIn, Expression expressionIn) {
+		this.category		= categoryIn;
+		this.attributeId	= attributeIdIn;
+		this.issuer			= issuerIn;
+		this.expression		= expressionIn;
+	}
+	
+	public Identifier getCategory() {
+		return this.category;
+	}
+	
+	public void setCategory(Identifier identifier) {
+		this.category	= identifier;
+	}
+	
+	public Identifier getAttributeId() {
+		return this.attributeId;
+	}
+	
+	public void setAttributeId(Identifier identifier) {
+		this.attributeId	= identifier;
+	}
+	
+	public String getIssuer() {
+		return this.issuer;
+	}
+	
+	public void setIssuer(String string) {
+		this.issuer	= string;
+	}
+	
+	public Expression getExpression() {
+		return this.expression;
+	}
+	
+	public void setExpression(Expression expressionIn) {
+		this.expression	= expressionIn;
+	}
+	
+	public AttributeAssignmentResult evaluate(EvaluationContext evaluationContext, PolicyDefaults policyDefaults) throws EvaluationException {
+		if (!this.validate()) {
+			return new AttributeAssignmentResult(new StdStatus(this.getStatusCode(), this.getStatusMessage()));
+		}
+		
+		Expression thisExpression	= this.getExpression();
+		if (thisExpression == null) {
+			return AAR_NULL_EXPRESSION;
+		}
+		
+		ExpressionResult thisExpressionResult	= thisExpression.evaluate(evaluationContext, policyDefaults);
+		if (thisExpressionResult == null) {
+			return AAR_NULL_EXPRESSION_RESULT;
+		} else if (!thisExpressionResult.isOk()) {
+			return new AttributeAssignmentResult(thisExpressionResult.getStatus());
+		} else {
+			List<AttributeAssignment> listAttributeAssignments	= new ArrayList<AttributeAssignment>();
+			if (thisExpressionResult.isBag()) {
+				Bag bagValues	= thisExpressionResult.getBag();
+				if (bagValues == null || bagValues.size() == 0) {
+					listAttributeAssignments.add(new StdMutableAttributeAssignment(this.getCategory(), this.getAttributeId(), this.getIssuer(), null));
+				} else {
+					Iterator<AttributeValue<?>> iterBagValues	= bagValues.getAttributeValues();
+					while (iterBagValues.hasNext()) {
+						AttributeValue<?> attributeValue	= iterBagValues.next();
+						listAttributeAssignments.add(new StdMutableAttributeAssignment(this.getCategory(), this.getAttributeId(), this.getIssuer(), attributeValue));
+					}
+				}
+			} else {
+				listAttributeAssignments.add(new StdMutableAttributeAssignment(this.getCategory(), this.getAttributeId(), this.getIssuer(), thisExpressionResult.getValue()));
+			}
+			return new AttributeAssignmentResult(listAttributeAssignments);
+		}
+	}
+
+	@Override
+	protected boolean validateComponent() {
+		if (this.getAttributeId() == null) {
+			this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing AttributeId");
+			return false;
+		} else if (this.getExpression() == null) {
+			this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing Expression");
+			return false;
+		} else {
+			this.setStatus(StdStatusCode.STATUS_CODE_OK, null);
+			return true;
+		}
+	}
+	
+	@Override
+	public String toString() {
+		StringBuilder stringBuilder	= new StringBuilder("{");
+		
+		stringBuilder.append("super=");
+		stringBuilder.append(super.toString());
+		
+		Object objectToDump;
+		if ((objectToDump = this.getCategory()) != null) {
+			stringBuilder.append(",category=");
+			stringBuilder.append(objectToDump.toString());
+		}
+		if ((objectToDump = this.getAttributeId()) != null) {
+			stringBuilder.append(",attributeId=");
+			stringBuilder.append(objectToDump.toString());
+		}
+		if ((objectToDump = this.getExpression()) != null) {
+			stringBuilder.append(",expression=");
+			stringBuilder.append(objectToDump.toString());
+		}
+		stringBuilder.append('}');
+		return stringBuilder.toString();
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AttributeAssignmentResult.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AttributeAssignmentResult.java
new file mode 100755
index 0000000..cc6c549
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AttributeAssignmentResult.java
@@ -0,0 +1,95 @@
+/*
+ *                        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.policy;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.AttributeAssignment;
+import com.att.research.xacml.api.Status;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.util.StringUtils;
+
+/**
+ * AttributeAssignmentResult is the object returned by the <code>evaluate</code> method of an {@link com.att.research.xacmlatt.pdp.policy.AttributeAssignmentExpression}.
+ * It contains a {@link com.att.research.xacml.api.Status} and an optional collection of {@link com.att.research.xacml.api.AttributeAssignment}
+ * elements.
+ * 
+ * @author car
+ * @version $Revision$
+ */
+public class AttributeAssignmentResult {
+	private Status status;
+	private List<AttributeAssignment> listAttributeAssignments;
+	
+	protected List<AttributeAssignment> getListAttributeAssignments() {
+		return this.listAttributeAssignments;
+	}
+	
+	public AttributeAssignmentResult(Status statusIn, Collection<AttributeAssignment> listAttributeAssignmentsIn) {
+		this.status	= statusIn;
+		if (listAttributeAssignmentsIn != null && listAttributeAssignmentsIn.size() > 0) {
+			this.listAttributeAssignments	= new ArrayList<AttributeAssignment>();
+			this.listAttributeAssignments.addAll(listAttributeAssignmentsIn);
+		}
+	}
+	
+	public AttributeAssignmentResult(Status statusIn) {
+		this(statusIn, null);
+	}
+	
+	public AttributeAssignmentResult(Collection<AttributeAssignment> listAttributeAssignmentsIn) {
+		this(StdStatus.STATUS_OK, listAttributeAssignmentsIn);
+	}
+
+	public Status getStatus() {
+		return this.status;
+	}
+	
+	public boolean isOk() {
+		return (this.getStatus() == null || this.getStatus().isOk());
+	}
+	
+	public Iterator<AttributeAssignment> getAttributeAssignments() {
+		List<AttributeAssignment> thisListAttributeAssignments	= this.getListAttributeAssignments();
+		return (thisListAttributeAssignments == null ? null : thisListAttributeAssignments.iterator());
+	}
+	
+	public int getNumAttributeAssignments() {
+		List<AttributeAssignment> thisListAttributeAssignments	= this.getListAttributeAssignments();
+		return (thisListAttributeAssignments == null ? 0 : thisListAttributeAssignments.size());
+	}
+
+	@Override
+	public String toString() {
+		StringBuilder stringBuilder	= new StringBuilder("{");
+		boolean needsComma	= false;
+		
+		Object objectToDump;
+		if ((objectToDump = this.getStatus()) != null) {
+			stringBuilder.append("status=");
+			stringBuilder.append(objectToDump.toString());
+			needsComma	= true;
+		}
+		
+		Iterator<?> iterToDump;
+		if ((iterToDump = this.getAttributeAssignments()) != null) {
+			if (needsComma) {
+				stringBuilder.append(',');
+			}
+			stringBuilder.append(StringUtils.toString(iterToDump));
+		}
+		stringBuilder.append('}');
+		return stringBuilder.toString();
+	}
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Bag.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Bag.java
new file mode 100755
index 0000000..47b7773
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Bag.java
@@ -0,0 +1,93 @@
+/*
+ *                        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.policy;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.AttributeValue;
+
+/**
+ * Bag represents a collection of XACML attribute values for the same attribute.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class Bag {
+	public static final Bag	EMPTY	= new Bag();
+	
+	private List<AttributeValue<?>> attributeValues	= new ArrayList<AttributeValue<?>>();
+
+	/**
+	 * Gets the <code>List</code> of <code>AttributeValue</code>s for this <code>Bag</code>.
+	 * 
+	 * @return the <code>List</code> of <code>AttributeValue</code>s for this <code>Bag</code>
+	 */
+	public List<AttributeValue<?>> getAttributeValueList() {
+		return this.attributeValues;
+	}
+	
+	/**
+	 * Creates a new, empty <code>Bag</code>.
+	 */
+	public Bag() {
+	}
+	
+	/**
+	 * Creates a new <code>Bag</code> by copying the {@link com.att.research.xacml.api.AttributeValue}s from the
+	 * given <code>Collection</code>.
+	 * 
+	 * @param attributeValuesIn the <code>Collection</code> of <code>AttributeValue</code>s for this <code>Bag</code>.
+	 *
+	public Bag(Collection<AttributeValue<?>> attributeValuesIn) {
+		if (attributeValuesIn != null) {
+			this.attributeValues.addAll(attributeValuesIn);
+		}
+	}
+	
+	public Bag(Iterator<AttributeValue<?>> iterAttributeValuesIn) {
+		if (iterAttributeValuesIn != null) {
+			while (iterAttributeValuesIn.hasNext()) {
+				this.attributeValues.add(iterAttributeValuesIn.next());
+			}
+		}
+	}
+	*/
+	
+	/**
+	 * Adds an <code>AttributeValue</code> to this <code>Bag</code>>
+	 * 
+	 * @param attributeValue the <code>AttributeValue</code> to add
+	 */
+	public void add(AttributeValue<?> attributeValue) {
+		this.attributeValues.add(attributeValue);
+	}
+	
+	/**
+	 * Gets the number of <code>AttributeValue</code>s in this <code>Bag</code>.
+	 * 
+	 * @return the number of <code>AttributeValue</code>s in this <code>Bag</code>.
+	 */
+	public int size() {
+		return this.getAttributeValueList().size();
+	}
+	
+	/**
+	 * Gets an <code>Iterator</code> over all of the <code>AttributeValue</code>s in this <code>Bag</code>.
+	 * 
+	 * @return an <code>Iterator</code> over all of the <code>AttributeValue</code>s in this <code>Bag</code>.
+	 */
+	public Iterator<AttributeValue<?>> getAttributeValues() {
+		return this.getAttributeValueList().iterator();
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombinerParameter.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombinerParameter.java
new file mode 100755
index 0000000..8277428
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombinerParameter.java
@@ -0,0 +1,149 @@
+/*
+ *                        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.policy;
+
+import com.att.research.xacml.api.AttributeValue;
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacml.std.StdStatusCode;
+
+/**
+ * CombinerParameter extends {@link PolicyComponent} to represent a XACML CombinerParameter element.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class CombinerParameter extends PolicyComponent {
+	private String 				name;
+	private AttributeValue<?>	attributeValue;
+	
+	@Override
+	protected boolean validateComponent() {
+		if (this.getName() == null) {
+			this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing parameter name");
+			return false;
+		} else if (this.getAttributeValue() == null) {
+			this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing attribute value");
+			return false;
+		} else {
+			this.setStatus(StdStatusCode.STATUS_CODE_OK, null);
+			return true;
+		}
+	}
+	
+	/**
+	 * Creates a new <code>CombinerParameter</code> with the given <code>String</code> name, <code>AttributeValue</code>,
+	 * {@link com.att.research.xacml.api.StatusCode} and <code>String</code> status message.
+	 * 
+	 * @param nameIn the <code>String</code> name of the <code>CombinerParameter</code>
+	 * @param attributeValueIn the <code>AttributeValue</code> of the <code>CombinerParameter</code>
+	 * @param statusCodeIn the <code>StatusCode</code> of the <code>CombinerParameter</code>
+	 * @param statusMessageIn the <code>String</code> status message of the <code>CombinerParameter</code>
+	 */
+	public CombinerParameter(String nameIn, AttributeValue<?> attributeValueIn, StatusCode statusCodeIn, String statusMessageIn) {
+		super(statusCodeIn, statusMessageIn);
+		this.name			= nameIn;
+		this.attributeValue	= attributeValueIn;
+	}
+	
+	/**
+	 * Creates a new <code>CombinerParameter</code> for an error condition with the given <code>StatusCode</code> and
+	 * <code>String</code> status message.
+	 * 
+	 * @param statusCodeIn the <code>StatusCode</code> of the <code>CombinerParameter</code>
+	 * @param statusMessageIn the <code>String</code> status message of the <code>CombinerParameter</code>
+	 */
+	public CombinerParameter(StatusCode statusCodeIn, String statusMessageIn) {
+		super(statusCodeIn, statusMessageIn);
+	}
+
+	/**
+	 * Creates a new <code>CombinerParameter</code> for an error condition with the given <code>StatusCode</code> and
+	 * null status message.
+	 * 
+	 * @param statusCodeIn the <code>StatusCode</code> of the <code>CombinerParameter</code>
+	 */
+	public CombinerParameter(StatusCode statusCodeIn) {
+		super(statusCodeIn);
+	}
+
+	/**
+	 * Creates a new <code>CombinerParameter</code> with a default <code>StatusCode</code>, null status message, and the given
+	 * <code>String</code> name and <code>AttributeValue</code>>
+	 * 
+	 * @param nameIn the <code>String</code> name of the <code>CombinerParameter</code>
+	 * @param attributeValueIn the <code>AttributeValue</code> of the <code>CombinerParameter</code>
+	 */
+	public CombinerParameter(String nameIn, AttributeValue<?> attributeValueIn) {
+		super();
+		this.name			= nameIn;
+		this.attributeValue	= attributeValueIn;
+	}
+	
+	public CombinerParameter() {
+		
+	}
+	
+	/**
+	 * Gets the <code>String</code> name of this <code>CombinerParameter</code>.
+	 * 
+	 * @return the <code>String</code> name of this <code>CombinerParameter</code>
+	 */
+	public String getName() {
+		return this.name;
+	}
+	
+	/**
+	 * Sets the name of this <code>CombinerParameter</code> to the given <code>String</code>.
+	 * 
+	 * @param nameIn the <code>String</code> name for this <code>CombinerParameter</code>.
+	 */
+	public void setName(String nameIn) {
+		this.name	= nameIn;
+	}
+	
+	/**
+	 * Gets the <code>AttributeValue</code> of this <code>CombinerParameter</code>.
+	 * 
+	 * @return the <code>AttributeValue</code> of this <code>CombinerParameter</code>
+	 */
+	public AttributeValue<?> getAttributeValue() {
+		return this.attributeValue;
+	}
+	
+	/**
+	 * Sets the <code>AttributeValue</code> for this <code>CombinerParameter</code>>
+	 * 
+	 * @param attributeValueIn the <code>AttributeValue</code> for this <code>CombinerParameter</code>>
+	 */
+	public void setAttributeValue(AttributeValue<?> attributeValueIn) {
+		this.attributeValue	= attributeValueIn;
+	}
+
+	@Override
+	public String toString() {
+		StringBuilder stringBuilder	= new StringBuilder("{");
+		stringBuilder.append("super=");
+		stringBuilder.append(super.toString());
+		
+		Object objectToDump;
+		if ((objectToDump = this.getName()) != null) {
+			stringBuilder.append(",name=");
+			stringBuilder.append((String)objectToDump);
+		}
+		if ((objectToDump = this.getAttributeValue()) != null) {
+			stringBuilder.append(",attributeValue=");
+			stringBuilder.append(objectToDump.toString());
+		}
+		stringBuilder.append('}');
+		return stringBuilder.toString();
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombiningAlgorithm.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombiningAlgorithm.java
new file mode 100755
index 0000000..d161efa
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombiningAlgorithm.java
@@ -0,0 +1,49 @@
+/*
+ *                        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.policy;
+
+import java.util.List;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacmlatt.pdp.eval.Evaluatable;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationResult;
+
+/**
+ * CombiningAlgorithm is the interface for objects that implement XACML combining algorithms for rules, policies, and policy sets.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ *
+ * @param <T> the type of object to be combined
+ * @param <U> the type of the identifier for <code>T</code>
+ */
+public interface CombiningAlgorithm<T extends Evaluatable> {
+	/**
+	 * Gets the {@link com.att.research.xacml.api.Identifier} for this <code>CombiningAlgorithm</code>.
+	 * 
+	 * @return the <code>Identifier</code> for this <code>CombiningAlgorithm</code>
+	 */
+	public Identifier getId();
+	
+	/**
+	 * Evaluates as many of the <code>CombiningElement</code>s supplied with the given <code>CombinerParameter</code>s based on
+	 * the particular combining algorithm and combines their <code>EvaluationResult</code>s into a single <code>EvaluationResult</code>.
+	 * 
+	 * @param evaluationContext the <code>EvaluationContext</code> in which to evaluate each of the <code>CombiningElement</code>s
+	 * @param elements the <code>List</code> of <code>CombiningElement</code>s to evaluate
+	 * @param combinerParameters the <code>List</code> of <code>CombinerParameter</code>s to apply to the combining algorithm
+	 * @return the combined <code>EvaluationResult</code>
+	 * @throws com.att.research.xacmlatt.pdp.eval.EvaluationException if there is an error in the <code>evaluate</code> method of any of the <code>CombiningElement</code>s
+	 */
+	public EvaluationResult combine(EvaluationContext evaluationContext, List<CombiningElement<T>> elements, List<CombinerParameter> combinerParameters) throws EvaluationException;
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombiningAlgorithmFactory.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombiningAlgorithmFactory.java
new file mode 100755
index 0000000..b6b278e
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombiningAlgorithmFactory.java
@@ -0,0 +1,91 @@
+/*
+ *                        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.policy;
+
+import java.util.Properties;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.util.FactoryException;
+import com.att.research.xacml.util.FactoryFinder;
+import com.att.research.xacmlatt.pdp.util.ATTPDPProperties;
+
+/**
+ * CombiningAlgorithmFactory is an abstract class for mapping function {@link com.att.research.xacml.api.Identifier} ids to
+ * {@link CombiningAlgorithm} objects.
+ * 
+ * @author car
+ * @version $Revision: 1.3 $
+ */
+public abstract class CombiningAlgorithmFactory {
+	private static final String	FACTORYID					= ATTPDPProperties.PROP_COMBININGALGORITHMFACTORY;
+	private static final String DEFAULT_FACTORY_CLASSNAME	= "com.att.research.xacmlatt.pdp.std.StdCombiningAlgorithmFactory";
+	
+	protected CombiningAlgorithmFactory() {
+	}
+	
+	protected CombiningAlgorithmFactory(Properties properties) {
+	}
+	
+	/**
+	 * Maps the given <code>Identifier</code> representing a XACML rule combining algorithm to a <code>CombiningAlgorithm</code> object.
+	 * 
+	 * @param combiningAlgorithmId the <code>Identifier</code> of the <code>CombiningAlgorithm</code> to retrieve
+	 * @return the <code>CombiningAlgorithm</code> for the given <code>Identifier</code> or null if not found
+	 */
+	public abstract CombiningAlgorithm<Rule> getRuleCombiningAlgorithm(Identifier combiningAlgorithmId);
+	
+	/**
+	 * Maps the given <code>Identifier</code> representing a XACML policy combinign algorithm to a <code>CombiningAlgorithm</code> object.
+	 * 
+	 * @param combiningAlgorithmId the <code.Identifier</code> of the <code>CombiningAlgorithm</code> to retrieve
+	 * @return the <code>CombiningAlgorithm</code> for the given <code>Identifier</code> or null if not found
+	 */
+	public abstract CombiningAlgorithm<PolicySetChild> getPolicyCombiningAlgorithm(Identifier combiningAlgorithmId);
+	
+	/**
+	 * Creates an instance of the <code>CombiningAlgorithmFactory</code> using default configuration information.
+	 * 
+	 * @return the default <code>CombiningAlgorithmFactory</code>
+	 */
+	public static CombiningAlgorithmFactory newInstance() throws FactoryException {
+		return FactoryFinder.find(FACTORYID, DEFAULT_FACTORY_CLASSNAME, CombiningAlgorithmFactory.class);
+	}
+	
+	/**
+	 * Creates an instance of the <code>CombiningAlgorithmFactory</code> using default configuration information.
+	 * 
+	 * @return the default <code>CombiningAlgorithmFactory</code>
+	 */
+	public static CombiningAlgorithmFactory newInstance(Properties properties) throws FactoryException {
+		return FactoryFinder.find(FACTORYID, DEFAULT_FACTORY_CLASSNAME, CombiningAlgorithmFactory.class, properties);
+	}
+	
+	/**
+	 * Creates an instance of the <code>CombiningAlgorithmFactory</code> using the given class name.
+	 * 
+	 * @param className the <code>String</code> class name of the <code>CombiningAlgorithmFactory</code> to create
+	 * @return the <code>CombiningAlgorithmFactory</code> for the given class name.
+	 */
+	public static CombiningAlgorithmFactory newInstance(String className) throws FactoryException {
+		return FactoryFinder.newInstance(className, CombiningAlgorithmFactory.class, null, true);
+	}
+	
+	/**
+	 * Creates an instance of the <code>CombiningAlgorithmFactory</code> using the given class name using the given <code>ClassLoader</code>.
+	 * 
+	 * @param className the <code>String</code> class name of the <code>CombiningAlgorithmFactory</code> to create
+	 * @param classLoader the <code>ClassLoader</code> to use to load the class with the given class name
+	 * @return the <code>CombiningAlgorithmFactory</code> for the given class name
+	 */
+	public static CombiningAlgorithmFactory newInstance(String className, ClassLoader classLoader) throws FactoryException {
+		return FactoryFinder.newInstance(className, CombiningAlgorithmFactory.class, classLoader, false);
+	}
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombiningElement.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombiningElement.java
new file mode 100755
index 0000000..8890b1a
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombiningElement.java
@@ -0,0 +1,82 @@
+/*
+ *                        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.policy;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacmlatt.pdp.eval.Evaluatable;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationResult;
+
+/**
+ * CombiningElement wraps an {@link com.att.research.xacmlatt.pdp.evl.Evaluatable} with a set of
+ * {@link com.att.research.xacmlatt.pdp.policy.TargetedCombinerParameter}s for use with a 
+ * {@link com.att.research.xacmlatt.pdp.policy.CombiningAlgorithm} to get a combined {@link com.att.research.xacmlatt.pdp.eval.EvaluationResult}
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ * 
+ * @param <T> the java class extending <code>Evaluatable</code> of the objects to be combined
+ */
+public class CombiningElement<T extends Evaluatable> {
+	private T										evaluatable;
+	private List<CombinerParameter>	targetedCombinerParameters;
+	
+	/**
+	 * Creates a new <code>CombiningElement</code> with the given <code>Evaluatable</code> and <code>List</code> of
+	 * <code>TargetedCombinerParameter</code>.
+	 * 
+	 * @param evaluatableIn the <code>Evaluatable</code>
+	 * @param targetedCombinerParametersIn the <code>List</code> of <code>TargetedCombinerParameter</code>s.
+	 */
+	public CombiningElement(T evaluatableIn, Collection<CombinerParameter> targetedCombinerParametersIn) {
+		this.evaluatable	= evaluatableIn;
+		if (targetedCombinerParametersIn != null) {
+			this.targetedCombinerParameters	= new ArrayList<CombinerParameter>();
+			this.targetedCombinerParameters.addAll(targetedCombinerParametersIn);
+		}
+	}
+	
+	/**
+	 * Gets the <code>Evaluatable</code> for this <code>CombiningElement</code>.
+	 * 
+	 * @return the <code>Evaluatable</code> for this <code>CombiningElement</code>
+	 */
+	public T getEvaluatable() {
+		return this.evaluatable;
+	}
+	
+	/**
+	 * Gets an <code>Iterator</code> over the <code>TargetedCombinerParameters</code> for this
+	 * <code>CombiningElement</code>.
+	 * 
+	 * @return an <code>Iterator</code> over the <code>TargetedCombinerParameters</code> for this <code>CombiningElement</code>
+	 */
+	public Iterator<CombinerParameter> getTargetedCombinerParameters() {
+		return (this.targetedCombinerParameters == null ? null : this.targetedCombinerParameters.iterator());
+	}
+	
+	/**
+	 * Evaluates this <code>CombiningElement</code> in the given {@link com.att.research.xacmlatt.pdp.eval.EvaluationContext}.
+	 * 
+	 * @param evaluationContext the <code>EvaluationContext</code>
+	 * @return the {@link com.att.research.xacmlatt.pdp.eval.EvaluationResult} from the <code>Evaluatable</code>
+	 * @throws com.att.research.xacmlatt.pdp.eval.EvaluationException if there is an error in the <code>evaluate</code> method of the <code>Evaluatable</code>
+	 */
+	public EvaluationResult evaluate(EvaluationContext evaluationContext) throws EvaluationException {
+		return this.getEvaluatable().evaluate(evaluationContext);
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Condition.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Condition.java
new file mode 100755
index 0000000..0f02f78
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Condition.java
@@ -0,0 +1,149 @@
+/*
+ *                        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.policy;
+
+import com.att.research.xacml.api.AttributeValue;
+import com.att.research.xacml.api.DataTypeException;
+import com.att.research.xacml.api.Status;
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.datatypes.DataTypes;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+
+/**
+ * Condition extends {@link com.att.research.xacmlatt.pdp.policy.PolicyComponent} to represent the XACML Condition element
+ * in a XACML Rule.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class Condition extends PolicyComponent {
+	private static final Status						STATUS_PE_RETURNED_BAG			= new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Condition Expression returned a bag");
+	private static final ExpressionResultBoolean	ERB_RETURNED_BAG				= new ExpressionResultBoolean(STATUS_PE_RETURNED_BAG);
+	private static final Status 					STATUS_PE_RETURNED_NULL			= new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Null value from Condition Expression");
+	private static final ExpressionResultBoolean	ERB_RETURNED_NULL				= new ExpressionResultBoolean(STATUS_PE_RETURNED_NULL);
+	private static final Status 					STATUS_PE_RETURNED_NON_BOOLEAN	= new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Non-boolean value from Condition Expression");
+	private static final ExpressionResultBoolean	ERB_RETURNED_NON_BOOLEAN		= new ExpressionResultBoolean(STATUS_PE_RETURNED_NON_BOOLEAN);
+	private static final Status						STATUS_PE_INVALID_BOOLEAN		= new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Invalid Boolean value");
+	private static final ExpressionResultBoolean	ERB_INVALID_BOOLEAN				= new ExpressionResultBoolean(STATUS_PE_INVALID_BOOLEAN);
+	
+	private Expression expression;
+	
+	/**
+	 * Creates a <code>Condition</code> with the given {@link com.att.research.xacml.api.StatusCode} and <code>String</code>
+	 * status message.
+	 * 
+	 * @param statusCodeIn the <code>StatusCode</code> for the <code>Condition</code>
+	 * @param statusMessageIn the <code>String</code> status message for the <code>Condition</code>
+	 */
+	public Condition(StatusCode statusCodeIn, String statusMessageIn) {
+		super(statusCodeIn, statusMessageIn);
+	}
+
+	/**
+	 * Creates a <code>Condition</code> with the given <code>StatusCode</code. and a null status message.
+	 * 
+	 * @param statusCodeIn the <code>StatusCode</code> for the <code>Condition</code>
+	 */
+	public Condition(StatusCode statusCodeIn) {
+		super(statusCodeIn);
+	}
+
+	/**
+	 * Creates an empty <code>Condition</code>
+	 */
+	public Condition() {
+	}
+	
+	/**
+	 * Creates a new <code>Condition</code> with the given {@link com.att.research.xacmlatt.pdp.policy.Expression} and a default
+	 * OK <code>StatusCode</code>.
+	 * 
+	 * @param expressionIn the <code>Expression</code> for the <code>Condition</code>
+	 */
+	public Condition(Expression expressionIn) {
+		this.expression	= expressionIn;
+	}
+	
+	public Expression getExpression() {
+		return this.expression;
+	}
+	
+	public void setExpression(Expression expressionIn) {
+		this.expression	= expressionIn;
+	}
+
+	@Override
+	protected boolean validateComponent() {
+		if (this.getExpression() == null) {
+			this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing Expression");
+			return false;
+		} else {
+			this.setStatus(StdStatusCode.STATUS_CODE_OK, null);
+			return true;
+		}
+	}
+
+	/**
+	 * Evaluates the <code>Expression</code> in this <code>Condition</code> in the given {@link com.att.research.xacmlatt.pdp.eval.EvaluationContext}.
+	 * and validates that the result is a boolean.
+	 * 
+	 * @param evaluationContext the <code>EvaluationContext</code> in which to evaluate this <code>Expression</code>
+	 * @param policyDefaults the {@link com.att.research.xacml.pdp.policy.PolicyDefaults} to use in evaluating this <code>Expression</code>
+	 * @return a {@link com.att.research.xacmlatt.pdp.policy.ExpressionResult}
+	 */
+	public ExpressionResultBoolean evaluate(EvaluationContext evaluationContext, PolicyDefaults policyDefaults) throws EvaluationException {
+		if (!this.validate()) {
+			return new ExpressionResultBoolean(new StdStatus(this.getStatusCode(), this.getStatusMessage()));
+		}
+		
+		/*
+		 * Evaluate the expression
+		 */
+		ExpressionResult expressionResult	= this.getExpression().evaluate(evaluationContext, policyDefaults);
+		assert(expressionResult != null);
+		
+		if (!expressionResult.isOk()) {
+			return new ExpressionResultBoolean(expressionResult.getStatus());
+		}
+		
+		/*
+		 * Ensure the result is a single element of type boolean
+		 */
+		if (expressionResult.isBag()) {
+			return ERB_RETURNED_BAG;
+		}
+		AttributeValue<?> attributeValueResult	= expressionResult.getValue();
+		if (attributeValueResult == null) {
+			return ERB_RETURNED_NULL;
+		} else if (!DataTypes.DT_BOOLEAN.getId().equals(attributeValueResult.getDataTypeId())) {
+			return ERB_RETURNED_NON_BOOLEAN;
+		}
+		
+		/*
+		 * Otherwise it is a valid condition evaluation
+		 */
+		Boolean	booleanValue	= null;
+		try {
+			booleanValue	= DataTypes.DT_BOOLEAN.convert(attributeValueResult.getValue());
+		} catch (DataTypeException ex) {
+			return new ExpressionResultBoolean(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, ex.getMessage()));
+		}
+		if (booleanValue == null) {
+			return ERB_INVALID_BOOLEAN;
+		} else {
+			return (booleanValue.booleanValue() ? ExpressionResultBoolean.ERB_TRUE : ExpressionResultBoolean.ERB_FALSE);
+		}
+	}
+	
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Expression.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Expression.java
new file mode 100755
index 0000000..c40c41a
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Expression.java
@@ -0,0 +1,44 @@
+/*
+ *                        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.policy;
+
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+
+/**
+ * Expression extends {@link com.att.research.xacmlatt.pdp.policy.PolicyComponent} to represent a XACML ExpressionType element.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public abstract class Expression extends PolicyComponent {
+
+	public Expression(StatusCode statusCodeIn, String statusMessageIn) {
+		super(statusCodeIn, statusMessageIn);
+	}
+
+	public Expression(StatusCode statusCodeIn) {
+		super(statusCodeIn);
+	}
+
+	public Expression() {
+	}
+	
+	/**
+	 * Evaluates this <code>Expression</code> in the given {@link com.att.research.xacmlatt.pdp.eval.EvaluationContext}.
+	 * 
+	 * @param evaluationContext the <code>EvaluationContext</code> in which to evaluate this <code>Expression</code>
+	 * @param policyDefaults the {@link com.att.research.xacml.pdp.policy.PolicyDefaults} to use in evaluating this <code>Expression</code>
+	 * @return a {@link com.att.research.xacmlatt.pdp.policy.ExpressionResult}
+	 */
+	public abstract ExpressionResult evaluate(EvaluationContext evaluationContext, PolicyDefaults policyDefaults) throws EvaluationException;
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/ExpressionResult.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/ExpressionResult.java
new file mode 100755
index 0000000..778861f
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/ExpressionResult.java
@@ -0,0 +1,254 @@
+/*
+ *                        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.policy;
+
+import java.util.Iterator;
+
+import com.att.research.xacml.api.AttributeValue;
+import com.att.research.xacml.api.Status;
+import com.att.research.xacml.std.StdStatus;
+
+/**
+ * ExpressionResult is the object returned by the <code>evaluate</code> method of {@link Expression}
+ * objects.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public abstract class ExpressionResult implements FunctionArgument {
+	private Status	status;
+
+	/**
+	 * ExpressionResultError extends <code>ExpressionResult</code> to represent error results.
+	 * 
+	 * @author car
+	 * @version $Revision: 1.1 $
+	 */
+	private static class ExpressionResultError extends ExpressionResult {
+		public ExpressionResultError(Status statusIn) {
+			super(statusIn);
+		}
+
+		@Override
+		public AttributeValue<?> getValue() {
+			return null;
+		}
+
+		@Override
+		public boolean isBag() {
+			return false;
+		}
+
+		@Override
+		public Bag getBag() {
+			return null;
+		}
+	}
+	
+	/**
+	 * ExpressionResultSingle extends <code>ExpressionResult</code> to represent results with a single value.
+	 * 
+	 * @author car
+	 * @version $Revision: 1.1 $
+	 */
+	private static class ExpressionResultSingle extends ExpressionResult {
+		AttributeValue<?>	attributeValue;
+		
+		public ExpressionResultSingle(AttributeValue<?> attributeValueIn) {
+			super(StdStatus.STATUS_OK);
+			this.attributeValue	= attributeValueIn;
+		}
+
+		@Override
+		public AttributeValue<?> getValue() {
+			return this.attributeValue;
+		}
+
+		@Override
+		public boolean isBag() {
+			return false;
+		}
+
+		@Override
+		public Bag getBag() {
+			return null;
+		}
+	}
+	
+	private static class ExpressionResultBag extends ExpressionResult {
+		private Bag bag;
+		
+		public ExpressionResultBag(Bag bagIn) {
+			super(StdStatus.STATUS_OK);
+			this.bag	= bagIn;
+		}
+		
+		@Override
+		public AttributeValue<?> getValue() {
+			Iterator<AttributeValue<?>> iter	= this.bag.getAttributeValues();
+			if (iter != null && iter.hasNext()) {
+				return iter.next();
+			} else {
+				return null;
+			}
+		}
+
+		@Override
+		public boolean isBag() {
+			return true;
+		}
+
+		@Override
+		public Bag getBag() {
+			return this.bag;
+		}
+	}
+	
+	private static class ExpressionResultEmptyBag extends ExpressionResult {
+		public ExpressionResultEmptyBag() {
+			super(StdStatus.STATUS_OK);
+		}
+
+		@Override
+		public AttributeValue<?> getValue() {
+			return null;
+		}
+
+		@Override
+		public boolean isBag() {
+			return true;
+		}
+
+		@Override
+		public Bag getBag() {
+			return Bag.EMPTY;
+		}
+	}
+	
+	/**
+	 * Creates a new <code>ExpressionResult</code> with the given {@link com.att.research.xacml.api.Status}.
+	 * 
+	 * @param statusIn the <code>Status</code> of this <code>ExpressionResult</code>
+	 */
+	protected ExpressionResult(Status statusIn) {
+		this.status	= statusIn;
+	}
+	
+	/**
+	 * Gets the <code>Status</code> for this <code>ExpressionResult</code>.
+	 * 
+	 * @return the <code>Status</code> for this <code>ExpressionResult</code>
+	 */
+	public Status getStatus() {
+		return this.status;
+	}
+	
+	/**
+	 * Shortcut procedure for determining if the <code>Status</code> of this <code>ExpressionResult</code> is OK.
+	 * 
+	 * @return true if the <code>Status</code> is null or has a <code>StatusCode</code> value of <code>STATUS_CODE_OK</code>.
+	 */
+	public boolean isOk() {
+		return (this.getStatus() == null || this.getStatus().isOk());
+	}
+	
+	/**
+	 * Gets the single {@link com.att.research.xacml.api.AttributeValue} from this <code>ExpressionResult</code>.  If this
+	 * <code>ExpressionResult</code> represents a bag, the first element in the bag is returned.
+	 * 
+	 * @return a single <code>AttributeValue</code> from this <code>ExpressionResult</code>
+	 */
+	public abstract AttributeValue<?> getValue();
+	
+	/**
+	 * Determines if this <code>ExpressionResult</code> represents a bag of <code>AttributeValue</code>s or not.
+	 * 
+	 * @return true if this <code>ExpressionResult</code> represents a bag of <code>AttributeValue</code>s, else false
+	 */
+	public abstract boolean isBag();
+	
+	/**
+	 * Gets the {@link Bag} of values for this <code>ExpressionResult</code> if
+	 * there is one.
+	 * 
+	 * @return the <code>Bag</code> of <code>AttributeValue</code>s for this <code>ExpressionResult</code>.
+	 */
+	public abstract Bag getBag();
+	
+	@Override
+	public String toString() {
+		StringBuilder stringBuilder	= new StringBuilder("{");
+		stringBuilder.append("isOk=" + this.isOk());
+		stringBuilder.append(", isBag=" + this.isBag());
+		Status thisStatus	= this.getStatus();
+		if (thisStatus != null) {
+			stringBuilder.append(", status=");
+			stringBuilder.append(thisStatus.toString());
+		}
+		AttributeValue<?> value = this.getValue();
+		if (value != null) {
+			stringBuilder.append(", value=");
+			stringBuilder.append(value);
+		}
+		/*
+		 * Not sure if I want this dumped
+		if (this.isBag()) {
+			Bag bag = this.getBag();
+			if (bag != null) {
+			}
+		}
+		*/
+		stringBuilder.append('}');
+		return stringBuilder.toString();
+	}
+	/**
+	 * Creates a new instance of the <code>ExpressionResult</code> class representing an error.
+	 * 
+	 * @param statusIn the <code>Status</code> containing the error information
+	 * @return a new <code>ExpressionResult</code> representing the error
+	 */
+	public static ExpressionResult newError(Status statusIn) {
+		return new ExpressionResultError(statusIn);
+	}
+	
+	public static ExpressionResult newSingle(AttributeValue<?> attributeValue) {
+		return new ExpressionResultSingle(attributeValue);
+	}
+	
+	/**
+	 * Creates a new instance of the <code>ExpressionResult</code> class representing a bag of values 
+	 * from the given <code>Bag</code>.
+	 * 
+	 * @param bag the <code>Bag</code> for the new <code>ExpressionResult</code>
+	 * @return a new <code>ExpressionResult</code> representing the given <code>Bag</code>.
+	 */
+	public static ExpressionResult newBag(Bag bag) {
+		return new ExpressionResultBag(bag);
+	}
+	
+	/**
+	 * Creates a new instance of the <code>ExpressionResult</code> class representing an empty bag of values.
+	 * 
+	 * @return the <code>ExpressionResult</code> representing the empty bag of values of the expression
+	 */
+	public static ExpressionResult newEmpty() {
+		return new ExpressionResultEmptyBag();
+	}
+	
+	public static ExpressionResult newInstance(Status statusIn) {
+		if (statusIn.getStatusCode().equals(StdStatus.STATUS_OK.getStatusCode())) {
+			return newEmpty();
+		} else {
+			return newError(statusIn);
+		}
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/ExpressionResultBoolean.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/ExpressionResultBoolean.java
new file mode 100755
index 0000000..3554dfa
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/ExpressionResultBoolean.java
@@ -0,0 +1,65 @@
+/*
+ *                        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.policy;
+
+import com.att.research.xacml.api.AttributeValue;
+import com.att.research.xacml.api.Status;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.datatypes.DataTypeBoolean;
+
+/**
+ * ExpressionResultBoolean extends {@link ExpressionResult} to represent predicates.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class ExpressionResultBoolean extends ExpressionResult {
+	private AttributeValue<Boolean>	value;
+	public static final ExpressionResultBoolean	ERB_FALSE						= new ExpressionResultBoolean(false);
+	public static final ExpressionResultBoolean	ERB_TRUE						= new ExpressionResultBoolean(true);
+	
+	public ExpressionResultBoolean(Status statusIn) {
+		super(statusIn);
+	}
+	
+	public ExpressionResultBoolean(boolean bvalue) {
+		super(StdStatus.STATUS_OK);
+		this.value	= (bvalue ? DataTypeBoolean.AV_TRUE : DataTypeBoolean.AV_FALSE);
+	}
+	
+	/**
+	 * Gets the <code>boolean</code> value of this <code>ExpressionResultBoolean</code>
+	 * 
+	 * @return the <code>boolean</code> value of this <code>ExpressionResultBoolean</code>
+	 */
+	public boolean isTrue() {
+		if (this.value == null) {
+			return false;
+		} else {
+			return this.value.getValue().booleanValue();
+		}
+	}
+
+	@Override
+	public AttributeValue<?> getValue() {
+		return this.value;
+	}
+
+	@Override
+	public boolean isBag() {
+		return false;
+	}
+
+	@Override
+	public Bag getBag() {
+		return null;
+	}
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgument.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgument.java
new file mode 100755
index 0000000..207da3d
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgument.java
@@ -0,0 +1,62 @@
+/*
+ *                        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.policy;
+
+import com.att.research.xacml.api.AttributeValue;
+import com.att.research.xacml.api.Status;
+
+/**
+ * FunctionArgument is the interface implemented by objects that can serve as arguments to a {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition}
+ * <code>evaluate</code> call.
+ * 
+ * @author car
+ * @version $Revision: 1.3 $
+ */
+public interface FunctionArgument {
+	/**
+	 * Gets the {@link com.att.research.xacml.api.Status} from the evaluation of this <code>FunctionArgument</code>.
+	 * 
+	 * @return the <code>Status</code> from the evaluation of this <code>FunctionArgument</code>>
+	 */
+	public Status getStatus();
+	
+	/**
+	 * Determines if this <code>FunctionArgument</code> is OK and can have its <code>AttributeValue</code> or
+	 * <code>Bag</code> retrieved.
+	 * 
+	 * @return true if this <code>FunctionArgument</code> is OK, otherwise false.
+	 */
+	public boolean isOk();
+	
+	/**
+	 * Determines if this <code>FunctionArgument</code> represents a bag of values.
+	 * 
+	 * @return true if this <code>FunctionArgument</code> represents a bag of values, else false.
+	 */
+	public boolean isBag();
+	
+	/**
+	 * Gets the single <code>AttributeValue</code> representing the value of this <code>FunctionArgument</code>.  If
+	 * this <code>FunctionArgument</code> represents a bag, the value returned is up to the implementation.
+	 * 
+	 * @return the single <code>AttributeValue</code> representing the value of this <code>FunctionArgument</code>.
+	 */
+	public AttributeValue<?> getValue();
+	
+	/**
+	 * Gets the {@link Bag} value for this <code>FunctionArgument</code> if the
+	 * argument represents a <code>Bag</code>, (i.e. <code>isBag</code> returns true).
+	 * 
+	 * @return the <code>Bag</code> value for this <code>FunctionArgument</code>.
+	 */
+	public Bag getBag();
+	
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgumentAttributeValue.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgumentAttributeValue.java
new file mode 100755
index 0000000..d81c14b
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgumentAttributeValue.java
@@ -0,0 +1,59 @@
+/*
+ *                        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.policy;
+
+import com.att.research.xacml.api.AttributeValue;
+import com.att.research.xacml.api.Status;
+import com.att.research.xacml.std.StdStatus;
+
+/**
+ * FunctionArgumentAttributeValue implements {@link FunctionArgument} for a single
+ * {@link com.att.research.xacml.api.AttributeValue} 
+ * @author car
+ *
+ */
+public class FunctionArgumentAttributeValue implements FunctionArgument {
+	private AttributeValue<?> attributeValue;
+	
+	/**
+	 * Creates a new <code>FunctionArgumentAttributeValue</code> from the given <code>AttributeValue</code>.
+	 * 
+	 * @param attributeValueIn the <code>AttributeValue</code> for the new <code>FunctionArgumentAttributeValue</code>.
+	 */
+	public FunctionArgumentAttributeValue(AttributeValue<?> attributeValueIn) {
+		this.attributeValue	= attributeValueIn;
+	}
+	
+	@Override
+	public Status getStatus() {
+		return StdStatus.STATUS_OK;
+	}
+	
+	@Override
+	public boolean isOk() {
+		return true;
+	}
+
+	@Override
+	public boolean isBag() {
+		return false;
+	}
+
+	@Override
+	public AttributeValue<?> getValue() {
+		return this.attributeValue;
+	}
+
+	@Override
+	public Bag getBag() {
+		return null;
+	}
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgumentBag.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgumentBag.java
new file mode 100755
index 0000000..9fc66cd
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgumentBag.java
@@ -0,0 +1,67 @@
+/*
+ *                        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.policy;
+
+import java.util.Iterator;
+
+import com.att.research.xacml.api.AttributeValue;
+import com.att.research.xacml.api.Status;
+import com.att.research.xacml.std.StdStatus;
+
+/**
+ * FunctionArgumentBag implements the {@link FunctionArgument} interface for
+ * a {@link Bag} objects.
+ * 
+ * @author car
+ * @version $Revision: 1.3 $
+ */
+public class FunctionArgumentBag implements FunctionArgument {
+	private Bag	bag;
+	
+	/**
+	 * Creates a new <code>FunctionArgumentBag</code> from the given <code>Bag</code>.
+	 * 
+	 * @param bagIn the <code>Bag</code> for the new <code>FunctionArgumentBag</code>.
+	 */
+	public FunctionArgumentBag(Bag bagIn) {
+		this.bag	= bagIn;
+	}
+	
+	@Override
+	public Status getStatus() {
+		return StdStatus.STATUS_OK;
+	}
+	
+	@Override
+	public boolean isOk() {
+		return true;
+	}
+
+	@Override
+	public boolean isBag() {
+		return true;
+	}
+
+	@Override
+	public AttributeValue<?> getValue() {
+		Iterator<AttributeValue<?>> iterAttributeValues	= this.bag.getAttributeValues();
+		if (iterAttributeValues == null || !iterAttributeValues.hasNext()) {
+			return null;
+		} else {
+			return iterAttributeValues.next();
+		}
+	}
+
+	@Override
+	public Bag getBag() {
+		return this.bag;
+	}
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgumentExpression.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgumentExpression.java
new file mode 100755
index 0000000..5845280
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgumentExpression.java
@@ -0,0 +1,113 @@
+/*
+ *                        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.policy;
+
+import com.att.research.xacml.api.AttributeValue;
+import com.att.research.xacml.api.Status;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+
+/**
+ * FunctionArgumentExpression implements the {@link FunctionArgument} interface for
+ * unevaluated {@link Expression}s.
+ * 
+ * @author car
+ * @version $Revision: 1.3 $
+ */
+public class FunctionArgumentExpression implements FunctionArgument {
+	private static final Status STATUS_NULL_EXPRESSION_RESULT	= new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Null expression result");
+	
+	private Expression expression;
+	private EvaluationContext evaluationContext;
+	private ExpressionResult expressionResult;
+	private PolicyDefaults policyDefaults;
+	
+	protected ExpressionResult evaluateExpression() {
+		if (this.getExpression() != null && this.getEvaluationContext() != null) {
+			try {
+				this.expressionResult	= this.getExpression().evaluate(this.getEvaluationContext(), this.getPolicyDefaults());
+			} catch (EvaluationException ex) {
+				this.expressionResult	= ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, ex.getMessage()));
+			}
+		}
+		return this.expressionResult;
+	}
+	
+	public FunctionArgumentExpression() {
+	}
+	
+	public FunctionArgumentExpression(Expression expressionIn, EvaluationContext evaluationContextIn, PolicyDefaults policyDefaultsIn) {
+		this.expression			= expressionIn;
+		this.evaluationContext	= evaluationContextIn;
+		this.policyDefaults		= policyDefaultsIn;
+	}
+	
+	protected ExpressionResult getExpressionResult() {
+		return this.expressionResult;
+	}
+	
+	protected Expression getExpression() {
+		return this.expression;
+	}
+	
+	protected EvaluationContext getEvaluationContext() {
+		return this.evaluationContext;
+	}
+	
+	protected PolicyDefaults getPolicyDefaults() {
+		
+		return this.policyDefaults;
+	}
+
+	@Override
+	public Status getStatus() {
+		ExpressionResult thisExpressionResult	= this.getExpressionResult();
+		if (thisExpressionResult == null) {
+			thisExpressionResult	= this.evaluateExpression();
+		}
+		return (thisExpressionResult == null ? STATUS_NULL_EXPRESSION_RESULT : thisExpressionResult.getStatus());
+	}
+	
+	@Override
+	public boolean isOk() {
+		Status thisStatus	= this.getStatus();
+		return (thisStatus == null ? true : thisStatus.isOk());
+	}
+
+	@Override
+	public boolean isBag() {
+		ExpressionResult thisExpressionResult	= this.getExpressionResult();
+		if (thisExpressionResult == null) {
+			thisExpressionResult	= this.evaluateExpression();
+		}
+		return (thisExpressionResult == null ? false : thisExpressionResult.isBag());
+	}
+
+	@Override
+	public AttributeValue<?> getValue() {
+		ExpressionResult thisExpressionResult	= this.getExpressionResult();
+		if (thisExpressionResult == null) {
+			thisExpressionResult	= this.evaluateExpression();
+		}
+		return (thisExpressionResult == null ? null : thisExpressionResult.getValue());
+	}
+
+	@Override
+	public Bag getBag() {
+		ExpressionResult thisExpressionResult	= this.getExpressionResult();
+		if (thisExpressionResult == null) {
+			thisExpressionResult	= this.evaluateExpression();
+		}
+		return (thisExpressionResult == null ? null : thisExpressionResult.getBag());
+	}
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionDefinition.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionDefinition.java
new file mode 100755
index 0000000..d112318
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionDefinition.java
@@ -0,0 +1,56 @@
+/*
+ *                        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.policy;
+
+import java.util.List;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+
+/**
+ * FunctionDefinition is the interface that objects representing XACML functions found in Match and Apply elements in Policies, PolicySets
+ * and Rules.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public interface FunctionDefinition {
+	/**
+	 * Gets the {@link com.att.research.xacml.api.Identifier} for this <code>FunctionDefinition</code>.
+	 * 
+	 * @return the <code>Identifier</code> for this <code>FunctionDefinition</code>.
+	 */
+	public Identifier getId();
+	
+	/**
+	 * Returns the <code>Identifier</code> for the data type returned by this function if <code>returnsBag()</code> is false or
+	 * if this <code>FunctionDefinition</code> returns a bag containing a single data type.  Otherwise it returns null.
+	 * 
+	 * @return the <code>Identifier</code> for the XACML data type this <code>FunctionDefinition</code> returns
+	 */
+	public Identifier getDataTypeId();
+	
+	/**
+	 * Determines if this <code>FunctionDefinition</code> returns a bag of values or a single value.
+	 * 
+	 * @return true if this <code>FunctionDefinition</code> returns a bag, else false
+	 */
+	public boolean returnsBag();
+	
+	/**
+	 * Evaluates this <code>FunctionDefinition</code> on the given <code>List</code> of{@link FunctionArgument}s.
+	 * 
+	 * @param evaluationContext the {@link com.att.research.xacmlatt.pdp.eval.EvaluationContext} to use in the evaluation
+	 * @param arguments the <code>List</code> of <code>FunctionArgument</code>s for the evaluation
+	 * @return an {@link ExpressionResult} with the results of the call
+	 */
+	public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments);
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionDefinitionFactory.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionDefinitionFactory.java
new file mode 100755
index 0000000..f204729
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionDefinitionFactory.java
@@ -0,0 +1,83 @@
+/*
+ *                        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.policy;
+
+import java.util.Properties;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.util.FactoryException;
+import com.att.research.xacml.util.FactoryFinder;
+import com.att.research.xacmlatt.pdp.util.ATTPDPProperties;
+
+/**
+ * FunctionDefinitionFactory is an abstract class for mapping function {@link com.att.research.xacml.api.Identifier} ids to
+ * {@link FunctionDefinition} objects.
+ * 
+ * @author car
+ * @version $Revision: 1.3 $
+ */
+public abstract class FunctionDefinitionFactory {
+	private static final String	FACTORYID					= ATTPDPProperties.PROP_FUNCTIONDEFINITIONFACTORY;
+	private static final String DEFAULT_FACTORY_CLASSNAME	= "com.att.research.xacmlatt.pdp.std.StdFunctionDefinitionFactory";
+	
+	protected FunctionDefinitionFactory() {
+	}
+	
+	protected FunctionDefinitionFactory(Properties properties) {
+	}
+	
+	/**
+	 * Maps the given <code>Identifier</code> representing a XACML function to a <code>FunctionDefinition</code> object.
+	 * 
+	 * @param functionId the <code>Identifier</code> of the <code>FunctionDefinition</code> to retrieve
+	 * @return the <code>FunctionDefinition</code> for the given <code>Identifier</code> or null if not found
+	 */
+	public abstract FunctionDefinition getFunctionDefinition(Identifier functionId);
+	
+	/**
+	 * Creates an instance of the <code>FunctionDefinitionFactory</code> using default configuration information.
+	 * 
+	 * @return the default <code>FunctionDefinitionFactory</code>
+	 */
+	public static FunctionDefinitionFactory newInstance() throws FactoryException {
+		return FactoryFinder.find(FACTORYID, DEFAULT_FACTORY_CLASSNAME, FunctionDefinitionFactory.class);
+	}
+	
+	/**
+	 * Creates an instance of the <code>FunctionDefinitionFactory</code> using default configuration information.
+	 * 
+	 * @return the default <code>FunctionDefinitionFactory</code>
+	 */
+	public static FunctionDefinitionFactory newInstance(Properties properties) throws FactoryException {
+		return FactoryFinder.find(FACTORYID, DEFAULT_FACTORY_CLASSNAME, FunctionDefinitionFactory.class, properties);
+	}
+	
+	/**
+	 * Creates an instance of the <code>FunctionDefinitionFactory</code> using the given class name.
+	 * 
+	 * @param className the <code>String</code> class name of the <code>FunctionDefinitionFactory</code> to create
+	 * @return the <code>FunctionDefinitionFactory</code> for the given class name.
+	 */
+	public static FunctionDefinitionFactory newInstance(String className) throws FactoryException {
+		return FactoryFinder.newInstance(className, FunctionDefinitionFactory.class, null, true);
+	}
+	
+	/**
+	 * Creates an instance of the <code>FunctionDefinitionFactory</code> using the given class name using the given <code>ClassLoader</code>.
+	 * 
+	 * @param className the <code>String</code> class name of the <code>FunctionDefinitionFactory</code> to create
+	 * @param classLoader the <code>ClassLoader</code> to use to load the class with the given class name
+	 * @return the <code>FunctionDefinitionFactory</code> for the given class name
+	 */
+	public static FunctionDefinitionFactory newInstance(String className, ClassLoader classLoader) throws FactoryException {
+		return FactoryFinder.newInstance(className, FunctionDefinitionFactory.class, classLoader, false);
+	}
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Match.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Match.java
new file mode 100755
index 0000000..d32b8cc
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Match.java
@@ -0,0 +1,243 @@
+/*
+ *                        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.policy;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.AttributeValue;
+import com.att.research.xacml.api.DataTypeException;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacml.api.XACML;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.datatypes.DataTypes;
+import com.att.research.xacml.util.FactoryException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.eval.MatchResult;
+import com.att.research.xacmlatt.pdp.eval.Matchable;
+import com.att.research.xacmlatt.pdp.policy.expressions.AttributeRetrievalBase;
+
+/**
+ * Match extends {@link com.att.research.xacmlatt.pdp.policy.PolicyComponent} and implements the
+ * {@link com.att.research.xacmlatt.pdp.eval.Matchable} interface to represent a XACML Match element.
+ * 
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class Match extends PolicyComponent implements Matchable {
+	private Identifier				matchId;
+	private AttributeValue<?>		attributeValue;
+	private AttributeRetrievalBase	attributeRetrievalBase;
+	private PolicyDefaults			policyDefaults;
+	private FunctionDefinition		functionDefinition;
+	
+	protected FunctionDefinition getFunctionDefinition() {
+		Identifier functionDefinitionId	= this.getMatchId();
+		if (this.functionDefinition == null && functionDefinitionId != null) {
+			try {
+				this.functionDefinition	= FunctionDefinitionFactory.newInstance().getFunctionDefinition(functionDefinitionId);
+			} catch (FactoryException ex) {
+				this.setStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "FactoryException getting FunctionDefinition");
+			}
+		}
+		return this.functionDefinition;
+	}
+	
+	public Match(StatusCode statusCodeIn, String statusMessageIn) {
+		super(statusCodeIn, statusMessageIn);
+	}
+
+	public Match(StatusCode statusCodeIn) {
+		super(statusCodeIn);
+	}
+
+	public Match() {
+	}
+	
+	public Match(Identifier matchIdIn, AttributeValue<?> attributeValueIn, AttributeRetrievalBase attributeRetrievalBaseIn, PolicyDefaults policyDefaultsIn) {
+		this(StdStatusCode.STATUS_CODE_OK);
+		this.matchId				= matchIdIn;
+		this.attributeValue			= attributeValueIn;
+		this.attributeRetrievalBase	= attributeRetrievalBaseIn;
+		this.policyDefaults			= policyDefaultsIn;
+	}
+	
+	public Identifier getMatchId() {
+		return this.matchId;
+	}
+	
+	public void setMatchId(Identifier matchIdIn) {
+		this.matchId	= matchIdIn;
+	}
+	
+	public AttributeValue<?> getAttributeValue() {
+		return this.attributeValue;
+	}
+	
+	public void setAttributeValue(AttributeValue<?> attributeValueIn) {
+		this.attributeValue	= attributeValueIn;
+	}
+	
+	public AttributeRetrievalBase getAttributeRetrievalBase() {
+		return this.attributeRetrievalBase;
+	}
+	
+	public void setAttributeRetrievalBase(AttributeRetrievalBase attributeRetrievalBaseIn) {
+		this.attributeRetrievalBase	= attributeRetrievalBaseIn;
+	}
+	
+	public PolicyDefaults getPolicyDefaults() {
+		return this.policyDefaults;
+	}
+	
+	public void setPolicyDefaults(PolicyDefaults policyDefaultsIn) {
+		this.policyDefaults	= policyDefaultsIn;
+	}
+
+	private static MatchResult match(EvaluationContext evaluationContext, FunctionDefinition functionDefinition, FunctionArgument arg1, FunctionArgument arg2) throws EvaluationException {
+		List<FunctionArgument> listArguments	= new ArrayList<FunctionArgument>(2);
+		listArguments.add(arg1);
+		listArguments.add(arg2);
+		
+		ExpressionResult expressionResult	= functionDefinition.evaluate(evaluationContext, listArguments);
+		assert(expressionResult != null);
+		if (!expressionResult.isOk()) {
+			return new MatchResult(expressionResult.getStatus());
+		}
+		
+		AttributeValue<Boolean> attributeValueResult	= null;
+		try {
+			attributeValueResult	= DataTypes.DT_BOOLEAN.convertAttributeValue(expressionResult.getValue());
+		} catch (DataTypeException ex) {
+			return new MatchResult(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, ex.getMessage()));
+		}
+		if (attributeValueResult == null) {
+			return new MatchResult(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Non-boolean result from Match Function " + functionDefinition.getId() + " on " + expressionResult.getValue().toString()));
+		} else if (attributeValueResult.getValue().booleanValue()) {
+			return MatchResult.MM_MATCH;
+		} else {
+			return MatchResult.MM_NOMATCH;
+		}
+		
+	}
+	
+	@Override
+	public MatchResult match(EvaluationContext evaluationContext) throws EvaluationException {
+		if (!this.validate()) {
+			return new MatchResult(new StdStatus(this.getStatusCode(), this.getStatusMessage()));
+		}
+		
+		FunctionDefinition functionDefinitionMatch		= this.getFunctionDefinition();
+		assert(functionDefinitionMatch != null);
+		
+		AttributeValue<?> attributeValue				= this.getAttributeValue();
+		assert(attributeValue != null);
+		FunctionArgument functionArgument1				= new FunctionArgumentAttributeValue(attributeValue);
+		
+		AttributeRetrievalBase attributeRetrievalBase	= this.getAttributeRetrievalBase();
+		assert(attributeRetrievalBase != null);
+		
+		ExpressionResult expressionResult	= attributeRetrievalBase.evaluate(evaluationContext, this.getPolicyDefaults());
+		assert(expressionResult != null);
+		if (!expressionResult.isOk()) {
+			return new MatchResult(expressionResult.getStatus());
+		}
+		
+		if (expressionResult.isBag()) {
+			MatchResult matchResult	= MatchResult.MM_NOMATCH;
+			Bag bagAttributeValues	= expressionResult.getBag();
+			if (bagAttributeValues != null) {
+				Iterator<AttributeValue<?>> iterAttributeValues	= bagAttributeValues.getAttributeValues();
+				while (matchResult.getMatchCode() != MatchResult.MatchCode.MATCH && iterAttributeValues.hasNext()) {
+					MatchResult matchResultValue	= match(evaluationContext, functionDefinitionMatch, functionArgument1, new FunctionArgumentAttributeValue(iterAttributeValues.next()));
+					switch(matchResultValue.getMatchCode()) {
+					case INDETERMINATE:
+						if (matchResult.getMatchCode() != MatchResult.MatchCode.INDETERMINATE) {
+							matchResult	= matchResultValue;
+						}
+						break;
+					case MATCH:
+						matchResult	= matchResultValue;
+						break;
+					case NOMATCH:
+						break;
+					}
+				}
+			}
+			return matchResult;
+		} else {
+			/*
+			 * There is a single value, so add it as the second argument and do the one function evaluation
+			 */
+			AttributeValue<?> attributeValueExpressionResult	= expressionResult.getValue();
+			if (attributeValueExpressionResult == null) {
+				return new MatchResult(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Null AttributeValue"));
+			}
+			
+			return match(evaluationContext, functionDefinitionMatch, functionArgument1, new FunctionArgumentAttributeValue(attributeValueExpressionResult));
+		}
+	}
+
+	@Override
+	protected boolean validateComponent() {
+		FunctionDefinition functionDefinitionHere;
+		if (this.getAttributeValue() == null) {
+			this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing AttributeValue");
+			return false;
+		} else if (this.getMatchId() == null) {
+			this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing MatchId");
+			return false;
+		} else if ((functionDefinitionHere = this.getFunctionDefinition()) == null) {
+			this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Unknown MatchId \"" + this.getMatchId().toString() + "\"");
+			return false;
+		} else if (functionDefinitionHere.returnsBag()) {
+			this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "FunctionDefinition returns a bag");
+			return false;
+		} else if (functionDefinitionHere.getDataTypeId() == null || !functionDefinitionHere.getDataTypeId().equals(XACML.ID_DATATYPE_BOOLEAN)) {
+			this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Non-Boolean return type for FunctionDefinition");
+			return false;
+		} else if (this.getAttributeRetrievalBase() == null) {
+			this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing AttributeSelector or AttributeDesignator");
+			return false;
+		} else {
+			this.setStatus(StdStatusCode.STATUS_CODE_OK, null);
+			return true;
+		}
+	}
+	
+	@Override
+	public String toString() {
+		StringBuilder stringBuilder	= new StringBuilder("{");
+		stringBuilder.append("super=");
+		stringBuilder.append(super.toString());
+		
+		Object objectToDump;
+		if ((objectToDump = this.getMatchId()) != null) {
+			stringBuilder.append(",matchId=");
+			stringBuilder.append(objectToDump.toString());
+		}
+		if ((objectToDump = this.getAttributeValue()) != null) {
+			stringBuilder.append(",attributeValue=");
+			stringBuilder.append(objectToDump.toString());
+		}
+		if ((objectToDump = this.getAttributeRetrievalBase()) != null) {
+			stringBuilder.append(",attributeRetrieval=");
+			stringBuilder.append(objectToDump.toString());
+		}
+		stringBuilder.append('}');
+		return stringBuilder.toString();
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/ObligationExpression.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/ObligationExpression.java
new file mode 100755
index 0000000..3ef01ef
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/ObligationExpression.java
@@ -0,0 +1,174 @@
+/*
+ *                        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.policy;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.AttributeAssignment;
+import com.att.research.xacml.api.Decision;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.Obligation;
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacml.std.StdMutableObligation;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+
+/**
+ * ObligationExpression extends {@link PolicyComponent} to implement the XACML
+ * ObligationExpression element.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class ObligationExpression extends PolicyComponent {
+	private Identifier							obligationId;
+	private RuleEffect							ruleEffect;
+	private List<AttributeAssignmentExpression>	attributeAssignmentExpressions;
+	
+	protected List<AttributeAssignmentExpression> getAttributeAssignmentExpressionList(boolean bNoNull) {
+		if (this.attributeAssignmentExpressions == null && bNoNull) {
+			this.attributeAssignmentExpressions	= new ArrayList<AttributeAssignmentExpression>();
+		}
+		return this.attributeAssignmentExpressions;
+	}
+	
+	protected void clearAttributeAssignmentExpressions() {
+		if (this.attributeAssignmentExpressions != null) {
+			this.attributeAssignmentExpressions.clear();
+		}
+	}
+	
+	public ObligationExpression(StatusCode statusCodeIn, String statusMessageIn) {
+		super(statusCodeIn, statusMessageIn);
+	}
+
+	public ObligationExpression(StatusCode statusCodeIn) {
+		super(statusCodeIn);
+	}
+
+	public ObligationExpression() {
+	}
+	
+	public Identifier getObligationId() {
+		return this.obligationId;
+	}
+	
+	public void setObligationId(Identifier identifier) {
+		this.obligationId	= identifier;
+	}
+	
+	public RuleEffect getRuleEffect() {
+		return this.ruleEffect;
+	}
+	
+	public void setRuleEffect(RuleEffect ruleEffectIn) {
+		this.ruleEffect	= ruleEffectIn;
+	}
+	
+	public Iterator<AttributeAssignmentExpression> getAttributeAssignmentExpressions() {
+		List<AttributeAssignmentExpression> listAttributeAssignmentExpressions	= this.getAttributeAssignmentExpressionList(false);
+		return (listAttributeAssignmentExpressions == null ? null : listAttributeAssignmentExpressions.iterator());
+	}
+	
+	public void setAttributeAssignmentExpressions(Collection<AttributeAssignmentExpression> attributeAssignmentExpressionsIn) {
+		this.clearAttributeAssignmentExpressions();
+		if (attributeAssignmentExpressionsIn != null) {
+			this.addAttributeAssignmentExpressions(attributeAssignmentExpressionsIn);
+		}
+	}
+	
+	public void addAttributeAssignmentExpression(AttributeAssignmentExpression attributeAssignmentExpression) {
+		List<AttributeAssignmentExpression> listAttributeAssignmentExpressions	= this.getAttributeAssignmentExpressionList(true);
+		listAttributeAssignmentExpressions.add(attributeAssignmentExpression);
+	}
+	
+	public void addAttributeAssignmentExpressions(Collection<AttributeAssignmentExpression> attributeAssignmentExpressionsIn) {
+		List<AttributeAssignmentExpression> listAttributeAssignmentExpressions	= this.getAttributeAssignmentExpressionList(true);
+		listAttributeAssignmentExpressions.addAll(attributeAssignmentExpressionsIn);
+	}
+	
+	/**
+	 * Evaluates this <code>ObligationExpression</code> in the given {@link com.att.research.xacmlatt.pdp.eval.EvaluationContext}
+	 * to get an {@link com.att.research.xacml.api.Obligation} to include in a PDP result.
+	 * 
+	 * @param evaluationContext the <code>EvaluationContext</code> in which to evaluate this <code>ObligationExpression</code>
+	 * @param policyDefaults the <code>PolicyDefaults</code> to apply to the evaluation
+	 * @return a new <code>Obliagion</code> from this <code>ObligationExpression</code>
+	 * @throws com.att.research.xacmlatt.pdp.eval.EvaluationException if there is an error evaluating any of the <code>AttributeAssignmentExpression</code>s
+	 */
+	public Obligation evaluate(EvaluationContext evaluationContext, PolicyDefaults policyDefaults) throws EvaluationException {
+		if (!this.validate()) {
+			return null;
+		}
+		List<AttributeAssignment> listAttributeAssignments							= new ArrayList<AttributeAssignment>();
+		Iterator<AttributeAssignmentExpression> iterAttributeAssignmentExpressions	= this.getAttributeAssignmentExpressions();
+		if (iterAttributeAssignmentExpressions != null) {
+			while (iterAttributeAssignmentExpressions.hasNext()) {
+				AttributeAssignmentResult attributeAssignmentResult	= iterAttributeAssignmentExpressions.next().evaluate(evaluationContext, policyDefaults);
+				if (attributeAssignmentResult.isOk() && attributeAssignmentResult.getNumAttributeAssignments() > 0) {
+					Iterator<AttributeAssignment> iterAttributeAssignments	= attributeAssignmentResult.getAttributeAssignments();
+					while (iterAttributeAssignments.hasNext()) {
+						listAttributeAssignments.add(iterAttributeAssignments.next());
+					}
+				}
+			}
+		}
+		return new StdMutableObligation(this.getObligationId(), listAttributeAssignments);
+	}
+	
+	/**
+	 * Evaluates a <code>Collection</code> of <code>ObligationExpression</code>s in the given <code>EvaluationContext</code> and returns
+	 * a <code>List</code> of <code>Obligation</code>s.
+	 * 
+	 * @param evaluationContext
+	 * @param policyDefaults
+	 * @param listObligationExpressions
+	 * @return
+	 * @throws com.att.research.xacmlatt.pdp.eval.EvaluationException
+	 */
+	public static List<Obligation> evaluate(EvaluationContext evaluationContext, PolicyDefaults policyDefaults, Decision decision, Collection<ObligationExpression> listObligationExpressions) throws EvaluationException {
+		List<Obligation> listObligations	= new ArrayList<Obligation>();
+		Iterator<ObligationExpression> iterObligationExpressions	= listObligationExpressions.iterator();
+		while (iterObligationExpressions.hasNext()) {
+			ObligationExpression obligationExpression	= iterObligationExpressions.next();
+			obligationExpression.validateComponent();
+			if ( ! obligationExpression.isOk()) {
+				throw new EvaluationException(obligationExpression.getStatusMessage());
+			}
+			if (decision == null || obligationExpression.getRuleEffect().getDecision().equals(decision)) {
+				Obligation obligation	= obligationExpression.evaluate(evaluationContext, policyDefaults);
+				if (obligation != null) {
+					listObligations.add(obligation);
+				}
+			}
+		}
+		return listObligations;
+	}
+
+	@Override
+	protected boolean validateComponent() {
+		if (this.getObligationId() == null) {
+			this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing ObligationId attribute");
+			return false;
+		} else if (this.getRuleEffect() == null) {
+			this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing FulfillOn attribute");
+			return false;
+		} else {
+			this.setStatus(StdStatusCode.STATUS_CODE_OK, null);
+			return true;
+		}
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Policy.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Policy.java
new file mode 100755
index 0000000..a7efaa5
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Policy.java
@@ -0,0 +1,323 @@
+/*
+ *                        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.policy;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.Decision;
+import com.att.research.xacml.api.Result;
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.trace.StdTraceEvent;
+import com.att.research.xacml.util.StringUtils;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationResult;
+import com.att.research.xacmlatt.pdp.eval.MatchResult;
+
+/**
+ * Policy extends {@link com.att.research.xacmlatt.pdp.policy.PolicyDef} to represent a XACML 3.0 Policy element.
+ * 
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class Policy extends PolicyDef {
+	private TargetedCombinerParameterMap<String,Rule>		ruleCombinerParameters	= new TargetedCombinerParameterMap<String,Rule>();
+	private VariableMap										variableMap				= new VariableMap();
+	private List<Rule>										rules					= new ArrayList<Rule>();
+	private List<CombiningElement<Rule>>					combiningRules;
+	private CombiningAlgorithm<Rule>						ruleCombiningAlgorithm;
+	
+	@Override
+	protected boolean validateComponent() {
+		if (super.validateComponent()) {
+			if (this.getRuleCombiningAlgorithm() == null) {
+				this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing rule combining algorithm");
+				return false;
+			} else {
+				return true;
+			}
+		} else {
+			return false;
+		}
+	}
+	
+	/**
+	 * Performs lazy evaluation of the combining parameters from this <code>Policy</code>.
+	 * 
+	 * @return the <code>List</code> of <code>CombiningElement</code>s for all of the <code>Rule</code>s
+	 */
+	protected List<CombiningElement<Rule>> getCombiningRules() {
+		if (this.combiningRules == null) {
+			this.combiningRules			= new ArrayList<CombiningElement<Rule>>();
+			Iterator<Rule> iterRules	= this.getRules();
+			while (iterRules.hasNext()) {
+				Rule rule	= iterRules.next();
+				this.combiningRules.add(new CombiningElement<Rule>(rule, this.ruleCombinerParameters.getCombinerParameters(rule)));
+			}
+		}
+		return this.combiningRules;
+	}
+	
+	public Policy(PolicySet policySetParent, StatusCode statusCodeIn, String statusMessageIn) {
+		super(policySetParent, statusCodeIn, statusMessageIn);
+	}
+	
+	public Policy(StatusCode statusCodeIn, String statusMessageIn) {
+		super(statusCodeIn, statusMessageIn);
+	}
+	
+	public Policy(StatusCode statusCodeIn) {
+		super(statusCodeIn);
+	}
+	
+	public Policy(PolicySet policySetParent) {
+		super(policySetParent);
+	}
+
+	public Policy() {
+		super();
+		ruleCombinerParameters.getTargetedCombinerParameters();
+	}
+	
+	/**
+	 * Gets an <code>Iterator</code> over the {@link com.att.research.xacmlatt.pdp.policy.TargetedCombinerParameter}s for
+	 * the {@link Rule}s in this <code>Policy</code>.
+	 * 
+	 * @return an <code>Iterator</code> over the <code>TargetedCombinerParameter</code>s for this <code>Policy</code>.
+	 */
+	public Iterator<TargetedCombinerParameter<String,Rule>> getRuleCombinerParameters() {
+		return this.ruleCombinerParameters.getTargetedCombinerParameters();
+	}
+	
+	/**
+	 * Sets the Rule combiner parameters for this <code>Policy</code> to the contents of the given <code>Collection</code> of
+	 * <code>TargetedCombinerParameter</code>s.
+	 * 
+	 * @param ruleCombinerParameters the <code>Collection</code> of <code>TargetedCombinerParameter</code>s to set
+	 */
+	public void setRuleCombinerParameters(Collection<TargetedCombinerParameter<String,Rule>> ruleCombinerParameters) {
+		this.ruleCombinerParameters.setCombinerParameters(ruleCombinerParameters);
+	}
+	
+	/**
+	 * Adds the given <code>TargetedCombinerParameter</code> to the set of Rule combiner parameters for this <code>Policy</code>.
+	 * @param ruleCombinerParameter the <code>TargetedCombinerParameter</code> for <code>Rule</code>s to add.
+	 */
+	public void addRuleCombinerParameter(TargetedCombinerParameter<String,Rule> ruleCombinerParameter) {
+		this.ruleCombinerParameters.addCombinerParameter(ruleCombinerParameter);
+	}
+	
+	/**
+	 * Adds the contents of the given <code>Collection</code> of <code>TargetedCombinerParameter</code>s to the set of Rule combiner parameters
+	 * for this <code>Policy</code>.
+	 * 
+	 * @param ruleCombinerParameters the <code>Collection</code> of <code>TargetedCombinerParameter</code>s to add
+	 */
+	public void addRuleCombinerParameters(Collection<TargetedCombinerParameter<String,Rule>> ruleCombinerParameters) {
+		this.ruleCombinerParameters.addCombinerParameters(ruleCombinerParameters);
+	}
+	
+	/**
+	 * Gets an <code>Iterator</code> over the {@link com.att.research.xacmlatt.pdp.policy.VariableDefinition}s in this <code>Policy</code>.
+	 * 
+	 * @return an <code>Iterator</code> over the <code>VariableDefinition</code>s in this <code>Policy</code>
+	 */
+	public Iterator<VariableDefinition> getVariableDefinitions() {
+		return this.variableMap.getVariableDefinitions();
+	}
+	
+	/**
+	 * Gets the <code>VariableDefinition</code> for the given <code>String</code> variable identifier.
+	 * 
+	 * @param variableId the <code>String</code> variable identifier
+	 * @return the <code>VariableDefinition</code> with the given <code>String</code> identifier or null if not found
+	 */
+	public VariableDefinition getVariableDefinition(String variableId) {
+		return this.variableMap.getVariableDefinition(variableId);
+	}
+	
+	/**
+	 * Sets the <code>VariableDefinition</code>s in this <code>Policy</code> to the contents of the given <code>Collection</code>.
+	 * 
+	 * @param listVariableDefinitions the <code>Collection</code> of <code>VariableDefinition</code>s to set
+	 */
+	public void setVariableDefinitions(Collection<VariableDefinition> listVariableDefinitions) {
+		this.variableMap.setVariableDefinitions(listVariableDefinitions);
+	}
+	
+	/**
+	 * Adds the given <code>VariableDefinition</code> to the set of <code>VariableDefinition</code>s for this <code>Policy</code>.
+	 * 
+	 * @param variableDefinition the <code>VariableDefinition</code> to add
+	 */
+	public void addVariableDefinition(VariableDefinition variableDefinition) {
+		this.variableMap.add(variableDefinition);
+	}
+	
+	/**
+	 * Adds the contents of the given <code>Collection</code> of <code>VariableDefinition</code>s to this <code>Policy</code>.
+	 * 
+	 * @param variableDefinitions the <code>Collection</code> of <code>VariableDefinition</code>s to add.
+	 */
+	public void addVariableDefinitions(Collection<VariableDefinition> variableDefinitions) {
+		this.variableMap.addVariableDefinitions(variableDefinitions);
+	}
+	
+	/**
+	 * Gets an <code>Iterator</code> over the <code>Rule</code>s in this <code>Policy</code> or null if there are none.
+	 * 
+	 * @return an <code>Iterator</code> over the <code>Rule</code>s in this <code>Policy</code> or null if there are none.
+	 */
+	public Iterator<Rule> getRules() {
+		return this.rules.iterator();
+	}
+	
+	/**
+	 * Sets the <code>Rule</code>s for this <code>Policy</code> to the contents of the given <code>Collection</code> of
+	 * <code>Rule</code>s. If the <code>Collection</code> is null, the set of <code>Rule</code>s for this <code>Policy</code> is set to null.
+	 * 
+	 * @param listRules the <code>Collection</code> of <code>Rule</code>s or null
+	 */
+	public void setRules(Collection<Rule> listRules) {
+		this.rules.clear();
+		if (listRules != null) {
+			this.addRules(listRules);
+		}
+	}
+	
+	/**
+	 * Adds the given <code>Rule</code> to the set of <code>Rule</code>s for this <code>Policy</code>.
+	 * 
+	 * @param rule the <code>Rule</code> to add
+	 */
+	public void addRule(Rule rule) {
+		this.rules.add(rule);
+	}
+	
+	/**
+	 * Adds the contents of the given <code>Collection</code> of <code>Rule</code>s to the set of <code>Rule</code>s for
+	 * this <code>Policy</code>.
+	 * 
+	 * @param listRules the <code>Collection</code> of <code>Rule</code>s to add
+	 */
+	public void addRules(Collection<Rule> listRules) {
+		this.rules.addAll(listRules);
+	}
+	
+	/**
+	 * Gets the <code>CombiningAlgorithm</code> for <code>Rule</code>s for this <code>Policy</code>.
+	 * 
+	 * @return the <code>CombiningAlgorithm</code> for <code>Rule</code>s for this <code>Policy</code>.
+	 */
+	public CombiningAlgorithm<Rule> getRuleCombiningAlgorithm() {
+		return this.ruleCombiningAlgorithm;
+	}
+	
+	/**
+	 * Sets the <code>CombiningAlgorithm</code> for <code>Rule</code>s for this <code>Policy</code>>
+	 * 
+	 * @param ruleCombiningAlgorithmIn the <code>CombiningAlgorithm</code> for <code>Rule</code>s for this <code>Policy</code>
+	 */
+	public void setRuleCombiningAlgorithm(CombiningAlgorithm<Rule> ruleCombiningAlgorithmIn) {
+		this.ruleCombiningAlgorithm	= ruleCombiningAlgorithmIn;
+	}
+
+	@Override
+	public EvaluationResult evaluate(EvaluationContext evaluationContext) throws EvaluationException {
+		/*
+		 * First check to see if we are valid.  If not, return an error status immediately
+		 */
+		if (!this.validate()) {
+			return new EvaluationResult(new StdStatus(this.getStatusCode(), this.getStatusMessage()));
+		}
+		
+		/*
+		 * See if we match
+		 */
+		MatchResult thisMatchResult	= this.match(evaluationContext);
+		assert(thisMatchResult != null);
+		if (evaluationContext.isTracing()) {
+			evaluationContext.trace(new StdTraceEvent<MatchResult>("Match", this, thisMatchResult));
+		}
+		switch(thisMatchResult.getMatchCode()) {
+		case INDETERMINATE:
+			return new EvaluationResult(Decision.INDETERMINATE, thisMatchResult.getStatus());
+		case MATCH:
+			break;
+		case NOMATCH:
+			return new EvaluationResult(Decision.NOTAPPLICABLE);
+		}
+		
+		/*
+		 * Get the combining elements
+		 */
+		List<CombiningElement<Rule>> ruleCombiningElements	= this.getCombiningRules();
+		assert(ruleCombiningElements != null);
+		
+		/*
+		 * Run the combining algorithm
+		 */
+		assert(this.getRuleCombiningAlgorithm() != null);
+		EvaluationResult evaluationResultCombined	= this.getRuleCombiningAlgorithm().combine(evaluationContext, ruleCombiningElements, this.getCombinerParameterList());
+		assert(evaluationResultCombined != null);
+		
+		if (evaluationResultCombined.getDecision() == Decision.DENY || evaluationResultCombined.getDecision() == Decision.PERMIT) {
+			this.updateResult(evaluationResultCombined, evaluationContext);
+			
+			/*
+			 * Add my id to the policy identifiers
+			 */
+			if (evaluationContext.getRequest().getReturnPolicyIdList()) {
+				evaluationResultCombined.addPolicyIdentifier(this.getIdReference());
+			}
+		}
+		if (evaluationContext.isTracing()) {
+			evaluationContext.trace(new StdTraceEvent<Result>("Result", this, evaluationResultCombined));
+		}
+		return evaluationResultCombined;
+	}
+
+	@Override
+	public String toString() {
+		StringBuilder stringBuilder	= new StringBuilder("{");
+		stringBuilder.append("super=");
+		stringBuilder.append(super.toString());
+		
+		String iteratorToDump;
+		if ((iteratorToDump = StringUtils.toString(this.getRuleCombinerParameters())) != null) {
+			stringBuilder.append(",ruleCombinerParameters=");
+			stringBuilder.append(iteratorToDump);
+		}
+		if ((iteratorToDump = StringUtils.toString(this.getVariableDefinitions())) != null) {
+			stringBuilder.append(",variableDefinitions=");
+			stringBuilder.append(iteratorToDump);
+		}
+		if ((iteratorToDump = StringUtils.toString(this.getRules())) != null) {
+			stringBuilder.append(",rules=");
+			stringBuilder.append(iteratorToDump);
+		}
+		
+		Object objectToDump;
+		if ((objectToDump = this.getRuleCombiningAlgorithm()) != null) {
+			stringBuilder.append(",ruleCombiningAlgorithm=");
+			stringBuilder.append(objectToDump.toString());
+		}
+		stringBuilder.append('}');
+		return stringBuilder.toString();
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyComponent.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyComponent.java
new file mode 100755
index 0000000..9195249
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyComponent.java
@@ -0,0 +1,144 @@
+/*
+ *                        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.policy;
+
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacml.std.StdStatusCode;
+
+/**
+ * PolicyComponent is the base class for all pieces of a XACML Policy or PolicySet that could potentially have errors associated
+ * with them by the policy loader.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+abstract class PolicyComponent {
+	private StatusCode	statusCode;
+	private String		statusMessage;
+	
+	/**
+	 * Creates a new <code>PolicyComponent</code> with the given {@link com.att.research.xacml.api.StatusCode} and
+	 * <code>String</code> detailed message.  If the <code>StatusCode</code> is null, a default OK status code is used.
+	 * 
+	 * @param statusCodeIn the <code>StatusCode</code> for the new <code>PolicyComponent</code>
+	 * @param statusMessageIn the <code>String</code> detailed status message for the new <code>PolicyComponent</code>
+	 */
+	public PolicyComponent(StatusCode statusCodeIn, String statusMessageIn) {
+		this.statusCode		= statusCodeIn;
+		this.statusMessage	= statusMessageIn;
+	}
+	
+	/**
+	 * Creates a new <code>PolicyComponent</code> with the given <code>StatusCode</code> and no status message.
+	 * 
+	 * @param statusCodeIn the <code>StatusCode</code> for the new <code>PolicyComponent</code>
+	 */
+	public PolicyComponent(StatusCode statusCodeIn) {
+		this(statusCodeIn, null);
+	}
+	
+	/**
+	 * Creates a new <code>PolicyCOmponent</code> with no <code>StatusCode</code> or status message.
+	 */
+	public PolicyComponent() {
+		this(null, null);
+	}
+	
+	/**
+	 * Gets the <code>StatusCode</code> associated with this <code>PolicyComponent</code>.
+	 * 
+	 * @return the <code>StatusCode</code> associated with this <code>PolicyComponent</code>
+	 */
+	public StatusCode getStatusCode() {
+		return this.statusCode;
+	}
+	
+	/**
+	 * Gets the <code>String</code> status message associated with this <code>PolicyComponent</code>.
+	 * 
+	 * @return the <code>String</code> status message associated with this <code>PolicyComponent</code> or null if none
+	 */
+	public String getStatusMessage() {
+		return this.statusMessage;
+	}
+	
+	/**
+	 * Sets the <code>StatusCode</code> and <code>String</code> status message for this <code>PolicyComponent</code>.
+	 * This method is mainly provided for objects that may have lazy evaluations performed on them, in which case the
+	 * status is not determined until the object is actually used.
+	 * 
+	 * @param statusCodeIn the <code>StatusCode</code> for this <code>PolicyComponent</code>
+	 * @param messageIn the <code>String</code> status message for this <code>PolicyComponent</code>
+	 */
+	public void setStatus(StatusCode statusCodeIn, String messageIn) {
+		this.statusCode		= statusCodeIn;
+		this.statusMessage	= messageIn;
+	}
+	
+	/**
+	 * Does a check on the <code>StatusCode</code> for this element to determine if it is equivalent to the
+	 * OK status code.
+	 * 
+	 * @return true if the <code>StatusCode</code> is equivalent to OK, otherwise false
+	 */
+	public boolean isOk() {
+		return StdStatusCode.STATUS_CODE_OK.equals(this.getStatusCode());
+	}
+	
+	/**
+	 * Validates that this <code>PolicyComponent</code> has all of the required elements according to the XACML 3.0
+	 * specification.  If the component is not valid, this method should set the <code>StatusCode</code> to reflect a
+	 * syntax error, and should set the status message to reflect the invalid piece(s).
+	 * 
+	 * <code>PolicyComponent</code>s that implement this method should only validate their immediate elements and not perform
+	 * a deep validation of descendents.
+	 * 
+	 * @return true if the resulting status code is OK, otherwise false
+	 */
+	abstract protected boolean validateComponent();
+	
+	/**
+	 * If a <code>StatusCode</code> has not been set, ask this <code>PolicyComponent</code> to validate itself and return
+	 * the value from the validation.  Otherwise, check to see if the cached <code>StatusCode</code> indicates this <code>PolicyComponent</code> is valid.
+	 * 
+	 * @return true if this <code>PolicyComponent</code> is valid, else false.
+	 */
+	public boolean validate() {
+		if (this.getStatusCode() == null) {
+			return this.validateComponent();
+		} else {
+			return this.isOk();
+		}
+	}
+	
+	@Override
+	public String toString() {
+		StringBuilder stringBuilder	= new StringBuilder("{");
+		Object objectToDump;
+		boolean needsComma	= false;
+		if ((objectToDump = this.getStatusCode()) != null) {
+			stringBuilder.append("statusCode=");
+			stringBuilder.append(objectToDump.toString());
+			needsComma	= true;
+		}
+		if ((objectToDump = this.getStatusMessage()) != null) {
+			if (needsComma) {
+				stringBuilder.append(',');
+			}
+			stringBuilder.append("statusMessage=");
+			stringBuilder.append((String)objectToDump);
+			needsComma	= true;
+		}
+		stringBuilder.append('}');
+		return stringBuilder.toString();
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyDef.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyDef.java
new file mode 100755
index 0000000..1c785c5
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyDef.java
@@ -0,0 +1,476 @@
+/*
+ *                        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.policy;
+
+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.IdReference;
+import com.att.research.xacml.api.IdReferenceMatch;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.Obligation;
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacml.api.Version;
+import com.att.research.xacml.api.VersionMatch;
+import com.att.research.xacml.std.StdIdReference;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.util.StringUtils;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationResult;
+import com.att.research.xacmlatt.pdp.eval.MatchResult;
+
+/**
+ * PolicyDef extends {@link com.att.research.xacmlatt.pdp.policy.PolicySetChild} with members and methods common
+ * to XACML 3.0 Policies and PolicySets.
+ * 
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public abstract class PolicyDef extends PolicySetChild {
+	private String 						description;
+	private PolicyIssuer 				policyIssuer;
+	private Target 						target;
+	private List<CombinerParameter> 	combinerParameters;
+	private List<ObligationExpression> 	obligationExpressions;
+	private List<AdviceExpression> 		adviceExpressions;
+	private Version						version;
+	private Integer 					maxDelegationDepth;
+	
+	private IdReference					idReference;
+
+	private void ensureCombinerParameters() {
+		if (this.combinerParameters == null) {
+			this.combinerParameters	= new ArrayList<CombinerParameter>();
+		}
+	}
+	
+	private void ensureObligationExpressions() {
+		if (this.obligationExpressions == null) {
+			this.obligationExpressions	= new ArrayList<ObligationExpression>();
+		}
+	}
+	
+	private void ensureAdviceExpressions() {
+		if (this.adviceExpressions == null) {
+			this.adviceExpressions	= new ArrayList<AdviceExpression>();
+		}
+	}
+	
+	protected List<CombinerParameter> getCombinerParameterList() {
+		return this.combinerParameters;
+	}
+	
+	protected List<ObligationExpression> getObligationExpressionList() {
+		return this.obligationExpressions;
+	}
+	
+	protected List<AdviceExpression> getAdviceExpressionList() {
+		return this.adviceExpressions;
+	}
+	
+	protected void updateResult(EvaluationResult evaluationResult, EvaluationContext evaluationContext) throws EvaluationException {
+		List<ObligationExpression> thisObligationExpressions	= this.getObligationExpressionList();
+		if (thisObligationExpressions != null && thisObligationExpressions.size() > 0) {
+			List<Obligation> listObligations	= ObligationExpression.evaluate(evaluationContext, this.getPolicyDefaults(), evaluationResult.getDecision(), thisObligationExpressions);
+			if (listObligations != null && listObligations.size() > 0) {
+				evaluationResult.addObligations(listObligations);
+			}
+		}
+		
+		List<AdviceExpression> thisAdviceExpressions			= this.getAdviceExpressionList();
+		if (thisAdviceExpressions != null && thisAdviceExpressions.size() > 0) {
+			List<Advice> listAdvices			= AdviceExpression.evaluate(evaluationContext, this.getPolicyDefaults(), evaluationResult.getDecision(), thisAdviceExpressions);
+			if (listAdvices != null && listAdvices.size() > 0) {
+				evaluationResult.addAdvice(listAdvices);
+			}
+		}
+	}
+	
+	@Override
+	protected boolean validateComponent() {
+		if (super.validateComponent()) {
+			if (this.getVersion() == null) {
+				this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing version string");
+				return false;
+			} else if (this.getTarget() == null) {
+				this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing Target in policy " + this.getIdReference().getId().stringValue());
+				return false;
+			} else {
+				return true;
+			}
+		} else {
+			return false;
+		}
+	}
+	
+	public PolicyDef(PolicySet policySetParent, StatusCode statusCodeIn, String statusMessageIn) {
+		super(policySetParent, statusCodeIn, statusMessageIn);
+	}
+	
+	public PolicyDef(StatusCode statusCodeIn, String statusMessageIn) {
+		super(statusCodeIn, statusMessageIn);
+	}
+	
+	public PolicyDef(StatusCode statusCodeIn) {
+		super(statusCodeIn);
+	}
+	
+	public PolicyDef(PolicySet policySetParent) {
+		super(policySetParent);
+	}
+
+	public PolicyDef() {
+		super();
+	}
+	
+	@Override
+	public void setIdentifier(Identifier identifierIn) {
+		super.setIdentifier(identifierIn);
+		this.idReference 	= null;
+	}
+	
+	/**
+	 * Gets the <code>String</code> description of this <code>PolicyDef</code>.
+	 * 
+	 * @return the <code>String</code> description of this <code>PolicyDef</code>.
+	 */
+	public String getDescription() {
+		return this.description;
+	}
+	
+	/**
+	 * Sets the <code>String</code> description of this <code>PolicyDef</code>.
+	 * 
+	 * @param s the <code>String</code> description of this <code>PolicyDef</code>
+	 */
+	public void setDescription(String s) {
+		this.description	= s;
+	}
+	
+	/**
+	 * Gets the {@link com.att.research.xacmlatt.pdp.policy.PolicyIssuer} for this <code>PolicyDef</code>.
+	 * 
+	 * @return the <code>PolicyIssuer</code> for this <code>PolicyDef</code>
+	 */
+	public PolicyIssuer getPolicyIssuer() {
+		return this.policyIssuer;
+	}
+	
+	/**
+	 * Sets the <code>PolicyIssuer</code> for this <code>PolicyDef</code>.
+	 * 
+	 * @param policyIssuerIn the <code>PolicyIssuer</code> for this <code>PolicyDef</code>.
+	 */
+	public void setPolicyIssuer(PolicyIssuer policyIssuerIn) {
+		this.policyIssuer	= policyIssuerIn;
+	}
+	
+	/**
+	 * Gets the <code>Target</code> for this <code>PolicyDef</code>.
+	 * 
+	 * @return the <code>Target</code> for this <code>PolicyDef</code>
+	 */
+	public Target getTarget() {
+		return this.target;
+	}
+	
+	/**
+	 * Sets the <code>Target</code> for this <code>PolicyDef</code>.
+	 * 
+	 * @param targetIn the <code>Target</code> for this <code>PolicyDef</code>
+	 */
+	public void setTarget(Target targetIn) {
+		this.target	= targetIn;
+	}
+	
+	/**
+	 * Gets an <code>Iterator</code> over the <code>CombinerParameter</code>s for this <code>Policy</code>.
+	 * 
+	 * @return an <code>Iterator</code> over the <code>CombinerParameter</code>s for this <code>Policy</code> or null if there are none
+	 */
+	public Iterator<CombinerParameter> getCombinerParameters() {
+		return (this.combinerParameters == null ? null : this.combinerParameters.iterator());
+	}
+	
+	/**
+	 * Sets the <code>CombinerParameter</code>s for this<code>Policy</code> to the contents of the
+	 * given <code>Collection</code>.  If the <code>Collection</code> is null, the set of <code>CombinerParameter</code>s
+	 * for this <code>Policy</code> is set to null.
+	 * 
+	 * @param combinerParametersIn the <code>Collection</code> of <code>CombinerParameter</code>s for this <code>PolicyDef</code>
+	 */
+	public void setCombinerParameters(Collection<CombinerParameter> combinerParametersIn) {
+		this.combinerParameters	= null;
+		if (combinerParametersIn != null) {
+			this.addCombinerParameters(combinerParametersIn);
+		}
+	}
+	
+	/**
+	 * Adds the given <code>CombinerParameter</code> to the set of <code>CombinerParameter</code>s for this
+	 * <code>PolicyDef</code>>
+	 * 
+	 * @param combinerParameter the <code>CombinerParameter</code> to add
+	 */
+	public void add(CombinerParameter combinerParameter) {
+		this.ensureCombinerParameters();
+		this.combinerParameters.add(combinerParameter);
+	}
+	
+	/**
+	 * Adds the given <code>Collection</code> of <code>CombinerParameter</code>s to this <code>PolicyDef</code>>
+	 * 
+	 * @param combinerParametersIn the <code>Collection</code> of <code>CombinerParameter</code>s to add
+	 */
+	public void addCombinerParameters(Collection<CombinerParameter> combinerParametersIn) {
+		this.ensureCombinerParameters();
+		this.combinerParameters.addAll(combinerParametersIn);
+	}
+	
+	/**
+	 * Gets an <code>Iterator</code> over the <code>ObligationExpression</code>s for this <code>PolicyDef</code>.
+	 * 
+	 * @return an <code>Iterator</code> over the <code>ObligationExpression</code>s for this <code>PolicyDef</code> or null if there are none.
+	 */
+	public Iterator<ObligationExpression> getObligationExpressions() {
+		return (this.obligationExpressions == null ? null : this.obligationExpressions.iterator());
+	}
+	
+	/**
+	 * Sets the <code>ObligationExpression</code>s for this <code>PolicyDef</code> to the contents of the given <code>Collection</code>.
+	 * If the <code>Collection</code> is null, the <code>ObligationExpression</code>s for this <code>PolicyDef</code> are set to null.
+	 * 
+	 * @param obligationExpressionsIn the <code>Collection</code> of <code>ObligationExpression</code>s for this <code>PolicyDef</code>.
+	 */
+	public void setObligationExpressions(Collection<ObligationExpression> obligationExpressionsIn) {
+		this.obligationExpressions	= null;
+		if (obligationExpressionsIn != null) {
+			this.addObligationExpressions(obligationExpressionsIn);
+		}
+	}
+	
+	/**
+	 * Adds the given <code>ObligationExpression</code> to the set of <code>ObligationExpression</code>s for this <code>PolicyDef</code>.
+	 * 
+	 * @param obligationExpression the <code>ObligationExpression</code> to add
+	 */
+	public void add(ObligationExpression obligationExpression) {
+		this.ensureObligationExpressions();
+		this.obligationExpressions.add(obligationExpression);
+	}
+	
+	/**
+	 * Adds the contents of the given <code>Collection</code> of <code>ObligationExpression</code>s to the set of <code>ObligationExpression</code>s for
+	 * this <code>PolicyDef</code>.
+	 * 
+	 * @param obligationExpressionsIn the <code>Collection</code> of <code>ObligationExpression</code>s to add
+	 */
+	public void addObligationExpressions(Collection<ObligationExpression> obligationExpressionsIn) {
+		this.ensureObligationExpressions();
+		this.obligationExpressions.addAll(obligationExpressionsIn);
+	}
+	
+	/**
+	 * Gets an <code>Iterator</code> over the set of <code>AdviceExpression</code>s for this <code>PolicyDef</code>.
+	 * 
+	 * @return an <code>Iterator</code> over the set of <code>AdviceExpression</code>s for this <code>PolicyDef</code> or null if there are none.
+	 */
+	public Iterator<AdviceExpression> getAdviceExpressions() {
+		return (this.adviceExpressions == null ? null : this.adviceExpressions.iterator());
+	}
+	
+	/**
+	 * Sets the set of <code>AdviceExpression</code>s for this <code>PolicyDef</code> to the contents of the given <code>Collection</code>.
+	 * 
+	 * @param adviceExpressionsIn the <code>Collection</code> of <code>AdviceExpression</code> to add
+	 */
+	public void setAdviceExpressions(Collection<AdviceExpression> adviceExpressionsIn) {
+		this.adviceExpressions	= null;
+		if (adviceExpressionsIn != null) {
+			this.addAdviceExpressions(adviceExpressionsIn);
+		}
+	}
+	
+	/**
+	 * Adds the given <code>AdviceExpression</code> to the set of <code>AdviceExpression</code>s for this <code>PolicyDef</code>.
+	 * 
+	 * @param adviceExpression the <code>AdviceExpression</code> to add.
+	 */
+	public void add(AdviceExpression adviceExpression) {
+		this.ensureAdviceExpressions();
+		this.adviceExpressions.add(adviceExpression);
+	}
+	
+	/**
+	 * Adds the contents of the given <code>Collection</code> of <code>AdviceExpression</code>s to the set of
+	 * <code>AdviceExpression</code>s for this <code>PolicyDef</code>.
+	 * 
+	 * @param adviceExpressionsIn the <code>Collection</code> of <code>AdviceExpression</code>s to add.
+	 */
+	public void addAdviceExpressions(Collection<AdviceExpression> adviceExpressionsIn) {
+		this.ensureAdviceExpressions();
+		this.adviceExpressions.addAll(adviceExpressionsIn);
+	}
+	
+	/**
+	 * Gets the <code>String</code> version for this <code>PolicyDef</code>.
+	 * 
+	 * @return the <code>String</code> version for this <code>PolicyDef</code>.
+	 */
+	public Version getVersion() {
+		return this.version;
+	}
+	
+	/**
+	 * Sets the version <code>String</code> for this <code>PolicyDef</code>>
+	 * 
+	 * @param versionIn the <code>String</code> version for this <code>PolicyDef</code>
+	 */
+	public void setVersion(Version versionIn) {
+		this.version		= versionIn;
+		this.idReference	= null;
+	}
+	
+	/**
+	 * Creates the <code>IdReference</code> for this <code>PolicyDef</code> if needed and returns it.
+	 * 
+	 * @return the <code>IdReference</code> for this <code>PolicyDef</code>
+	 */
+	public IdReference getIdReference() {
+		if (this.idReference == null) {
+			this.idReference	= new StdIdReference(this.getIdentifier(), this.getVersion());
+		}
+		return this.idReference;
+	}
+	
+	public boolean matches(IdReferenceMatch idReferenceRequest) {
+		IdReference thisIdReference	= this.getIdReference();
+		if (thisIdReference == null || thisIdReference.getId() == null || idReferenceRequest == null || idReferenceRequest.getId() == null) {
+			return false;
+		} else if (!thisIdReference.getId().equals(idReferenceRequest.getId())) {
+			return false;
+		}
+		
+		/*
+		 * Now do version number matching
+		 */
+		VersionMatch idReferenceRequestVersion	= idReferenceRequest.getVersion();
+		if (idReferenceRequestVersion != null) {
+			/*
+			 * Do exact version matching
+			 */
+			Version thisVersion	= thisIdReference.getVersion();
+			if (thisVersion == null) {
+				return false;
+			} else {
+				return idReferenceRequestVersion.match(thisVersion, 0);
+			}
+		} else {
+			VersionMatch idReferenceRequestEarliestVersion	= idReferenceRequest.getEarliestVersion();
+			Version thisVersion								= thisIdReference.getVersion();
+			
+			if (idReferenceRequestEarliestVersion != null) {
+				if (thisVersion == null) {
+					return false;
+				} else if (!idReferenceRequestEarliestVersion.match(thisVersion, 1)) {
+					return false;
+				}
+			}
+			
+			VersionMatch idReferenceRequestLatestVersion	= idReferenceRequest.getLatestVersion();
+			if (idReferenceRequestLatestVersion != null) {
+				if (thisVersion == null) {
+					return false;
+				} else if (!idReferenceRequestLatestVersion.match(thisVersion, -1)) {
+					return false;
+				}
+			}
+			
+			return true;
+		}
+	}
+	
+	/**
+	 * Gets the <code>Integer</code> maximum delegation depth for this <code>PolicyDef</code>.
+	 * 
+	 * @return the <code>Integer</code> maximum delegation depth for this <code>PolicyDef</code>
+	 */
+	public Integer getMaxDelegationDepth() {
+		return this.maxDelegationDepth;
+	}
+	
+	/**
+	 * Sets the <code>Integer</code> maximum delegation depth for this <code>PolicyDef</code>
+	 * @param i the <code>Integer</code> maximum delegation depth for this <code>PolicyDef</code>
+	 */
+	public void setMaxDelegationDepth(Integer i) {
+		this.maxDelegationDepth	= i;
+	}
+	
+	@Override
+	public String toString() {
+		StringBuilder stringBuilder	= new StringBuilder("{");
+		
+		stringBuilder.append("super=");
+		stringBuilder.append(super.toString());
+		
+		Object objectToDump;
+		if ((objectToDump = this.getDescription()) != null) {
+			stringBuilder.append(",description=");
+			stringBuilder.append((String)objectToDump);
+		}
+		if ((objectToDump = this.getPolicyIssuer()) != null) {
+			stringBuilder.append(",policyIssuer=");
+			stringBuilder.append(objectToDump.toString());
+		}
+		if ((objectToDump = this.getTarget()) != null) {
+			stringBuilder.append(",target=");
+			stringBuilder.append(objectToDump.toString());
+		}
+		String iteratorToString;
+		if ((iteratorToString = StringUtils.toString(this.getCombinerParameters())) != null) {
+			stringBuilder.append(",combinerParameters=");
+			stringBuilder.append(iteratorToString);
+		}
+		if ((iteratorToString = StringUtils.toString(this.getObligationExpressions())) != null) {
+			stringBuilder.append(",obligationExpressions=");
+			stringBuilder.append(iteratorToString);
+		}
+		if ((iteratorToString = StringUtils.toString(this.getAdviceExpressions())) != null) {
+			stringBuilder.append(",adviceExpressions=");
+			stringBuilder.append(iteratorToString);
+		}
+		if ((objectToDump = this.getVersion()) != null) {
+			stringBuilder.append(",version=");
+			stringBuilder.append(objectToDump.toString());
+		}
+		if ((objectToDump = this.getMaxDelegationDepth()) != null) {
+			stringBuilder.append(",maxDelegationDepth=");
+			stringBuilder.append(objectToDump.toString());
+		}
+		stringBuilder.append('}');
+		return stringBuilder.toString();
+	}
+
+	@Override
+	public MatchResult match(EvaluationContext evaluationContext) throws EvaluationException {
+		if (!this.validate()) {
+			return new MatchResult(new StdStatus(this.getStatusCode(), this.getStatusMessage()));
+		}
+		return this.getTarget().match(evaluationContext);
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyDefaults.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyDefaults.java
new file mode 100755
index 0000000..a2c0c3c
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyDefaults.java
@@ -0,0 +1,111 @@
+/*
+ *                        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.policy;
+
+import java.net.URI;
+
+import com.att.research.xacml.api.XACML;
+
+/**
+ * PolicyDefaults represents the default values associated with a XACML 3.0 Policy or PolicySet that may
+ * be overridden or inherited by child Policies or PolicySets.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class PolicyDefaults {
+	private static URI		xpathVersionDefault;
+	
+	static {
+		try {
+			xpathVersionDefault	= new URI(XACML.XPATHVERSION_2_0);
+		} catch (Exception ex) {
+			
+		}
+	}
+	
+	private URI				xpathVersion;
+	private PolicyDefaults 	policyDefaultsParent;
+	
+	/**
+	 * Creates a new <code>PolicyDefaults</code> with the given <code>URI</code> for the XPath version and
+	 * the given <code>PolicyDefaults</code> pointing to the parent.
+	 * 
+	 * @param xpathVersionIn the <code>URI</code> representing the XPath version for the new <code>PolicyDefaults</code>
+	 * @param policyDefaultsParentIn the <code>PolicyDefaults</code> object that is the parent of the new <code>PolicyDefaults</code>
+	 */
+	public PolicyDefaults(URI xpathVersionIn, PolicyDefaults policyDefaultsParentIn) {
+		this.xpathVersion			= xpathVersionIn;
+		this.policyDefaultsParent	= policyDefaultsParentIn;
+	}
+	
+	/**
+	 * Gets the parent <code>PolicyDefaults</code> for this <code>PolicyDefaults</code>.
+	 * 
+	 * @return the parent <code>PolicyDefaults</code> for this <code>PolicyDefaults</code> or null if none
+	 */
+	public PolicyDefaults getPolicyDefaultsParent() {
+		return this.policyDefaultsParent;
+	}
+	
+	/**
+	 * Gets the XPath version <code>URI</code> for this <code>PolicyDefaults</code>.  If there is no explicit
+	 * version in this <code>PolicyDefaults</code>, walk up the parent <code>PolicyDefaults</code> hierarchy until
+	 * one is found, or return the default value.
+	 * 
+	 * @return the <code>URI</code> for the XPath version
+	 */
+	public URI getXPathVersion() {
+		/*
+		 * See if the XPath version was explicitly set here
+		 */
+		if (this.xpathVersion != null) {
+			return this.xpathVersion;
+		}
+		
+		/*
+		 * Try the parent hierarchy if there is one
+		 */
+		PolicyDefaults	policyDefaultsParentThis	= this.getPolicyDefaultsParent();
+		if (policyDefaultsParentThis != null) {
+			return policyDefaultsParentThis.getXPathVersion();
+		}
+		
+		/*
+		 * Use the default
+		 */
+		return xpathVersionDefault;
+	}
+	
+	@Override
+	public String toString() {
+		StringBuilder stringBuilder	= new StringBuilder("{");
+		
+		boolean	needsComma	= false;
+		Object objectToDump;
+		if ((objectToDump = this.xpathVersion) != null) {
+			stringBuilder.append("xpathVersion=");
+			stringBuilder.append(objectToDump.toString());
+			needsComma	= true;
+		}
+		if ((objectToDump = this.getPolicyDefaultsParent()) != null) {
+			if (needsComma) {
+				stringBuilder.append(',');
+			}
+			stringBuilder.append("policyDefaultsParent=");
+			stringBuilder.append(objectToDump.toString());
+			needsComma	= true;
+		}
+		stringBuilder.append('}');
+		return stringBuilder.toString();
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyFinder.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyFinder.java
new file mode 100755
index 0000000..8a3b391
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyFinder.java
@@ -0,0 +1,50 @@
+/*
+ *                        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.policy;
+
+import com.att.research.xacml.api.IdReferenceMatch;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+
+/**
+ * PolicyFinder is the interface for objects that can locate XACML Policies and PolicySets by identifier and contains the root
+ * Policy or Policy set.  The interface is designed to allow for finders that can retrieve a root policy from a repository based on
+ * matching a {@link com.att.research.xacml.api.Request}.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public interface PolicyFinder {
+	/**
+	 * Gets the root {@link PolicyDef} from the policy store
+	 * configured by the particular implementation of the <code>PolicyFinderFactory</code> class that
+	 * is applicable to the {@link com.att.research.xacml.api.Request} in the given {@link com.att.research.xacmlatt.pdp.eval.EvaluationContext}.
+	 * 
+	 * @return a <code>PolicyFinderResult</code> with the root <code>PolicyDef</code>
+	 */
+	public PolicyFinderResult<PolicyDef> getRootPolicyDef(EvaluationContext evaluationContext);
+	
+	/**
+	 * Gets the {@link Policy} that matches the given {@link com.att.research.xacml.api.IdReferenceMatch}.
+	 * 
+	 * @param idReferenceMatch the <code>IdReferenceMatch</code> to search for
+	 * @return a <code>PolicyFinderResult</code> with the <code>Policy</code> matching the given <code>IdReferenceMatch</code>
+	 */
+	public PolicyFinderResult<Policy> getPolicy(IdReferenceMatch idReferenceMatch);
+	
+	/**
+	 * Gets the {@link PolicySet} that matches the given {@link com.att.research.xacml.api.IdReferenceMatch}.
+	 * 
+	 * @param idReferenceMatch the <code>IdReferenceMatch</code> to search for
+	 * @return a <code>PolicyFinderResult</code> with the <code>PolicySet</code> matching the given <code>IdReferenceMatch</code>.
+	 */
+	public PolicyFinderResult<PolicySet> getPolicySet(IdReferenceMatch idReferenceMatch);
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyFinderFactory.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyFinderFactory.java
new file mode 100755
index 0000000..f700046
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyFinderFactory.java
@@ -0,0 +1,65 @@
+/*
+ *                        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.policy;
+
+import java.util.Properties;
+
+import com.att.research.xacml.util.FactoryException;
+import com.att.research.xacml.util.FactoryFinder;
+import com.att.research.xacmlatt.pdp.util.ATTPDPProperties;
+
+/**
+ * PolicyFinderFactory provides methods for loading XACML 3.0 policies and policy sets that are used
+ * by the {@link com.att.research.xacmlatt.pdp.PDPEngine} to evaluate requests.
+ * 
+ * @author car
+ * @version $Revision: 1.3 $
+ */
+public abstract class PolicyFinderFactory {
+	private static final String	FACTORYID					= ATTPDPProperties.PROP_POLICYFINDERFACTORY;
+	private static final String DEFAULT_FACTORY_CLASSNAME	= "com.att.research.xacmlatt.pdp.std.StdPolicyFinderFactory";
+	
+	protected PolicyFinderFactory() {
+	}
+	
+	protected PolicyFinderFactory(Properties properties) {
+	}
+	
+	public static PolicyFinderFactory newInstance() throws FactoryException {
+		return FactoryFinder.find(FACTORYID, DEFAULT_FACTORY_CLASSNAME, PolicyFinderFactory.class);
+	}
+	
+	public static PolicyFinderFactory newInstance(Properties properties) throws FactoryException {
+		return FactoryFinder.find(FACTORYID, DEFAULT_FACTORY_CLASSNAME, PolicyFinderFactory.class, properties);
+	}
+	
+	public static PolicyFinderFactory newInstance(String className, ClassLoader classLoader) throws FactoryException {
+		return FactoryFinder.newInstance(className, PolicyFinderFactory.class, classLoader, false);
+	}
+	
+	public static PolicyFinderFactory newInstance(String className) throws FactoryException {
+		return FactoryFinder.newInstance(className, PolicyFinderFactory.class, null, true);
+	}
+
+	/**
+	 * Gets the configured {@link PolicyFinder}.
+	 * 
+	 * @return the configured <code>PolicyFinder</code>
+	 */
+	abstract public PolicyFinder getPolicyFinder() throws FactoryException;
+
+	/**
+	 * Gets the configured {@link PolicyFinder}.
+	 * 
+	 * @return the configured <code>PolicyFinder</code>
+	 */
+	abstract public PolicyFinder getPolicyFinder(Properties properties) throws FactoryException;
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyFinderResult.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyFinderResult.java
new file mode 100755
index 0000000..fe1d8ab
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyFinderResult.java
@@ -0,0 +1,36 @@
+/*
+ *                        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.policy;
+
+import com.att.research.xacml.api.Status;
+
+/**
+ * PolicyFinderResult is the interface for return values of the methods in the {@link com.att.research.xacmlatt.pdp.policy.PolicyFinderFactory} interface.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ * @param <T> the class extending {@link PolicyDef} contained as a result in this <code>PolicyFinderResult</code>
+ */
+public interface PolicyFinderResult<T extends PolicyDef> {
+	/**
+	 * Gets the {@link com.att.research.xacml.api.Status} of the method call.
+	 * 
+	 * @return the <code>Status</code> of the method call
+	 */
+	public Status getStatus();
+	
+	/**
+	 * Gets the {@link PolicyDef} returned by the method if the status is OK.
+	 * 
+	 * @return the <code>T</code> returned by the method if the status is OK.
+	 */
+	public T getPolicyDef();
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyIdReference.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyIdReference.java
new file mode 100755
index 0000000..ea75497
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyIdReference.java
@@ -0,0 +1,57 @@
+/*
+ *                        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.policy;
+
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+
+/**
+ * PolicyIdReference extends {@link com.att.research.xacmlatt.pdp.policy.PolicyIdReferenceBase} for
+ * {@link Policy} objects with an implementation of the <code>ensureReferencee</code>
+ * method to find a <code>Policy</code>.
+ * 
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class PolicyIdReference extends PolicyIdReferenceBase<Policy> {
+
+	public PolicyIdReference(PolicySet policySetParent, StatusCode statusCodeIn, String statusMessageIn) {
+		super(policySetParent, statusCodeIn, statusMessageIn);
+	}
+	
+	public PolicyIdReference(StatusCode statusCodeIn, String statusMessageIn) {
+		super(statusCodeIn, statusMessageIn);
+	}
+
+	public PolicyIdReference(StatusCode statusCodeIn) {
+		super(statusCodeIn);
+	}
+	
+	public PolicyIdReference(PolicySet policySetParent) {
+		super(policySetParent);
+	}
+
+	public PolicyIdReference() {
+	}
+
+	@Override
+	protected Policy ensureReferencee(EvaluationContext evaluationContext) throws EvaluationException {
+		if (this.getReferencee() == null) {
+			PolicyFinderResult<Policy> policyFactoryResult	= evaluationContext.getPolicy(this.getIdReferenceMatch());
+			if (policyFactoryResult.getStatus() == null || policyFactoryResult.getStatus().isOk()) {
+				this.setReferencee(policyFactoryResult.getPolicyDef());
+			}
+		}
+		return this.getReferencee();
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyIdReferenceBase.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyIdReferenceBase.java
new file mode 100755
index 0000000..10961fc
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyIdReferenceBase.java
@@ -0,0 +1,122 @@
+/*
+ *                        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.policy;
+
+import com.att.research.xacml.api.Decision;
+import com.att.research.xacml.api.IdReferenceMatch;
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationResult;
+import com.att.research.xacmlatt.pdp.eval.MatchResult;
+
+/**
+ * PolicyIdReferenceBase extends {@link PolicySetChild} to implement a XACML PolicyIdReference element.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public abstract class PolicyIdReferenceBase<T extends PolicyDef> extends PolicySetChild {
+	private IdReferenceMatch	idReferenceMatch;
+	private T					referencee;
+	
+	@Override
+	protected boolean validateComponent() {
+		if (super.validateComponent()) {
+			if (this.getIdReferenceMatch() == null) {
+				this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing reference id");
+				return false;
+			} else {
+				return true;
+			}
+		} else {
+			return false;
+		}
+	}
+	
+	/**
+	 * If the <code>T</code> referencee has not been set, this method will try and find it
+	 * in the given <code>EvaluationContext</code> and return it.
+	 * 
+	 * @param evaluationContext the <code>EvaluationContext</code> to search for the referencee
+	 * @return the <code>T</code> referencee if found, else null
+	 * @throws com.att.research.xacmlatt.pdp.eval.EvaluationException if there is an error attempting to locate the referenced <code>T</code>.
+	 */
+	protected abstract T ensureReferencee(EvaluationContext evaluationContext) throws EvaluationException;
+	
+	public PolicyIdReferenceBase(PolicySet policySetParent, StatusCode statusCodeIn, String statusMessageIn) {
+		super(policySetParent, statusCodeIn, statusMessageIn);
+	}
+	
+	public PolicyIdReferenceBase(StatusCode statusCodeIn, String statusMessageIn) {
+		super(statusCodeIn, statusMessageIn);
+	}
+
+	public PolicyIdReferenceBase(StatusCode statusCodeIn) {
+		super(statusCodeIn);
+	}
+	
+	public PolicyIdReferenceBase(PolicySet policySetParent) {
+		super(policySetParent);
+	}
+
+	public PolicyIdReferenceBase() {
+	}
+	
+	/**
+	 * Gets the {@link com.att.research.xacml.api.IdReferenceMatch} for this <code>PolicyIdReferenceBase</code>.
+	 * 
+	 * @return the <code>IdReferenceMatch</code> for this <code>PolicyIdReference</code>.
+	 */
+	public IdReferenceMatch getIdReferenceMatch() {
+		return this.idReferenceMatch;
+	}
+	
+	public void setIdReferenceMatch(IdReferenceMatch idReferenceMatchIn) {
+		this.idReferenceMatch	= idReferenceMatchIn;
+	}
+	
+	/**
+	 * Sets the <code>PolicyDef</code> object referred to by this <code>PolicyIdReferenceBase</code>.
+	 * 
+	 * @return the <code>PolicyDef</code> object referred to by this <code>PolicyIdReferenceBase</code>
+	 */
+	public T getReferencee() {
+		return this.referencee;
+	}
+	
+	public void setReferencee(T referenceeIn) {
+		this.referencee	= referenceeIn;
+	}
+	
+	@Override
+	public EvaluationResult evaluate(EvaluationContext evaluationContext) throws EvaluationException {
+		T thisReferencee	= this.ensureReferencee(evaluationContext);
+		if (thisReferencee == null) {
+			return new EvaluationResult(Decision.INDETERMINATE, new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Could not find referencee for " + this.getIdReferenceMatch().toString()));
+		} else {
+			return thisReferencee.evaluate(evaluationContext);
+		}
+	}
+
+	@Override
+	public MatchResult match(EvaluationContext evaluationContext) throws EvaluationException {
+		T thisReferencee	= this.ensureReferencee(evaluationContext);
+		if (thisReferencee == null) {
+			return new MatchResult(MatchResult.MatchCode.INDETERMINATE, new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Could not find referencee for " + this.getIdReferenceMatch().toString()));
+		} else {
+			return thisReferencee.match(evaluationContext);
+		}
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyIssuer.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyIssuer.java
new file mode 100755
index 0000000..792d864
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyIssuer.java
@@ -0,0 +1,111 @@
+/*
+ *                        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.policy;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.w3c.dom.Node;
+
+import com.att.research.xacml.api.Attribute;
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacml.std.StdStatusCode;
+
+/**
+ * PolicyIssuer extends {@link com.att.research.xacmlatt.pdp.policy.PolicyComponent} to represent the XACML 3.0
+ * PolicyIssuer element in Policies and PolicySets.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class PolicyIssuer extends PolicyComponent {
+	private Node			content;
+	private List<Attribute>	attributes;
+	
+	public PolicyIssuer(StatusCode statusCodeIn, String statusMessageIn) {
+		super(statusCodeIn, statusMessageIn);
+	}
+
+	public PolicyIssuer(StatusCode statusCodeIn) {
+		super(statusCodeIn);
+	}
+
+	public PolicyIssuer() {
+	}
+	
+	public Node getContent() {
+		return this.content;
+	}
+	
+	public void setContent(Node nodeContent) {
+		this.content	= nodeContent;
+	}
+	
+	public Iterator<Attribute> getAttributes() {
+		return (this.attributes == null ? null : this.attributes.iterator());
+	}
+	
+	public void setAttributes(Collection<Attribute> listAttributes) {
+		this.attributes	= null;
+		if (listAttributes != null) {
+			this.add(listAttributes);
+		}
+	}
+	
+	public void add(Attribute attribute) {
+		if (this.attributes == null) {
+			this.attributes	= new ArrayList<Attribute>();
+		}
+		this.attributes.add(attribute);
+	}
+	
+	public void add(Collection<Attribute> listAttributes) {
+		if (this.attributes == null) {
+			this.attributes = new ArrayList<Attribute>();
+		}
+		this.attributes.addAll(listAttributes);
+	}
+	
+	@Override
+	public String toString() {
+		StringBuilder stringBuilder	= new StringBuilder("{");
+		
+		stringBuilder.append("super=");
+		stringBuilder.append(super.toString());
+		
+		Object objectToDump;
+		if ((objectToDump = this.getContent()) != null) {
+			stringBuilder.append(",content=");
+			stringBuilder.append(objectToDump.toString());
+		}
+		Iterator<Attribute> iterAttributes	= this.getAttributes();
+		if (iterAttributes != null && iterAttributes.hasNext()) {
+			stringBuilder.append(",attributes=[");
+			stringBuilder.append(iterAttributes.next().toString());
+			while (iterAttributes.hasNext()) {
+				stringBuilder.append(',');
+				stringBuilder.append(iterAttributes.next().toString());
+			}
+			stringBuilder.append(']');
+		}
+		stringBuilder.append('}');
+		return stringBuilder.toString();
+	}
+
+	@Override
+	protected boolean validateComponent() {
+		this.setStatus(StdStatusCode.STATUS_CODE_OK, null);
+		return true;
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicySet.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicySet.java
new file mode 100755
index 0000000..a4333be
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicySet.java
@@ -0,0 +1,259 @@
+/*
+ *                        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.policy;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.Decision;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.Result;
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacml.api.trace.Traceable;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.trace.StdTraceEvent;
+import com.att.research.xacml.util.StringUtils;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationResult;
+import com.att.research.xacmlatt.pdp.eval.MatchResult;
+
+/**
+ * PolicySet extends {@link PolicyDef} to represent a XACML PolicySet element.
+ * 
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class PolicySet extends PolicyDef {
+	private TargetedCombinerParameterMap<Identifier,PolicySetChild>		policyCombinerParameters	= new TargetedCombinerParameterMap<Identifier,PolicySetChild>();
+	private List<PolicySetChild>										children;
+	private List<CombiningElement<PolicySetChild>>						combiningPolicies;
+	private CombiningAlgorithm<PolicySetChild>							combiningAlgorithm;
+	
+	private void ensureChildren() {
+		if (this.children == null) {
+			this.children	= new ArrayList<PolicySetChild>();
+		}
+	}
+	
+	/**
+	 * Performs lazy evaluation of the combining parameters from this <code>Policy</code>.
+	 * 
+	 * @return the <code>List</code> of <code>CombiningElement</code>s for all of the <code>Rule</code>s
+	 */
+	protected List<CombiningElement<PolicySetChild>> getCombiningPolicies() {
+		if (this.combiningPolicies == null) {
+			this.combiningPolicies			= new ArrayList<CombiningElement<PolicySetChild>>();
+			Iterator<PolicySetChild> iterPolicies	= this.getChildren();
+			if (iterPolicies != null) {
+				while (iterPolicies.hasNext()) {
+					PolicySetChild policySetChild	= iterPolicies.next();
+					this.combiningPolicies.add(new CombiningElement<PolicySetChild>(policySetChild, this.policyCombinerParameters.getCombinerParameters(policySetChild)));
+				}
+			}
+		}
+		return this.combiningPolicies;
+	}
+	
+	@Override
+	protected boolean validateComponent() {
+		if (super.validateComponent()) {
+			if (this.getPolicyCombiningAlgorithm() == null) {
+				this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing policy combining algorithm");
+				return false;
+			} else {
+				return true;
+			}
+		} else {
+			return false;
+		}
+	}
+
+	public PolicySet(StatusCode statusCodeIn, String statusMessageIn) {
+		super(statusCodeIn, statusMessageIn);
+	}
+
+	public PolicySet(StatusCode statusCodeIn) {
+		super(statusCodeIn);
+	}
+	
+	public PolicySet(PolicySet policySetParent) {
+		super(policySetParent);
+	}
+
+	public PolicySet() {
+	}
+	
+	/**
+	 * Gets an <code>Iterator</code> over the {@link com.att.research.xacmlatt.pdp.policy.TargetedCombinerParameter}s 
+	 * for {@link Policy} elements in this
+	 * <code>PolicySet</code>.
+	 * 
+	 * @return an <code>Iterator</code> over the <code>TargetedCombinerParameter</code>s for <code>Policy</code> elements in this
+	 * <code>PolicySet</code>.
+	 */
+	public Iterator<TargetedCombinerParameter<Identifier,PolicySetChild>> getPolicyCombinerParameters() {
+		return this.policyCombinerParameters.getTargetedCombinerParameters();
+	}
+
+	/**
+	 * Sets the Policy combiner parameters for this <code>PolicySet</code> from the contents of the given <code>Collection</code>
+	 * of <code>TargetedCombinerParameter</code>s.
+	 * 
+	 * @param policyCombinerParametersIn the <code>Collection</code> of <code>TargetedCombinerParameter</code>s.
+	 */
+	public void setPolicyCombinerParameters(Collection<TargetedCombinerParameter<Identifier,PolicySetChild>> policyCombinerParametersIn) {
+		this.policyCombinerParameters.setCombinerParameters(policyCombinerParametersIn);
+	}
+	
+	public void addPolicyCombinerParameter(TargetedCombinerParameter<Identifier,PolicySetChild> policyCombinerParameter) {
+		this.policyCombinerParameters.addCombinerParameter(policyCombinerParameter);
+	}
+	
+	public void addPolicyCombinerParameters(Collection<TargetedCombinerParameter<Identifier,PolicySetChild>> policyCombinerParametersIn) {
+		this.policyCombinerParameters.addCombinerParameters(policyCombinerParametersIn);
+	}
+	
+	/**
+	 * Gets an <code>Iterator</code> over the <code>PolicySetChild</code> children of this <code>PolicySet</code>.
+	 * 
+	 * @return an <code>Iterator</code> over the <code>PolicySetChild</code> children of this <code>PolicySet</code> or null if there are none.
+	 */
+	public Iterator<PolicySetChild> getChildren() {
+		return (this.children == null ? null : this.children.iterator());
+	}
+	
+	public void setChildren(Collection<PolicySetChild> policySetChildren) {
+		this.children	= null;
+		if (policySetChildren != null) {
+			this.addChildren(policySetChildren);
+		}
+	}
+	
+	public void addChild(PolicySetChild policySetChild) {
+		this.ensureChildren();
+		this.children.add(policySetChild);
+	}
+	
+	public void addChildren(Collection<PolicySetChild> policySetChildren) {
+		this.ensureChildren();
+		this.children.addAll(policySetChildren);
+	}
+	
+	/**
+	 * Gets the {@link com.att.research.xacmlatt.pdp.policy.CombiningAlgorithm} for <code>PolicySetChild</code> children for this <code>PolicySet</code>.
+	 * 
+	 * @return the <code>CombiningAlgorithm</code> for <code>PolicySetChild</code> children for this <code>PolicySet</code>.
+	 */
+	public CombiningAlgorithm<PolicySetChild> getPolicyCombiningAlgorithm() {
+		return this.combiningAlgorithm;
+	}
+	
+	public void setPolicyCombiningAlgorithm(CombiningAlgorithm<PolicySetChild> combiningAlgorithmIn) {
+		this.combiningAlgorithm	= combiningAlgorithmIn;
+	}
+
+	@Override
+	public EvaluationResult evaluate(EvaluationContext evaluationContext) throws EvaluationException {
+		/*
+		 * First check to see if we are valid.  If not, return an error status immediately
+		 */
+		if (evaluationContext.isTracing()) {
+			evaluationContext.trace(new StdTraceEvent<Object>("PolicySet", this, null));
+		}
+		if (!this.validate()) {
+			return new EvaluationResult(new StdStatus(this.getStatusCode(), this.getStatusMessage()));
+		}
+		
+		/*
+		 * See if we match
+		 */
+		MatchResult thisMatchResult	= this.match(evaluationContext);
+		assert(thisMatchResult != null);
+		if (evaluationContext.isTracing()) {
+			evaluationContext.trace(new StdTraceEvent<MatchResult>("Match", this, thisMatchResult));
+		}
+		switch(thisMatchResult.getMatchCode()) {
+		case INDETERMINATE:
+			return new EvaluationResult(Decision.INDETERMINATE, thisMatchResult.getStatus());
+		case MATCH:
+			break;
+		case NOMATCH:
+			return new EvaluationResult(Decision.NOTAPPLICABLE);
+		}
+		
+		/*
+		 * Get the combining elements
+		 */
+		List<CombiningElement<PolicySetChild>> listCombiningElements	= this.getCombiningPolicies();
+		assert(listCombiningElements != null);
+		
+		/*
+		 * Run the PolicyCombiningAlgorithm
+		 */
+		assert(this.getPolicyCombiningAlgorithm() != null);
+		EvaluationResult evaluationResultCombined	= this.getPolicyCombiningAlgorithm().combine(evaluationContext, listCombiningElements, getCombinerParameterList());
+		assert(evaluationResultCombined != null);
+		
+		if (evaluationResultCombined.getDecision() == Decision.DENY || evaluationResultCombined.getDecision() == Decision.PERMIT) {
+			this.updateResult(evaluationResultCombined, evaluationContext);
+			
+			/*
+			 * Add my id to the policy set identifiers
+			 */
+			if (evaluationContext.getRequest().getReturnPolicyIdList()) {
+				evaluationResultCombined.addPolicySetIdentifier(this.getIdReference());
+			}
+		}
+		if (evaluationContext.isTracing()) {
+			evaluationContext.trace(new StdTraceEvent<Result>("Result", this, evaluationResultCombined));
+		}
+		return evaluationResultCombined;
+	}
+
+	@Override
+	public String toString() {
+		StringBuilder stringBuilder	= new StringBuilder("{");
+		stringBuilder.append("super=");
+		stringBuilder.append(super.toString());
+		
+		String iteratorToDump;
+		if ((iteratorToDump = StringUtils.toString(this.getPolicyCombinerParameters())) != null) {
+			stringBuilder.append(",policyCombinerParameters=");
+			stringBuilder.append(iteratorToDump);
+		}
+		if ((iteratorToDump = StringUtils.toString(this.getChildren())) != null) {
+			stringBuilder.append(",children=");
+			stringBuilder.append(iteratorToDump);
+		}
+		Object objectToDump;
+		if ((objectToDump = this.getPolicyCombiningAlgorithm()) != null) {
+			stringBuilder.append(",policyCombiningAlgorithm=");
+			stringBuilder.append(objectToDump.toString());
+		}
+		
+		stringBuilder.append('}');
+		return stringBuilder.toString();
+	}
+
+	@Override
+	public String getTraceId() {
+		return this.getIdentifier().stringValue();
+	}
+
+	@Override
+	public Traceable getCause() {
+		return null;
+	}
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicySetChild.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicySetChild.java
new file mode 100755
index 0000000..eeae452
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicySetChild.java
@@ -0,0 +1,149 @@
+/*
+ *                        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.policy;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacml.api.trace.Traceable;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacmlatt.pdp.eval.Evaluatable;
+import com.att.research.xacmlatt.pdp.eval.Matchable;
+
+/**
+ * PolicySetChild extends {@link com.att.research.xacmlatt.pdp.PolicyComponent} to represent XACML 3.0 Policies, PolicySets, PolicyReferences,
+ * and PolicySetReferences.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public abstract class PolicySetChild extends PolicyComponent implements Evaluatable, Matchable, Traceable {
+	private Identifier		identifier;
+	private PolicyDefaults	policyDefaults;
+	private PolicySet parent;
+	
+	/**
+	 * Creates a new <code>PolicySetChild</code> with the given given {@link com.att.research.xacml.api.StatusCode} 
+	 * and <code>String</code> status message.
+	 * 
+	 * @param statusCodeIn the <code>StatusCode</code> for the new <code>PolicySetChild</code>
+	 * @param statusMessageIn the <code>String</code> status message for the new <code>PolicySetChild</code>
+	 */
+	protected PolicySetChild(PolicySet parentIn, StatusCode statusCodeIn, String statusMessageIn) {
+		super(statusCodeIn, statusMessageIn);
+		this.parent	= parentIn;
+	}
+	
+	protected PolicySetChild(StatusCode statusCodeIn, String statusMessageIn) {
+		this(null, statusCodeIn, statusMessageIn);
+	}
+	
+	/**
+	 * Creates a new <code>PolicySetChild</code> with the default OK <code>StatusCode</code>.
+	 * 
+	 * @param statusCodeIn the <code>StatusCode</code> for this <code>PolicySetChild</code>
+	 */
+	protected PolicySetChild(StatusCode statusCodeIn) {
+		super(statusCodeIn);
+	}
+	
+	protected PolicySetChild(PolicySet parentIn) {
+		this.parent	= parentIn;
+	}
+	
+	/**
+	 * Creates a new <code>PolicySetChild</code> with the default OK status.
+	 */
+	protected PolicySetChild() {
+		super();
+	}
+	
+	/**
+	 * Gets the <code>Identifier</code> for this <code>PolicySetChild</code>.
+	 * 
+	 * @return the <code>Identifier</code> for this <code>PolicySetChild</code>
+	 */
+	public Identifier getIdentifier() {
+		return this.identifier;
+	}
+	
+	public void setIdentifier(Identifier identifierIn) {
+		this.identifier	= identifierIn;
+	}
+	
+	/**
+	 * Gets the <code>PolicyDefaults</code> for this <code>PolicySetChild</code>.
+	 * 
+	 * @return the <code>PolicyDefaults</code> for this <code>PolicySetChild</code>
+	 */
+	public PolicyDefaults getPolicyDefaults() {
+		return this.policyDefaults;
+	}
+	
+	/**
+	 * Sets the <code>PolicyDefaults</code> for this <code>PolicySetChild</code>.
+	 * 
+	 * @param policyDefaultsIn the <code>PolicyDefaults</code> for this <code>PolicySetChild</code>
+	 */
+	public void setPolicyDefaults(PolicyDefaults policyDefaultsIn) {
+		this.policyDefaults	= policyDefaultsIn;
+	}
+	
+	/**
+	 * Gets the parent {@link PolicySet} containing this <code>PolicySetChild</code>
+	 * or null if this is the root.
+	 *  
+	 * @return the parent <code>PolicySet</code> of this <code>PolicySetChild</code>
+	 */
+	public PolicySet getParent() {
+		return this.parent;
+	}
+	
+	@Override
+	protected boolean validateComponent() {
+		if (this.getIdentifier() == null) {
+			this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing identifier");
+			return false;
+		} else {
+			this.setStatus(StdStatusCode.STATUS_CODE_OK, null);
+			return true;
+		}
+	}
+	
+	@Override
+	public String getTraceId() {
+		return this.getIdentifier().stringValue();
+	}
+	
+	@Override
+	public Traceable getCause() {
+		return this.parent;
+	}
+
+	@Override
+	public String toString() {
+		StringBuilder stringBuilder	= new StringBuilder("{");
+		
+		stringBuilder.append("super=");
+		stringBuilder.append(super.toString());
+		
+		Object objectToDump;
+		if ((objectToDump = this.getIdentifier()) != null) {
+			stringBuilder.append(",identifier=");
+			stringBuilder.append(objectToDump.toString());
+		}
+		if ((objectToDump = this.getPolicyDefaults()) != null) {
+			stringBuilder.append(",policyDefaults=");
+			stringBuilder.append(objectToDump.toString());
+		}
+		stringBuilder.append('}');
+		return stringBuilder.toString();
+	}
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicySetIdReference.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicySetIdReference.java
new file mode 100755
index 0000000..adb96a9
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicySetIdReference.java
@@ -0,0 +1,57 @@
+/*
+ *                        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.policy;
+
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+
+/**
+ * PolicySetIdReference extends {@link com.att.research.xacmlatt.pdp.policy.PolicyIdReferenceBase} for
+ * {@link com.att.research.xacmlatt.pdp.PolicySet} objects to implement the <code>ensureReferencee</code>
+ * method to find <code>PolicySet</code>s.
+ * 
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class PolicySetIdReference extends PolicyIdReferenceBase<PolicySet> {
+
+	public PolicySetIdReference(PolicySet policySetParent, StatusCode statusCodeIn, String statusMessageIn) {
+		super(policySetParent, statusCodeIn, statusMessageIn);
+	}
+	
+	public PolicySetIdReference(StatusCode statusCodeIn, String statusMessageIn) {
+		super(statusCodeIn, statusMessageIn);
+	}
+
+	public PolicySetIdReference(StatusCode statusCodeIn) {
+		super(statusCodeIn);
+	}
+	
+	public PolicySetIdReference(PolicySet policySetParent) {
+		super(policySetParent);
+	}
+
+	public PolicySetIdReference() {
+	}
+
+	@Override
+	protected PolicySet ensureReferencee(EvaluationContext evaluationContext) throws EvaluationException {
+		if (this.getReferencee() == null) {
+			PolicyFinderResult<PolicySet> policyFactoryResult	= evaluationContext.getPolicySet(this.getIdReferenceMatch());
+			if (policyFactoryResult.getStatus() == null || policyFactoryResult.getStatus().isOk()) {
+				this.setReferencee(policyFactoryResult.getPolicyDef());
+			}
+		}
+		return this.getReferencee();
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Rule.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Rule.java
new file mode 100755
index 0000000..467255b
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Rule.java
@@ -0,0 +1,299 @@
+/*
+ *                        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.policy;
+
+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.Decision;
+import com.att.research.xacml.api.Obligation;
+import com.att.research.xacml.api.Result;
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacml.api.trace.Traceable;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.trace.StdTraceEvent;
+import com.att.research.xacml.util.StringUtils;
+import com.att.research.xacmlatt.pdp.eval.Evaluatable;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationResult;
+import com.att.research.xacmlatt.pdp.eval.MatchResult;
+import com.att.research.xacmlatt.pdp.eval.Matchable;
+
+/**
+ * Rule extends {@link com.att.research.xacmlatt.pdp.policy.PolicyComponent} to represent a XACML Rule within a Policy.  It implements
+ * {@link com.att.research.xacmlatt.pdp.eval.Matchable} and {@link com.att.research.xacmlatt.pdp.eval.Evaluatable} for matching and evaluation
+ * a request.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class Rule extends PolicyComponent implements Matchable, Evaluatable, Traceable {
+	private Policy						policy;
+	private String						ruleId;
+	private RuleEffect					ruleEffect;
+	private String 						description;
+	private Target						target;
+	private Condition					condition;
+	private List<ObligationExpression>	obligationExpressions	= new ArrayList<ObligationExpression>();
+	private List<AdviceExpression>		adviceExpressions		= new ArrayList<AdviceExpression>();
+	
+	protected List<ObligationExpression> getObligationExpressionList() {
+		return this.obligationExpressions;
+	}
+	
+	protected void clearObligationExpressions() {
+		this.getObligationExpressionList().clear();
+	}
+	
+	protected List<AdviceExpression> getAdviceExpressionList() {
+		return this.adviceExpressions;
+	}
+	
+	protected void clearAdviceExpressions() {
+		this.getAdviceExpressionList().clear();
+	}
+	
+	public Rule(StatusCode statusCodeIn, String statusMessageIn) {
+		super(statusCodeIn, statusMessageIn);
+	}
+
+	public Rule(StatusCode statusCodeIn) {
+		super(statusCodeIn);
+	}
+
+	public Rule() {
+	}
+	
+	public Policy getPolicy() {
+		return this.policy;
+	}
+	
+	public void setPolicy(Policy policyIn) {
+		this.policy	= policyIn;
+	}
+	
+	public String getRuleId() {
+		return this.ruleId;
+	}
+	
+	public void setRuleId(String ruleIdIn) {
+		this.ruleId	= ruleIdIn;
+	}
+	
+	public RuleEffect getRuleEffect() {
+		return this.ruleEffect;
+	}
+	
+	public void setRuleEffect(RuleEffect ruleEffectIn) {
+		this.ruleEffect	= ruleEffectIn;
+	}
+	
+	public String getDescription() {
+		return this.description;
+	}
+	
+	public void setDescription(String descriptionIn) {
+		this.description	= descriptionIn;
+	}
+	
+	public Target getTarget() {
+		return this.target;
+	}
+	
+	public void setTarget(Target targetIn) {
+		this.target	= targetIn;
+	}
+	
+	public Condition getCondition() {
+		return this.condition;
+	}
+	
+	public void setCondition(Condition conditionIn) {
+		this.condition	= conditionIn;
+	}
+	
+	public Iterator<ObligationExpression> getObligationExpressions() {
+		return (this.obligationExpressions == null ? null : this.obligationExpressions.iterator());
+	}
+	
+	public void setObligationExpressions(Collection<ObligationExpression> obligationExpressionsIn) {
+		this.clearObligationExpressions();
+		if (obligationExpressionsIn != null) {
+			this.addObligationExpressions(obligationExpressionsIn);
+		}
+	}
+	
+	public void addObligationExpression(ObligationExpression obligationExpression) {
+		this.getObligationExpressionList().add(obligationExpression);
+	}
+	
+	public void addObligationExpressions(Collection<ObligationExpression> obligationExpressionsIn) {
+		this.getObligationExpressionList().addAll(obligationExpressionsIn);
+	}
+
+	public Iterator<AdviceExpression> getAdviceExpressions() {
+		return (this.adviceExpressions == null ? null : this.adviceExpressions.iterator());
+	}
+	
+	public void setAdviceExpressions(Collection<AdviceExpression> adviceExpressionsIn) {
+		this.clearAdviceExpressions();
+		if (adviceExpressionsIn != null) {
+			this.addAdviceExpressions(adviceExpressionsIn);
+		}
+	}
+	
+	public void addAdviceExpression(AdviceExpression adviceExpression) {
+		this.getAdviceExpressionList().add(adviceExpression);
+	}
+	
+	public void addAdviceExpressions(Collection<AdviceExpression> adviceExpressionsIn) {
+		this.getAdviceExpressionList().addAll(adviceExpressionsIn);
+	}
+
+	@Override
+	public EvaluationResult evaluate(EvaluationContext evaluationContext) throws EvaluationException {
+		if (!this.validate()) {
+			return new EvaluationResult(new StdStatus(this.getStatusCode(), this.getStatusMessage()));
+		}
+		
+		/*
+		 * See if our target matches
+		 */
+		MatchResult matchResult	= this.match(evaluationContext);
+		if (evaluationContext.isTracing()) {
+			evaluationContext.trace(new StdTraceEvent<MatchResult>("Match", this, matchResult));
+		}
+		switch(matchResult.getMatchCode()) {
+		case INDETERMINATE:
+			return new EvaluationResult(Decision.INDETERMINATE, matchResult.getStatus());
+		case MATCH:
+			break;
+		case NOMATCH:
+			return new EvaluationResult(Decision.NOTAPPLICABLE);
+		}
+		
+		/*
+		 * See if our condition matches
+		 */
+		Condition thisCondition	= this.getCondition();
+		if (thisCondition != null) {
+			ExpressionResultBoolean expressionResultCondition	= thisCondition.evaluate(evaluationContext, this.getPolicy().getPolicyDefaults());
+			assert(expressionResultCondition != null);
+			
+			if (evaluationContext.isTracing()) {
+				evaluationContext.trace(new StdTraceEvent<ExpressionResultBoolean>("Condition", this, expressionResultCondition));
+			}
+			
+			if (!expressionResultCondition.isOk()) {
+				return new EvaluationResult(Decision.INDETERMINATE, expressionResultCondition.getStatus());
+			} else if (!expressionResultCondition.isTrue()) {
+				return new EvaluationResult(Decision.NOTAPPLICABLE);
+			}
+		}
+		
+		/*
+		 * The target and condition match, so we can start creating the EvaluationResult
+		 */
+		List<Obligation> listObligations	= ObligationExpression.evaluate(evaluationContext, this.getPolicy().getPolicyDefaults(), this.getRuleEffect().getDecision(), this.getObligationExpressionList());
+		List<Advice> listAdvices			= AdviceExpression.evaluate(evaluationContext, this.getPolicy().getPolicyDefaults(), this.getRuleEffect().getDecision(), this.getAdviceExpressionList());
+		
+		EvaluationResult evaluationResult	= new EvaluationResult(this.getRuleEffect().getDecision(), listObligations, listAdvices);
+		if (evaluationContext.isTracing()) {
+			evaluationContext.trace(new StdTraceEvent<Result>("Result", this, evaluationResult));
+		}
+		return evaluationResult;
+	}
+
+	@Override
+	public MatchResult match(EvaluationContext evaluationContext) throws EvaluationException {
+		if (!this.validate()) {
+			return new MatchResult(new StdStatus(this.getStatusCode(), this.getStatusMessage()));
+		}
+		Target thisTarget	= this.getTarget();
+		if (thisTarget != null) {
+			return thisTarget.match(evaluationContext);
+		} else {
+			return MatchResult.MM_MATCH;
+		}
+	}
+
+	@Override
+	protected boolean validateComponent() {
+		if (this.getRuleId() == null) {
+			this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing rule id");
+			return false;
+		} else if (this.getPolicy() == null) {
+			this.setStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Rule not in a Policy");
+			return false;
+		} else if (this.getRuleEffect() == null) {
+			this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing effect");
+			return false;
+		}
+		return true;
+	}
+	
+	@Override
+	public String toString() {
+		StringBuffer stringBuffer	= new StringBuffer("{");
+		stringBuffer.append("super=");
+		stringBuffer.append(super.toString());
+		
+		Object objectToDump;
+		if ((objectToDump = this.getRuleId()) != null) {
+			stringBuffer.append(",ruleId=");
+			stringBuffer.append((String)objectToDump);
+		}
+		if ((objectToDump = this.getRuleEffect()) != null) {
+			stringBuffer.append(",ruleEffect=");
+			stringBuffer.append(objectToDump.toString());
+		}
+		if ((objectToDump = this.getDescription()) != null) {
+			stringBuffer.append(",description=");
+			stringBuffer.append((String)objectToDump);
+		}
+		if ((objectToDump = this.getTarget()) != null) {
+			stringBuffer.append(",target=");
+			stringBuffer.append(objectToDump.toString());
+		}
+		if ((objectToDump = this.getCondition()) != null) {
+			stringBuffer.append(",condition=");
+			stringBuffer.append(objectToDump.toString());
+		}
+		
+		String iterToDump;
+		if ((iterToDump = StringUtils.toString(this.getObligationExpressions())) != null) {
+			stringBuffer.append(",obligationExpressions=");
+			stringBuffer.append(iterToDump);
+		}
+		if ((iterToDump = StringUtils.toString(this.getAdviceExpressions())) != null) {
+			stringBuffer.append(",adviceExpressions=");
+			stringBuffer.append(iterToDump);
+		}
+		stringBuffer.append('}');
+		return stringBuffer.toString();
+	}
+
+	@Override
+	public String getTraceId() {
+		return this.getRuleId();
+	}
+
+	@Override
+	public Traceable getCause() {
+		return this.policy;
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/RuleEffect.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/RuleEffect.java
new file mode 100755
index 0000000..bdf95e3
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/RuleEffect.java
@@ -0,0 +1,61 @@
+/*
+ *                        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.policy;
+
+import com.att.research.xacml.api.Decision;
+
+/**
+ * RuleEffect is an enumeration of the XACML decision effects that a {@link Rule} may apply
+ * to.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public enum RuleEffect {
+	DENY("Deny", Decision.DENY),
+	PERMIT("Permit", Decision.PERMIT)
+	;
+	
+	private String name;
+	private Decision decision;
+	private RuleEffect(String nameIn, Decision decisionIn) {
+		this.name		= nameIn;
+		this.decision	= decisionIn;
+	}
+	
+	public String getName() {
+		return this.name;
+	}
+	
+	public Decision getDecision() {
+		return this.decision;
+	}
+	
+	@Override
+	public String toString() {
+		return this.getName();
+	}
+	
+	/**
+	 * Maps a XACML rule effect <code>String</code> name to the matching <code>RuleEffect</code>.
+	 * 
+	 * @param effectName the <code>String</code> effect name to match
+	 * @return the matching <code>RuleEffect</code> or null if there is no match
+	 */
+	public static RuleEffect getRuleEffect(String effectName) {
+		for (RuleEffect ruleEffect: RuleEffect.values()) {
+			if (ruleEffect.getName().equalsIgnoreCase(effectName)) {
+				return ruleEffect;
+			}
+		}
+		return null;
+	}
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Target.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Target.java
new file mode 100755
index 0000000..b4eac6c
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Target.java
@@ -0,0 +1,138 @@
+/*
+ *                        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.policy;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.util.StringUtils;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.eval.MatchResult;
+import com.att.research.xacmlatt.pdp.eval.Matchable;
+
+/**
+ * Target extends {@link com.att.research.xacmlatt.pdp.policy.PolicyComponent} to implement XACML 3.0 Target elements for
+ * Policies, PolicySets, and Rules.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class Target extends PolicyComponent implements Matchable {
+	private List<AnyOf>	anyOfs;
+	
+	protected List<AnyOf> getAnyOfList(boolean bNoNull) {
+		if (this.anyOfs == null && bNoNull) {
+			this.anyOfs	= new ArrayList<AnyOf>();
+		}
+		return this.anyOfs;
+	}
+	
+	protected void clearAnyOfList() {
+		if (this.anyOfs != null) {
+			this.anyOfs.clear();
+		}
+	}
+	
+	public Target(StatusCode statusCodeIn, String statusMessageIn) {
+		super(statusCodeIn, statusMessageIn);
+	}
+
+	public Target(StatusCode statusCodeIn) {
+		super(statusCodeIn);
+	}
+
+	public Target() {
+	}
+	
+	public Target(Collection<AnyOf> anyOfsIn) {
+		if (anyOfsIn != null) {
+			this.addAnyOfs(anyOfsIn);
+		}
+	}
+	
+	public Target(AnyOf anyOfIn) {
+		if (anyOfIn != null) {
+			this.addAnyOf(anyOfIn);
+		}
+	}
+	
+	/**
+	 * Gets an <code>Iterator</code> over all of the {@link AnyOf}s in this <code>Target</code>.
+	 * 
+	 * @return an <code>Iterator</code> over all of the <code>AnyOf</code>s in this <code>Target</code> or null if there are none
+	 */
+	public Iterator<AnyOf> getAnyOfs() {
+		return (this.anyOfs == null ? null : this.anyOfs.iterator());
+	}
+	
+	public void setAnyOfs(Collection<AnyOf> anyOfsIn) {
+		this.clearAnyOfList();
+		if (anyOfsIn != null) {
+			this.addAnyOfs(anyOfsIn);
+		}
+	}
+	
+	public void addAnyOf(AnyOf anyOfIn) {
+		List<AnyOf> listAnyOfs	= this.getAnyOfList(true);
+		listAnyOfs.add(anyOfIn);
+	}
+	
+	public void addAnyOfs(Collection<AnyOf> anyOfsIn) {
+		List<AnyOf> listAnyOfs	= this.getAnyOfList(true);
+		listAnyOfs.addAll(anyOfsIn);
+	}
+
+	@Override
+	public MatchResult match(EvaluationContext evaluationContext) throws EvaluationException {
+		if (!this.validate()) {
+			return new MatchResult(new StdStatus(this.getStatusCode(), this.getStatusMessage()));
+		}
+		Iterator<AnyOf> iterAnyOfs	= this.getAnyOfs();
+		if (iterAnyOfs == null || !iterAnyOfs.hasNext()) {
+			return MatchResult.MM_MATCH;
+		} else {
+			MatchResult matchResult	= MatchResult.MM_MATCH;
+			while (iterAnyOfs.hasNext()) {
+				matchResult	= iterAnyOfs.next().match(evaluationContext);
+				if (matchResult.getMatchCode() != MatchResult.MatchCode.MATCH) {
+					return matchResult;
+				}
+			}
+			return matchResult;
+		}
+	}
+
+	@Override
+	protected boolean validateComponent() {
+		return true;
+	}
+	
+	@Override
+	public String toString() {
+		StringBuilder stringBuilder	= new StringBuilder("{");
+		stringBuilder.append("super=");
+		stringBuilder.append(super.toString());
+		
+		String iterToDump	= StringUtils.toString(this.getAnyOfs());
+		if (iterToDump != null) {
+			stringBuilder.append(",anyOfs=");
+			stringBuilder.append(iterToDump);
+		}
+		stringBuilder.append('}');
+		return stringBuilder.toString();
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameter.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameter.java
new file mode 100755
index 0000000..f93b520
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameter.java
@@ -0,0 +1,107 @@
+/*
+ *                        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.policy;
+
+import com.att.research.xacml.api.AttributeValue;
+import com.att.research.xacml.api.StatusCode;
+
+/**
+ * TargetedCombinerParameter extends {@link CombinerParameter} to include a lazy
+ * reference to a particular sub-element within the evaluatable children that should be used when combining evaluation
+ * results from that sub-element.
+ * 
+ * @author car
+ *
+ * @param <T> the type of the identifier used to reference the targeted object
+ * @param <U> the type of the targeted object
+ */
+public class TargetedCombinerParameter<T, U> extends CombinerParameter {
+	private T	targetId;
+	private U	target;
+	
+	public TargetedCombinerParameter(T targetIdIn, String nameIn, AttributeValue<?> attributeValueIn, StatusCode statusCodeIn, String statusMessageIn) {
+		super(nameIn, attributeValueIn, statusCodeIn, statusMessageIn);
+		this.targetId	= targetIdIn;
+	}
+
+	public TargetedCombinerParameter(StatusCode statusCodeIn, String statusMessageIn) {
+		super(statusCodeIn, statusMessageIn);
+	}
+
+	public TargetedCombinerParameter(StatusCode statusCodeIn) {
+		super(statusCodeIn);
+	}
+
+	public TargetedCombinerParameter(T targetIdIn, String nameIn, AttributeValue<?> attributeValueIn) {
+		super(nameIn, attributeValueIn);
+		this.targetId	= targetIdIn;
+	}
+	
+	public TargetedCombinerParameter() {
+		
+	}
+	
+	/**
+	 * Gets the target id of this <code>TargetedCombinerParameter</code>.
+	 * 
+	 * @return the <code>T</code> id of this <code>TargetedCombinerParameter</code>
+	 */
+	public T getTargetId() {
+		return this.targetId;
+	}
+	
+	/**
+	 * Sets the target id to the given <code>T</code> value.
+	 * 
+	 * @param targetIdIn the <code>T</code> to set as the target id
+	 */
+	public void setTargetId(T targetIdIn) {
+		this.targetId	= targetIdIn;
+	}
+	
+	/**
+	 * Gets the target for this <code>TargetedCombinerParameter</code>.
+	 * 
+	 * @return the <code>U</code> target for this <code>TargetedCombinerParameter</code>
+	 */
+	public U getTarget() {
+		return this.target;
+	}
+	
+	/**
+	 * Sets the target for this <code>TargetedCombinerParameter</code> to the given <code>U</code>.
+	 * 
+	 * @param targetIn the <code>U</code> target for this <code>TargetedCombinerParameter</code>
+	 */
+	public void setTarget(U targetIn) {
+		this.target	= targetIn;
+	}
+	
+	@Override
+	public String toString() {
+		StringBuilder stringBuilder	= new StringBuilder("{");
+		stringBuilder.append("super=");
+		stringBuilder.append(super.toString());
+		
+		Object objectToDump;
+		if ((objectToDump = this.getTargetId()) != null) {
+			stringBuilder.append("targetId=");
+			stringBuilder.append(objectToDump.toString());
+		}
+		if ((objectToDump = this.getTarget()) != null) {
+			stringBuilder.append("target=");
+			stringBuilder.append(objectToDump.toString());
+		}
+		stringBuilder.append('}');
+		return stringBuilder.toString();
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameterMap.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameterMap.java
new file mode 100755
index 0000000..1ffa5c0
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameterMap.java
@@ -0,0 +1,155 @@
+/*
+ *                        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.policy;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * TargetedCombinerParameterMap is a utility for maintaining a collection of {@link com.att.research.xacmlatt.policy.TargetedCombinerParameter}
+ * objects with the mappings to their targets.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ *
+ * @param <T> the type of the identifier for the <code>TargetedCombinerParameter</code>s in the map
+ * @param <U> the type of the object referenced by the identifier
+ */
+public class TargetedCombinerParameterMap<T, U> {
+	List<TargetedCombinerParameter<T,U>>	targetedCombinerParameters		= null;
+	Map<T,U>								mapTargetIdToTarget				= new HashMap<T,U>();
+	Map<U,List<CombinerParameter>>			mapTargetToCombinerParameters	= null;
+	
+	private void ensureTargetedCombinerParameters() {
+		if (this.targetedCombinerParameters == null) {
+			this.targetedCombinerParameters	= new ArrayList<TargetedCombinerParameter<T,U>>();
+		}
+	}
+	
+	/**
+	 * Gets the target from the given <code>TargetedCombinerParameter</code> if present.  If not, find the
+	 * target in the target id to target mapping, update the <code>TargetedCombinerParameter</code> and then
+	 * return the target.
+	 * 
+	 * @param targetedCombinerParameter the <code>TargetedCombinerParameter</code> to resolve
+	 * @return the target for the given <code>TargetedCombinerParameter</code>
+	 */
+	protected U resolve(TargetedCombinerParameter<T,U> targetedCombinerParameter) {
+		U result;
+		if ((result = targetedCombinerParameter.getTarget()) != null) {
+			return result;
+		} else if ((result = this.mapTargetIdToTarget.get(targetedCombinerParameter.getTargetId())) != null) {
+			targetedCombinerParameter.setTarget(result);
+			return result;
+		} else {
+			return null;
+		}
+	}
+	
+	/**
+	 * Ensures the <code>Map</code> from targets to <code>List</code> of <code>CombinerParameter</code>s has been
+	 * created if needed.
+	 * 
+	 * @throws IllegalStateException if there are <code>TargetedCombinerParameter</code>s that cannot be resolved
+	 */
+	protected void ensureMap() throws IllegalStateException {
+		if (this.mapTargetToCombinerParameters == null) {
+			if (this.targetedCombinerParameters != null && this.targetedCombinerParameters.size() > 0) {
+				this.mapTargetToCombinerParameters	= new HashMap<U,List<CombinerParameter>>();
+				for (TargetedCombinerParameter<T,U> targetedCombinerParameter: this.targetedCombinerParameters) {
+					U	target	= this.resolve(targetedCombinerParameter);
+					if (target == null) {
+						throw new IllegalStateException("Unresolved TargetCombinerParameter \"" + targetedCombinerParameter.toString() + "\"");
+					}
+					List<CombinerParameter>	listCombinerParameters	= this.mapTargetToCombinerParameters.get(target);
+					if (listCombinerParameters == null) {
+						listCombinerParameters	= new ArrayList<CombinerParameter>();
+						this.mapTargetToCombinerParameters.put(target, listCombinerParameters);
+					}
+					listCombinerParameters.add(targetedCombinerParameter);
+				}
+			}
+		}
+	}
+	
+	/**
+	 * Creates a new <code>TargetedCombinerParameterMap</code>.
+	 */
+	public TargetedCombinerParameterMap() {
+	}
+	
+	/**
+	 * Adds a new target object to the identifier map.
+	 * 
+	 * @param targetId the id for the target
+	 * @param target the target
+	 */
+	public void addTarget(T targetId, U target) {
+		this.mapTargetIdToTarget.put(targetId, target);
+	}
+	
+	/**
+	 * Adds a new <code>TargetedCombinerParameter</code> to this <code>TargetedCombinerParameterMap</code>.
+	 * 
+	 * @param targetdCombinerParameter the <code>TargetedCombinerParameter</code> to add
+	 */
+	public void addCombinerParameter(TargetedCombinerParameter<T,U> targetdCombinerParameter) {
+		this.ensureTargetedCombinerParameters();
+		this.targetedCombinerParameters.add(targetdCombinerParameter);
+		this.mapTargetToCombinerParameters	= null;
+	}
+	
+	/**
+	 * Adds the contents of the given <code>Collection</code> of <code>TargetedCombinerParameter</code>s to this <code>TargetedCombinerParameterMap</code>.
+	 * 
+	 * @param listTargetedCombinerParameters the <code>Collection</code> of <code>TargetedCombinerParameter</code>s to add
+	 */
+	public void addCombinerParameters(Collection<TargetedCombinerParameter<T,U>> listTargetedCombinerParameters) {
+		this.ensureTargetedCombinerParameters();
+		this.targetedCombinerParameters.addAll(listTargetedCombinerParameters);
+		this.mapTargetToCombinerParameters	= null;
+	}
+	
+	/**
+	 * Sets the set of <code>TargetedCombinerParameter</code>s for this <code>TargetedCombinerParameterMap</code> to the contents of the
+	 * given <code>Collection</code>>
+	 * 
+	 * @param listTargetedCombinerParameters the <code>Collection</code> of <code>TargetedCombinerParameter</code>s to set
+	 */
+	public void setCombinerParameters(Collection<TargetedCombinerParameter<T,U>> listTargetedCombinerParameters) {
+		this.targetedCombinerParameters	= null;
+		if (listTargetedCombinerParameters != null) {
+			this.addCombinerParameters(targetedCombinerParameters);
+		}
+	}
+	
+	/**
+	 * Looks up the given target in the map for any {@link CombinerParameter}s for the
+	 * given target.
+	 * 
+	 * @param target the target
+	 * @return a <code>List</code> of <code>CombinerParameter</code>s for the target or null if none
+	 * @throws IllegalStateException if there are <code>TargetedCombinerParameter</code>s that cannot be resolved
+	 */
+	public List<CombinerParameter> getCombinerParameters(U target) throws IllegalStateException {
+		this.ensureMap();
+		return (this.mapTargetToCombinerParameters == null ? null : this.mapTargetToCombinerParameters.get(target));
+	}
+	
+	public Iterator<TargetedCombinerParameter<T,U>> getTargetedCombinerParameters() {
+		return (this.targetedCombinerParameters == null ? null : this.targetedCombinerParameters.iterator());
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/VariableDefinition.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/VariableDefinition.java
new file mode 100755
index 0000000..017dd12
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/VariableDefinition.java
@@ -0,0 +1,106 @@
+/*
+ *                        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.policy;
+
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacml.std.StdStatusCode;
+
+/**
+ * VariableDefinition extends {@link PolicyComponent} to represent a XACML VariableDefinition element.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class VariableDefinition extends PolicyComponent {
+	private String id;
+	private Expression expression;
+	
+	public VariableDefinition(StatusCode statusCodeIn, String statusMessageIn) {
+		super(statusCodeIn, statusMessageIn);
+	}
+
+	public VariableDefinition(StatusCode statusCodeIn) {
+		super(statusCodeIn);
+	}
+	
+	public VariableDefinition() {
+		super();
+	}
+
+	/**
+	 * Gets the id of the variable for this <code>VariableDefinition</code>.
+	 * 
+	 * @return the <code>String</code> id for the variable for this <code>VariableDefinition</code>.
+	 */
+	public String getId() {
+		return this.id;
+	}
+	
+	/**
+	 * Sets the id of the variable for this <code>VariableDefinition</code>.
+	 * 
+	 * @param idIn the <code>String</code> id for the variable for this <code>VariableDefinition</code>.
+	 */
+	public void setId(String idIn) {
+		this.id	= idIn;
+	}
+	
+	/**
+	 * Gets the {@link Expression} for this <code>VariableDefinition</code>.
+	 * 
+	 * @return the <code>Expression</code> for this <code>VariableDefinition</code>.
+	 */
+	public Expression getExpression() {
+		return this.expression;
+	}
+	
+	/**
+	 * Sets the <code>Expression</code> for this <code>VariableDefinition</code>.
+	 * 
+	 * @param expressionIn the <code>Expression</code> for this <code>VariableDefinition</code>
+	 */
+	public void setExpression(Expression expressionIn) {
+		this.expression	= expressionIn;
+	}
+	
+	@Override
+	public String toString() {
+		StringBuilder stringBuilder	= new StringBuilder("{");
+		stringBuilder.append("super=");
+		stringBuilder.append(super.toString());
+		
+		Object objectToDump;
+		if ((objectToDump = this.getId()) != null) {
+			stringBuilder.append(",id=");
+			stringBuilder.append((String)objectToDump);
+		}
+		if ((objectToDump = this.getExpression()) != null) {
+			stringBuilder.append(",expression=");
+			stringBuilder.append(objectToDump.toString());
+		}
+		stringBuilder.append('}');
+		return stringBuilder.toString();
+	}
+
+	@Override
+	protected boolean validateComponent() {
+		if (this.getId() == null) {
+			this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing variable id");
+			return false;
+		} else if (this.getExpression() == null) {
+			this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing variable expression");
+			return false;
+		} else {
+			this.setStatus(StdStatusCode.STATUS_CODE_OK, null);
+			return true;
+		}
+	}
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/VariableMap.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/VariableMap.java
new file mode 100755
index 0000000..4d55a9d
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/VariableMap.java
@@ -0,0 +1,116 @@
+/*
+ *                        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.policy;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import com.att.research.xacml.util.StringUtils;
+
+/**
+ * VariableMap is a collection of {@link com.att.research.xacmlatt.pdp.policy.VariableDefinition}s that are accessible by
+ * the variable identifier.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class VariableMap {
+	private List<VariableDefinition>		variableDefinitions;
+	private Map<String, VariableDefinition> mapVariableDefinitions;
+	
+	private void ensureVariableDefinitions() {
+		if (this.variableDefinitions == null) {
+			this.variableDefinitions	= new ArrayList<VariableDefinition>();
+		}
+	}
+	
+	private void ensureMap() {
+		if (this.mapVariableDefinitions == null) {
+			this.mapVariableDefinitions	= new HashMap<String, VariableDefinition>();
+		}
+	}
+	
+	public VariableMap() {
+	}
+
+	/**
+	 * Gets the <code>VariableDefinition</code> with the given <code>String</code> id.
+	 * 
+	 * @param variableId the <code>String</code> identifier of the <code>VariableDefinition</code> to retrieve
+	 * @return the <code>VariableDefinition</code> with the given <code>String</code> id or null if not found.
+	 */
+	public VariableDefinition getVariableDefinition(String variableId) {
+		return (this.mapVariableDefinitions == null ? null : this.mapVariableDefinitions.get(variableId));
+	}
+	
+	/**
+	 * Gets an <code>Iterator</code> over the <code>VariableDefinition</code>s in this <code>VariableMap</code>
+	 * in the order they were added.
+	 * 
+	 * @return an <code>Iterator</code> over the <code>VariableDefinition</code>s in this <code>VariableMap</code>
+	 */
+	public Iterator<VariableDefinition> getVariableDefinitions() {
+		return (this.variableDefinitions == null ? null : this.variableDefinitions.iterator());
+	}
+	
+	/**
+	 * Adds the given <code>VariableDefinition</code> to this <code>VariableMap</code>.
+	 * 
+	 * @param variableDefinition the <code>VariableDefinition</code> to add
+	 */
+	public void add(VariableDefinition variableDefinition) {
+		this.ensureMap();
+		this.ensureVariableDefinitions();
+		this.variableDefinitions.add(variableDefinition);
+		this.mapVariableDefinitions.put(variableDefinition.getId(), variableDefinition);
+	}
+	
+	/**
+	 * Adds the contents of the given <code>Collection</code> of <code>VariableDefinition</code>s to the set of
+	 * <code>VariableDefinition</code>s in this <code>VariableMap</code>>
+	 * 
+	 * @param listVariableDefinitions the <code>Collection</code> of <code>VariableDefinition</code>s to add
+	 */
+	public void addVariableDefinitions(Collection<VariableDefinition> listVariableDefinitions) {
+		for (VariableDefinition variableDefinition: listVariableDefinitions) {
+			this.add(variableDefinition);
+		}
+	}
+	
+	/**
+	 * Sets the <code>VariableDefinition</code>s in this <code>VariableMap</code> to the contents of the given
+	 * <code>Collection</code>.
+	 * 
+	 * @param listVariableDefinitions the <code>Collection</code> of <code>VariableDefinition</code> to set
+	 */
+	public void setVariableDefinitions(Collection<VariableDefinition> listVariableDefinitions) {
+		this.variableDefinitions	= null;
+		this.mapVariableDefinitions	= null;
+		if (listVariableDefinitions != null) {
+			this.addVariableDefinitions(variableDefinitions);
+		}		
+	}
+	
+	@Override
+	public String toString() {
+		StringBuilder stringBuilder	= new StringBuilder("{");
+		if (this.mapVariableDefinitions.size() > 0) {
+			stringBuilder.append("variableDefinitions=");
+			stringBuilder.append(StringUtils.toString(this.mapVariableDefinitions.values().iterator()));
+		}
+		stringBuilder.append('}');
+		return stringBuilder.toString();
+	}
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAdviceExpression.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAdviceExpression.java
new file mode 100755
index 0000000..eda3962
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAdviceExpression.java
@@ -0,0 +1,191 @@
+/*
+ *                        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.policy.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+import com.att.research.xacmlatt.pdp.policy.AdviceExpression;
+import com.att.research.xacmlatt.pdp.policy.Policy;
+import com.att.research.xacmlatt.pdp.policy.RuleEffect;
+
+/**
+ * DOMAdviceExpression extends {@link com.att.research.xacmlatt.pdp.policy.AdviceExpression} with methods for creation
+ * from {@link org.w3c.dom.Node}s.
+ * 
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class DOMAdviceExpression extends AdviceExpression {
+	private static final Log logger	= LogFactory.getLog(DOMAdviceExpression.class);
+	
+	protected DOMAdviceExpression() {
+	}
+
+	/**
+	 * Creates a new <code>AdviceExpression</code> by parsing the given <code>Node</code> representing a XACML AdviceExpression element.
+	 * 
+	 * @param nodeAdviceExpression the <code>Node</code> representing the XACML AdviceExpression element
+	 * @param policy the {@link com.att.research.xacmlatt.pdp.policy.Policy} encompassing the AdviceExpression element
+	 * @return a new <code>AdviceExpression</code> parsed from the given <code>Node</code>
+	 * @throws DOMStructureException if there is an error parsing the <code>Node</code>
+	 */
+	public static AdviceExpression newInstance(Node nodeAdviceExpression, Policy policy) throws DOMStructureException {
+		Element elementAdviceExpression			= DOMUtil.getElement(nodeAdviceExpression);
+		boolean bLenient						= DOMProperties.isLenient();
+		
+		DOMAdviceExpression domAdviceExpression	= new DOMAdviceExpression();
+		
+		try {
+			NodeList children	= elementAdviceExpression.getChildNodes();
+			int numChildren;
+			if (children != null && (numChildren = children.getLength()) > 0) {
+				for (int i = 0 ; i < numChildren ; i++) {
+					Node child	= children.item(i);
+					if (DOMUtil.isElement(child)) {
+						if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ATTRIBUTEASSIGNMENTEXPRESSION.equals(child.getLocalName())) {
+							domAdviceExpression.addAttributeAssignmentExpression(DOMAttributeAssignmentExpression.newInstance(child, policy));
+						} else if (!bLenient) {
+							throw DOMUtil.newUnexpectedElementException(child, nodeAdviceExpression);
+						}
+					}
+				}
+			}
+			
+			domAdviceExpression.setAdviceId(DOMUtil.getIdentifierAttribute(elementAdviceExpression, XACML3.ATTRIBUTE_ADVICEID, !bLenient));
+			
+			String string	= DOMUtil.getStringAttribute(elementAdviceExpression, XACML3.ATTRIBUTE_APPLIESTO, !bLenient);
+			RuleEffect ruleEffect	= RuleEffect.getRuleEffect(string);
+			if (ruleEffect == null && !bLenient) {
+				throw new DOMStructureException(nodeAdviceExpression, "Unknown EffectType \"" + string + "\"");
+			} else {
+				domAdviceExpression.setAppliesTo(ruleEffect);
+			}
+		} catch (DOMStructureException ex) {
+			domAdviceExpression.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+			if (DOMProperties.throwsExceptions()) {
+				throw ex;
+			}
+		}
+		
+		return domAdviceExpression;
+	}
+	
+	public static boolean repair(Node nodeAdviceExpression) throws DOMStructureException {
+		Element elementAdviceExpression	= DOMUtil.getElement(nodeAdviceExpression);
+		boolean result					= false;
+		
+		NodeList children	= elementAdviceExpression.getChildNodes();
+		int numChildren;
+		if (children != null && (numChildren = children.getLength()) > 0) {
+			for (int i = 0 ; i < numChildren ; i++) {
+				Node child	= children.item(i);
+				if (DOMUtil.isElement(child)) {
+					if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ATTRIBUTEASSIGNMENTEXPRESSION.equals(child.getLocalName())) {
+						result			= DOMAttributeAssignmentExpression.repair(child) || result; 
+					} else {
+						logger.warn("Unexpected element " + child.getNodeName());
+						nodeAdviceExpression.removeChild(child);
+						result			= true;
+					}
+				}
+			}
+		}
+		
+		result	= DOMUtil.repairIdentifierAttribute(elementAdviceExpression, XACML3.ATTRIBUTE_ADVICEID, logger) || result;
+		result	= DOMUtil.repairStringAttribute(elementAdviceExpression, XACML3.ATTRIBUTE_APPLIESTO, RuleEffect.DENY.getName(), logger) || result;
+		String stringRuleEffect	= DOMUtil.getStringAttribute(elementAdviceExpression, XACML3.ATTRIBUTE_APPLIESTO);
+		RuleEffect ruleEffect	= RuleEffect.getRuleEffect(stringRuleEffect);
+		if (ruleEffect == null) {
+			logger.warn("Setting invalid RuleEffect " + stringRuleEffect + " to " + RuleEffect.DENY.getName());
+			elementAdviceExpression.setAttribute(XACML3.ATTRIBUTE_APPLIESTO, RuleEffect.DENY.getName());
+			result	= true;
+		}
+		return result;
+	}
+	
+	/**
+	 * Creates a <code>List</code> of <code>AdviceExpression</code>s by parsing the given <code>Node</code> representing a
+	 * XACML AdviceExpressions element.
+	 * 
+	 * @param nodeAdviceExpressions the <code>Node</code> representing the XACML AdviceExpressions element
+	 * @param policy the <code>Policy</code> encompassing the AdviceExpressions element
+	 * @return a new <code>List</code> of <code>AdviceExpression</code>s parsed from the given <code>Node</code>.
+	 * @throws DOMStructureException if there is an error parsing the <code>Node</code>
+	 */
+	public static List<AdviceExpression> newList(Node nodeAdviceExpressions, Policy policy) throws DOMStructureException {
+		Element elementAdviceExpressions	= DOMUtil.getElement(nodeAdviceExpressions);
+		boolean bLenient					= DOMProperties.isLenient();
+		
+		List<AdviceExpression> listAdviceExpressions	= new ArrayList<AdviceExpression>();
+		
+		NodeList children	= elementAdviceExpressions.getChildNodes();
+		int numChildren;
+		if (children != null && (numChildren = children.getLength()) > 0) {
+			for (int i = 0 ; i < numChildren ; i++) {
+				Node child	= children.item(i);
+				if (DOMUtil.isElement(child)) {
+					if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ADVICEEXPRESSION.equals(child.getLocalName())) {
+						listAdviceExpressions.add(DOMAdviceExpression.newInstance(child, policy));
+					} else if (!bLenient) {
+						throw DOMUtil.newUnexpectedElementException(child, nodeAdviceExpressions);
+					}
+				}
+			}
+		}
+		
+		if (listAdviceExpressions.size() == 0 && !bLenient) {
+			throw DOMUtil.newMissingElementException(nodeAdviceExpressions, XACML3.XMLNS, XACML3.ELEMENT_ADVICEEXPRESSION);
+		}		
+		return listAdviceExpressions;
+	}
+	
+	public static boolean repairList(Node nodeAdviceExpressions) throws DOMStructureException {
+		Element elementAdviceExpressions	= DOMUtil.getElement(nodeAdviceExpressions);
+		boolean result						= false;
+		
+		boolean sawAdviceExpression			= false;
+		NodeList children	= elementAdviceExpressions.getChildNodes();
+		int numChildren;
+		if (children != null && (numChildren = children.getLength()) > 0) {
+			for (int i = 0 ; i < numChildren ; i++) {
+				Node child	= children.item(i);
+				if (DOMUtil.isElement(child)) {
+					if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ADVICEEXPRESSION.equals(child.getLocalName())) {
+						sawAdviceExpression	= true;
+						result				= result || DOMAdviceExpression.repair(child);
+					} else {
+						logger.warn("Unexpected element " + child.getNodeName());
+						nodeAdviceExpressions.removeChild(child);
+						result			= true;						
+					}
+				}
+			}
+		}
+		
+		if (!sawAdviceExpression) {
+			throw DOMUtil.newMissingElementException(nodeAdviceExpressions, XACML3.XMLNS, XACML3.ELEMENT_ADVICEEXPRESSION);
+		}
+		
+		return result;
+	}
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAllOf.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAllOf.java
new file mode 100755
index 0000000..c169bc7
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAllOf.java
@@ -0,0 +1,109 @@
+/*
+ *                        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.policy.dom;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+import com.att.research.xacmlatt.pdp.policy.AllOf;
+
+/**
+ * DOMAllOf extends {@link com.att.research.xacmlatt.pdp.policy.AllOf} with methods for creation from
+ * DOM {@link org.w3c.dom.Node}s.
+ * 
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class DOMAllOf extends AllOf {
+	private static final Log logger	= LogFactory.getLog(DOMAllOf.class);
+	
+	protected DOMAllOf() {
+	}
+	
+	/**
+	 * Creates a new <code>DOMAllOf</code> by parsing the given <code>Node</code> representing a XACML AllOf element.
+	 * 
+	 * @param nodeAllOf the <code>Node</code> representing the XACML AllOf element
+	 * @return a new <code>DOMAllOf</code> parsed from the given <code>Node</code>
+	 * @throws DOMStructureException if there is an error parsing the given <code>Node</code>
+	 */
+	public static AllOf newInstance(Node nodeAllOf) throws DOMStructureException {
+		Element elementAllOf	= DOMUtil.getElement(nodeAllOf);
+		boolean bLenient		= DOMProperties.isLenient();
+		
+		DOMAllOf domAllOf		= new DOMAllOf();
+		
+		try {
+			NodeList children	= elementAllOf.getChildNodes();
+			int numChildren;
+			boolean sawMatch	= false;
+			if (children != null && (numChildren = children.getLength()) > 0) {
+				for (int i = 0 ; i < numChildren ; i++) {
+					Node child	= children.item(i);
+					if (DOMUtil.isElement(child)) {
+						if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_MATCH.equals(child.getLocalName())) {
+							domAllOf.addMatch(DOMMatch.newInstance(child));
+							sawMatch	= true;
+						} else if (!bLenient) {
+							throw DOMUtil.newUnexpectedElementException(child, nodeAllOf);
+						}
+					}
+				}
+			}
+			if (!sawMatch && !bLenient) {
+				throw DOMUtil.newMissingElementException(nodeAllOf, XACML3.XMLNS, XACML3.ELEMENT_MATCH);
+			}
+		} catch (DOMStructureException ex) {
+			domAllOf.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+			if (DOMProperties.throwsExceptions()) {
+				throw ex;
+			}
+		}
+		return domAllOf;
+	}
+	
+	public static boolean repair(Node nodeAllOf) throws DOMStructureException {
+		Element elementAllOf	= DOMUtil.getElement(nodeAllOf);
+		boolean result			= false;
+		
+		NodeList children	= elementAllOf.getChildNodes();
+		int numChildren;
+		boolean sawMatch	= false;
+		if (children != null && (numChildren = children.getLength()) > 0) {
+			for (int i = 0 ; i < numChildren ; i++) {
+				Node child	= children.item(i);
+				if (DOMUtil.isElement(child)) {
+					if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_MATCH.equals(child.getLocalName())) {
+						result		= DOMMatch.repair(child) || result;
+						sawMatch	= true;
+					} else {
+						logger.warn("Unexpected element " + child.getNodeName());
+						elementAllOf.removeChild(child);
+						result	= true;
+					}
+				}
+			}
+		}
+		if (!sawMatch) {
+			throw DOMUtil.newMissingElementException(nodeAllOf, XACML3.XMLNS, XACML3.ELEMENT_MATCH);
+		}
+		
+		return result;
+	}
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAnyOf.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAnyOf.java
new file mode 100755
index 0000000..882ce67
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAnyOf.java
@@ -0,0 +1,100 @@
+/*
+ *                        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.policy.dom;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+import com.att.research.xacmlatt.pdp.policy.AnyOf;
+
+/**
+ * DOMAnyOf extends {@link com.att.research.xacmlatt.pdp.policy.AnyOf} with methods for creation
+ * from DOM {@link org.w3c.dom.Node}s.
+ * 
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class DOMAnyOf extends AnyOf {
+	private static final Log logger	= LogFactory.getLog(DOMAnyOf.class);
+	
+	protected DOMAnyOf() {
+	}
+	
+	/**
+	 * Creates a new <code>DOMAnyOf</code> by parsing the given <code>Node</code> representing a XACML AnyOf element.
+	 * 
+	 * @param nodeAnyOf the <code>Node</code> representing the XACML AnyOf element
+	 * @return a new <code>DOMAnyOf</code> parsed from the given <code>Node</code> 
+	 * @throws DOMStructureException if there is an error parsing the given <code>Node</code>.
+	 */
+	public static AnyOf newInstance(Node nodeAnyOf) throws DOMStructureException {
+		Element elementAnyOf	= DOMUtil.getElement(nodeAnyOf);
+		boolean bLenient		= DOMProperties.isLenient();
+		
+		DOMAnyOf domAnyOf		= new DOMAnyOf();
+		
+		try {
+			NodeList children	= elementAnyOf.getChildNodes();
+			int numChildren;
+			if (children != null && (numChildren = children.getLength()) > 0) {
+				for (int i = 0 ; i < numChildren ; i++) {
+					Node child	= children.item(i);
+					if (DOMUtil.isElement(child)) {
+						if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && (XACML3.ELEMENT_ALLOF.equals(child.getLocalName()))) {
+							domAnyOf.addAllOf(DOMAllOf.newInstance(child));
+						} else if (!bLenient) {
+							throw DOMUtil.newUnexpectedElementException(child, nodeAnyOf);
+						}
+					}
+				}
+			}
+		} catch (DOMStructureException ex) {
+			domAnyOf.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+			if (DOMProperties.throwsExceptions()) {
+				throw ex;
+			}
+		}
+		
+		return domAnyOf;
+	}
+	
+	public static boolean repair(Node nodeAnyOf) throws DOMStructureException {
+		Element elementAnyOf	= DOMUtil.getElement(nodeAnyOf);
+		boolean result			= false;
+		
+		NodeList children	= elementAnyOf.getChildNodes();
+		int numChildren;
+		if (children != null && (numChildren = children.getLength()) > 0) {
+			for (int i = 0 ; i < numChildren ; i++) {
+				Node child	= children.item(i);
+				if (DOMUtil.isElement(child)) {
+					if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && (XACML3.ELEMENT_ALLOF.equals(child.getLocalName()))) {
+						result	= DOMAllOf.repair(child) || result;
+					} else {
+						logger.warn("Unexpected element " + child.getNodeName());
+						elementAnyOf.removeChild(child);
+						result	= true;
+					}
+				}
+			}
+		}
+		
+		return result;
+	}
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMApply.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMApply.java
new file mode 100755
index 0000000..1ca3021
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMApply.java
@@ -0,0 +1,111 @@
+/*
+ *                        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.policy.dom;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+import com.att.research.xacmlatt.pdp.policy.Policy;
+import com.att.research.xacmlatt.pdp.policy.expressions.Apply;
+
+/**
+ * DOMApply extends {@link com.att.research.xacmlatt.pdp.policy.expressions.Apply} with methods for creation from
+ * DOM {@link org.w3c.dom.Node}s.
+ * 
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class DOMApply extends Apply {
+	private static final Log logger	= LogFactory.getLog(DOMApply.class);
+	
+	protected DOMApply() {
+	}
+	
+	/**
+	 * Creates a new <code>Apply</code> by parsing the given <code>Node</core> representing a XACML Apply element.
+	 * 
+	 * @param nodeApply the <code>Node</code> representing the XACML Apply element
+	 * @param policy the <code>Policy</code> encompassing the Apply element
+	 * @return a new <code>Apply</code> parsed from the given <code>Node</code>
+	 * @throws DOMStructureException if there is an error parsing the <code>Node</code>
+	 */
+	public static Apply newInstance(Node nodeApply, Policy policy) throws DOMStructureException {
+		Element elementApply	= DOMUtil.getElement(nodeApply);
+		boolean bLenient		= DOMProperties.isLenient();
+		
+		DOMApply domApply		= new DOMApply();
+		
+		try {
+			NodeList children	= nodeApply.getChildNodes();
+			if (children != null) {
+				int numChildren	= children.getLength();
+				for (int i = 0 ; i < numChildren ; i++) {
+					Node child	= children.item(i);
+					if (child.getNodeType() == Node.ELEMENT_NODE && XACML3.XMLNS.equals(child.getNamespaceURI())) {
+						String childName	= child.getLocalName();
+						if (XACML3.ELEMENT_DESCRIPTION.equals(childName)) {
+							domApply.setDescription(child.getTextContent());
+						} else if (DOMExpression.isExpression(child)) {
+							domApply.addArgument(DOMExpression.newInstance(child, policy));
+						} else if (!bLenient) {
+							throw DOMUtil.newUnexpectedElementException(child, nodeApply);
+						}
+					}
+				}
+			}
+			
+			domApply.setFunctionId(DOMUtil.getIdentifierAttribute(elementApply, XACML3.ATTRIBUTE_FUNCTIONID, !bLenient));
+		} catch (DOMStructureException ex) {
+			domApply.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+			if (DOMProperties.throwsExceptions()) {
+				throw ex;
+			}
+		}
+		
+		return domApply;
+	}
+	
+	public static boolean repair(Node nodeApply) throws DOMStructureException {
+		Element elementApply	= DOMUtil.getElement(nodeApply);
+		boolean result			= false;
+		
+		NodeList children	= nodeApply.getChildNodes();
+		if (children != null) {
+			int numChildren	= children.getLength();
+			for (int i = 0 ; i < numChildren ; i++) {
+				Node child	= children.item(i);
+				if (child.getNodeType() == Node.ELEMENT_NODE && XACML3.XMLNS.equals(child.getNamespaceURI())) {
+					String childName	= child.getLocalName();
+					if (XACML3.ELEMENT_DESCRIPTION.equals(childName)) {
+					} else if (DOMExpression.isExpression(child)) {
+						result	= DOMExpression.repair(child) || result;
+					} else {
+						logger.warn("Unexpected element " + child.getNodeName());
+						elementApply.removeChild(child);
+						result	= true;
+					}
+				}
+			}
+		}
+		
+		result					= DOMUtil.repairIdentifierAttribute(elementApply, XACML3.ATTRIBUTE_FUNCTIONID, XACML3.ID_FUNCTION_STRING_EQUAL, logger) || result;
+		
+		return result;
+	}
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeAssignmentExpression.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeAssignmentExpression.java
new file mode 100755
index 0000000..4e42751
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeAssignmentExpression.java
@@ -0,0 +1,116 @@
+/*
+ *                        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.policy.dom;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+import com.att.research.xacmlatt.pdp.policy.AttributeAssignmentExpression;
+import com.att.research.xacmlatt.pdp.policy.Policy;
+
+/**
+ * DOMAttributeAssignmentExpression extends {@link com.att.research.xacmlatt.pdp.policy.AttributeAssignmentExpression} with
+ * methods for creation from {@link org.w3c.dom.Node}s.
+ * 
+ * @author car
+ * @version $Revision: 1.3 $
+ */
+public class DOMAttributeAssignmentExpression extends AttributeAssignmentExpression {
+	private static final Log logger	= LogFactory.getLog(DOMAttributeAssignmentExpression.class);
+	
+	protected DOMAttributeAssignmentExpression() {
+	}
+
+	/**
+	 * Creates a new <code>AttributeAssignmentExpression</code> by parsing the given <code>Node</code> representing
+	 * a XACML AttributeAssignmentExpression element.
+	 * 
+	 * @param nodeAttributeAssignmentExpression the <code>Node</code> representing the XACML AttributeAssignmentExpression element
+	 * @return a new <code>AttributeAssignmentExpression</code> parsed from the given <code>Node</code>
+	 * @throws DOMStructureException if there is an error parsing the <code>Node</code>
+	 */
+	public static AttributeAssignmentExpression newInstance(Node nodeAttributeAssignmentExpression, Policy policy) throws DOMStructureException {
+		Element elementAttributeAssignmentExpression	= DOMUtil.getElement(nodeAttributeAssignmentExpression);
+		boolean bLenient								= DOMProperties.isLenient();
+		
+		DOMAttributeAssignmentExpression domAttributeAssignmentExpression	= new DOMAttributeAssignmentExpression();
+		
+		try {
+			Node node	= DOMUtil.getFirstChildElement(elementAttributeAssignmentExpression);
+			if (node == null) {
+				if (!bLenient) {
+					throw DOMUtil.newMissingElementException(elementAttributeAssignmentExpression, XACML3.XMLNS, XACML3.ELEMENT_EXPRESSION);
+				}
+			} else {
+				domAttributeAssignmentExpression.setExpression(DOMExpression.newInstance(node, policy));				
+			}
+			
+			Identifier identifier;
+			domAttributeAssignmentExpression.setAttributeId(DOMUtil.getIdentifierAttribute(elementAttributeAssignmentExpression, XACML3.ATTRIBUTE_ATTRIBUTEID, !bLenient));;
+			if ((identifier = DOMUtil.getIdentifierAttribute(elementAttributeAssignmentExpression, XACML3.ATTRIBUTE_CATEGORY)) != null) {
+				domAttributeAssignmentExpression.setCategory(identifier);
+			}
+			
+			String issuer	= DOMUtil.getStringAttribute(elementAttributeAssignmentExpression, XACML3.ATTRIBUTE_ISSUER);
+			if (issuer != null) {
+				domAttributeAssignmentExpression.setIssuer(issuer);
+			}
+		} catch (DOMStructureException ex) {
+			domAttributeAssignmentExpression.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+			if (DOMProperties.throwsExceptions()) {
+				throw ex;
+			}
+		}
+		
+		return domAttributeAssignmentExpression;
+	}
+	
+	public static boolean repair(Node nodeAttributeAssignmentExpression) throws DOMStructureException {
+		Element elementAttributeAssignmentExpression	= DOMUtil.getElement(nodeAttributeAssignmentExpression);
+		boolean result									= false;
+		
+		if (DOMUtil.getFirstChildElement(elementAttributeAssignmentExpression) == null) {
+			/*
+			 * See if we can repair the <AttributeAssignmentExpression DataType="">string</AttributeAssignmentExpression> pattern
+			 */
+			Identifier identifier	= DOMUtil.getIdentifierAttribute(elementAttributeAssignmentExpression, XACML3.ATTRIBUTE_DATATYPE);
+			String textContent	= elementAttributeAssignmentExpression.getTextContent();
+			if (textContent != null) {
+				textContent	= textContent.trim();
+			}
+			if (textContent != null && textContent.length() > 0 && identifier != null) {
+				Element attributeValue	= elementAttributeAssignmentExpression.getOwnerDocument().createElementNS(XACML3.XMLNS, XACML3.ELEMENT_ATTRIBUTEVALUE);
+				attributeValue.setAttribute(XACML3.ATTRIBUTE_DATATYPE, identifier.stringValue());
+				attributeValue.setTextContent(textContent);
+				logger.warn("Adding a new AttributeValue using the DataType from the AttributeAssignment");
+				elementAttributeAssignmentExpression.removeAttribute(XACML3.ATTRIBUTE_DATATYPE);
+				while (elementAttributeAssignmentExpression.hasChildNodes()) {
+					elementAttributeAssignmentExpression.removeChild(elementAttributeAssignmentExpression.getFirstChild());
+				}
+				elementAttributeAssignmentExpression.appendChild(attributeValue);
+				result	= true;
+			} else {
+				throw DOMUtil.newMissingElementException(elementAttributeAssignmentExpression, XACML3.XMLNS, XACML3.ELEMENT_EXPRESSION);
+			}
+		}
+		result	= DOMUtil.repairIdentifierAttribute(elementAttributeAssignmentExpression, XACML3.ATTRIBUTE_ATTRIBUTEID, logger) || result;
+		
+		return result;
+	}
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeDesignator.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeDesignator.java
new file mode 100755
index 0000000..1d5936f
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeDesignator.java
@@ -0,0 +1,87 @@
+/*
+ *                        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.policy.dom;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+import com.att.research.xacmlatt.pdp.policy.expressions.AttributeDesignator;
+
+/**
+ * DOMAttributeDesignator extends {@link com.att.research.xacmlatt.pdp.policy.expressions.AttributeDesignator} with methods
+ * for creation from DOM {@link org.w3c.dom.Node}s.
+ * 
+ * @author car
+ * @version $Revision: 1.3 $
+ */
+public class DOMAttributeDesignator extends AttributeDesignator {
+	private static final Log logger	= LogFactory.getLog(DOMAttributeDesignator.class);
+	
+	protected DOMAttributeDesignator() {
+	}
+	
+	/**
+	 * Creates a new <code>DOMAttributeDesignator</code> by parsing the given <code>Node</code> representing a XACML AttributeDesignator
+	 * element.
+	 * 
+	 * @param nodeAttributeDesignator the <code>Node</code> representing the XACML AttributeDesignator element
+	 * @return a new <code>DOMAttributeDesignator</code> parsed from the given <code>Node</code>
+	 * @throws DOMStructureException if there is an error parsing the <code>Node</code>
+	 */
+	public static AttributeDesignator newInstance(Node nodeAttributeDesignator) throws DOMStructureException {
+		Element elementAttributeDesignator				= DOMUtil.getElement(nodeAttributeDesignator);
+		boolean bLenient								= DOMProperties.isLenient();
+		
+		DOMAttributeDesignator domAttributeDesignator	= new DOMAttributeDesignator();
+		
+		try {
+			domAttributeDesignator.setCategory(DOMUtil.getIdentifierAttribute(elementAttributeDesignator, XACML3.ATTRIBUTE_CATEGORY, !bLenient));
+			domAttributeDesignator.setAttributeId(DOMUtil.getIdentifierAttribute(elementAttributeDesignator, XACML3.ATTRIBUTE_ATTRIBUTEID, !bLenient));
+			domAttributeDesignator.setDataTypeId(DOMUtil.getIdentifierAttribute(elementAttributeDesignator, XACML3.ATTRIBUTE_DATATYPE, !bLenient));
+			
+			String string;			
+			if ((string = DOMUtil.getStringAttribute(elementAttributeDesignator, XACML3.ATTRIBUTE_ISSUER)) != null) {
+				domAttributeDesignator.setIssuer(string);
+			}
+			Boolean mustBePresent	= DOMUtil.getBooleanAttribute(elementAttributeDesignator, XACML3.ATTRIBUTE_MUSTBEPRESENT, !bLenient);
+			if (mustBePresent != null) {
+				domAttributeDesignator.setMustBePresent(mustBePresent);
+			}
+		} catch (DOMStructureException ex) {
+			domAttributeDesignator.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+			if (DOMProperties.throwsExceptions()) {
+				throw ex;
+			}
+		}
+		
+		return domAttributeDesignator;
+	}
+	
+	public static boolean repair(Node nodeAttributeDesignator) throws DOMStructureException {
+		Element elementAttributeDesignator	= DOMUtil.getElement(nodeAttributeDesignator);
+		boolean result						= false;
+		
+		result								= DOMUtil.repairIdentifierAttribute(elementAttributeDesignator, XACML3.ATTRIBUTE_CATEGORY, logger) || result;
+		result								= DOMUtil.repairIdentifierAttribute(elementAttributeDesignator, XACML3.ATTRIBUTE_ATTRIBUTEID, logger) || result;
+		result								= DOMUtil.repairIdentifierAttribute(elementAttributeDesignator, XACML3.ATTRIBUTE_DATATYPE, logger) || result;
+		result								= DOMUtil.repairBooleanAttribute(elementAttributeDesignator, XACML3.ATTRIBUTE_MUSTBEPRESENT, false, logger) || result;
+		
+		return result;
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeSelector.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeSelector.java
new file mode 100755
index 0000000..da1359b
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeSelector.java
@@ -0,0 +1,87 @@
+/*
+ *                        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.policy.dom;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+import com.att.research.xacmlatt.pdp.policy.expressions.AttributeSelector;
+
+/**
+ * DOMAttributeSelector extends {@link com.att.research.xacmlatt.pdp.policy.expressions.AttributeSelector} with methods
+ * for creation from DOM {@link org.w3c.dom.Node}s.
+ * 
+ * @author car
+ * @version $Revision: 1.3 $
+ */
+public class DOMAttributeSelector extends AttributeSelector {
+	private static Log logger	= LogFactory.getLog(DOMAttributeSelector.class);
+	
+	protected DOMAttributeSelector() {
+	}
+
+	/**
+	 * Creates a new <code>DOMAttributeSelector</code> by parsing the given <code>Node</code> representing a XACML AttributeSelector element.
+	 * 
+	 * @param nodeAttributeSelector the <code>Node</code> representing the XACML AttributeSelector element
+	 * @return a new <code>DOMAttributeSelector</code> parsed from the given <code>Node</code>.
+	 * @throws DOMStructureException if there is an error parsing the <code>Node</code>
+	 */
+	public static AttributeSelector newInstance(Node nodeAttributeSelector) throws DOMStructureException {
+		Element elementAttributeSelector			= DOMUtil.getElement(nodeAttributeSelector);
+		boolean bLenient							= DOMProperties.isLenient();
+		
+		DOMAttributeSelector domAttributeSelector	= new DOMAttributeSelector();
+		
+		try {
+			domAttributeSelector.setCategory(DOMUtil.getIdentifierAttribute(elementAttributeSelector, XACML3.ATTRIBUTE_CATEGORY, !bLenient));
+			
+			Identifier identifier;			
+			if ((identifier = DOMUtil.getIdentifierAttribute(elementAttributeSelector, XACML3.ATTRIBUTE_CONTEXTSELECTORID)) != null) {
+				domAttributeSelector.setContextSelectorId(identifier);
+			}
+			
+			domAttributeSelector.setPath(DOMUtil.getStringAttribute(elementAttributeSelector, XACML3.ATTRIBUTE_PATH, !bLenient));
+			domAttributeSelector.setDataTypeId(DOMUtil.getIdentifierAttribute(elementAttributeSelector, XACML3.ATTRIBUTE_DATATYPE, !bLenient));
+			Boolean mustBePresent	= DOMUtil.getBooleanAttribute(elementAttributeSelector, XACML3.ATTRIBUTE_MUSTBEPRESENT, !bLenient);
+			if (mustBePresent != null) {
+				domAttributeSelector.setMustBePresent(mustBePresent);
+			}
+		} catch (DOMStructureException ex) {
+			domAttributeSelector.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+			if (DOMProperties.throwsExceptions()) {
+				throw ex;
+			}
+		}
+		
+		return domAttributeSelector;
+	}
+	
+	public static boolean repair(Node nodeAttributeSelector) throws DOMStructureException {
+		Element elementAttributeSelector	= DOMUtil.getElement(nodeAttributeSelector);
+		boolean result						= false;
+		
+		result								= DOMUtil.repairIdentifierAttribute(elementAttributeSelector, XACML3.ATTRIBUTE_CATEGORY, logger) || result;
+		result								= DOMUtil.repairStringAttribute(elementAttributeSelector, XACML3.ATTRIBUTE_PATH, "/", logger) || result;
+		result								= DOMUtil.repairIdentifierAttribute(elementAttributeSelector, XACML3.ATTRIBUTE_DATATYPE, logger) || result;
+		result								= DOMUtil.repairBooleanAttribute(elementAttributeSelector, XACML3.ATTRIBUTE_MUSTBEPRESENT, false, logger) || result;
+		
+		return result;
+	}
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMCombinerParameter.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMCombinerParameter.java
new file mode 100755
index 0000000..b32a4c7
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMCombinerParameter.java
@@ -0,0 +1,183 @@
+/*
+ *                        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.policy.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.dom.DOMAttributeValue;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+import com.att.research.xacmlatt.pdp.policy.CombinerParameter;
+
+/**
+ * DOMCombinerParameter extends {@link com.att.research.xacmlatt.pdp.policy.CombinerParameter} with methods for
+ * creation from DOM {@link org.w3c.dom.Node}s.
+ * 
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class DOMCombinerParameter extends CombinerParameter {
+	private static final Log logger	= LogFactory.getLog(DOMCombinerParameter.class);
+	
+	protected DOMCombinerParameter() {
+		
+	}
+	
+	/**
+	 * Creates a new <code>CombinerParameter</code> by parsing the given <code>Node</code> representing a XACML CombinerParameter element.
+	 * 
+	 * @param nodeCombinerParameter the <code>Node</code> representing the XACML CombinerParameter element
+	 * @return a new <code>CombinerParameter</code> parsed from the given <code>Node</code>
+	 * @throws DOMStructureException if there is an error parsing the <code>Node</code>
+	 */
+	public static CombinerParameter newInstance(Node nodeCombinerParameter) throws DOMStructureException {
+		Element elementCombinerParameter		= DOMUtil.getElement(nodeCombinerParameter);
+		boolean bLenient						= DOMProperties.isLenient();
+		
+		DOMCombinerParameter combinerParameter	= new DOMCombinerParameter();
+		
+		try {
+			NodeList children					= elementCombinerParameter.getChildNodes();
+			int numChildren;
+			if (children != null && (numChildren = children.getLength()) > 0) {
+				for (int i = 0 ; i < numChildren ; i++) {
+					Node child	= children.item(i);
+					if (DOMUtil.isElement(child)) {
+						if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ATTRIBUTEVALUE.equals(child.getLocalName())) {
+							if (combinerParameter.getAttributeValue() != null && !bLenient) {
+								throw DOMUtil.newUnexpectedElementException(child, elementCombinerParameter);
+							} else {
+								combinerParameter.setAttributeValue(DOMAttributeValue.newInstance(child, null));
+							}
+						} else if (!bLenient) {
+							throw DOMUtil.newUnexpectedElementException(child, elementCombinerParameter);
+						}
+					}
+				}
+			}
+			
+			if (combinerParameter.getAttributeValue() == null && !bLenient) {
+				throw DOMUtil.newMissingElementException(elementCombinerParameter, XACML3.XMLNS, XACML3.ELEMENT_ATTRIBUTEVALUE);
+			}			
+			combinerParameter.setName(DOMUtil.getStringAttribute(elementCombinerParameter, XACML3.ATTRIBUTE_PARAMETERNAME, !bLenient));
+		} catch (DOMStructureException ex) {
+			combinerParameter.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+			if (DOMProperties.throwsExceptions()) {
+				throw ex;
+			}
+		}
+		
+		return combinerParameter;
+	}
+	
+	public static boolean repair(Node nodeCombinerParameter) throws DOMStructureException {
+		Element elementCombinerParameter	= DOMUtil.getElement(nodeCombinerParameter);
+		boolean result						= false;
+		
+		NodeList children					= elementCombinerParameter.getChildNodes();
+		int numChildren;
+		boolean sawAttributeValue			= false;
+		
+		if (children != null && (numChildren = children.getLength()) > 0) {
+			for (int i = 0 ; i < numChildren ; i++) {
+				Node child	= children.item(i);
+				if (DOMUtil.isElement(child)) {
+					if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ATTRIBUTEVALUE.equals(child.getLocalName())) {
+						if (sawAttributeValue) {
+							logger.warn("Unexpected element " + child.getNodeName());
+							elementCombinerParameter.removeChild(child);
+							result	= true;
+						} else {
+							result				= DOMAttributeValue.repair(child) || result;
+							sawAttributeValue	= true;
+						}
+					} else {
+						logger.warn("Unexpected element " + child.getNodeName());
+						elementCombinerParameter.removeChild(child);
+						result	= true;
+					}
+				}
+			}
+		}
+		
+		if (!sawAttributeValue) {
+			throw DOMUtil.newMissingElementException(elementCombinerParameter, XACML3.XMLNS, XACML3.ELEMENT_ATTRIBUTEVALUE);
+		}
+		
+		result	= DOMUtil.repairStringAttribute(elementCombinerParameter, XACML3.ATTRIBUTE_PARAMETERNAME, "parameter", logger) || result;
+		
+		return result;
+	}
+	
+	/**
+	 * Creates a <code>List</code> of <code>CombinerParameter</code>s by parsing the given <code>Node</code> representing a
+	 * XACML CombinerParameters element.
+	 * 
+	 * @param nodeCombinerParameters the <code>Node</code> representing the XACML CombinerParameters element
+	 * @return a <code>List</code> of <code>CombinerParameter</code>s parsed from the given <code>Node</code>.
+	 * @throws DOMStructureException if there is an error parsing the <code>Node</code>
+	 */
+	public static List<CombinerParameter> newList(Node nodeCombinerParameters) throws DOMStructureException {
+		Element elementCombinerParameters	= DOMUtil.getElement(nodeCombinerParameters);
+		boolean bLenient					= DOMProperties.isLenient();
+		
+		List<CombinerParameter> listCombinerParameters	= new ArrayList<CombinerParameter>();
+		
+		NodeList children	= elementCombinerParameters.getChildNodes();
+		int numChildren;
+		if (children != null && (numChildren = children.getLength()) > 0) {
+			for (int i = 0 ; i < numChildren ; i++) {
+				Node child	= children.item(i);
+				if (DOMUtil.isElement(child)) {
+					if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_COMBINERPARAMETER.equals(child.getLocalName())) {
+						listCombinerParameters.add(DOMCombinerParameter.newInstance(child));
+					} else if (!bLenient) {
+						throw DOMUtil.newUnexpectedElementException(child, elementCombinerParameters);
+					}
+				}
+			}
+		}
+		return listCombinerParameters;
+	}
+	
+	public static boolean repairList(Node nodeCombinerParameters) throws DOMStructureException {
+		Element elementCombinerParameters	= DOMUtil.getElement(nodeCombinerParameters);
+		boolean result						= false;
+		
+		NodeList children	= elementCombinerParameters.getChildNodes();
+		int numChildren;
+		if (children != null && (numChildren = children.getLength()) > 0) {
+			for (int i = 0 ; i < numChildren ; i++) {
+				Node child	= children.item(i);
+				if (DOMUtil.isElement(child)) {
+					if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_COMBINERPARAMETER.equals(child.getLocalName())) {
+						result	= DOMCombinerParameter.repair(child) || result;
+					} else {
+						logger.warn("Unexpected element " + child.getNodeName());
+						elementCombinerParameters.removeChild(child);
+						result	= true;
+					}
+				}
+			}
+		}
+		return result;
+	}
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMDocumentRepair.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMDocumentRepair.java
new file mode 100755
index 0000000..f25e6cd
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMDocumentRepair.java
@@ -0,0 +1,70 @@
+/*
+ *                        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.policy.dom;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+
+/**
+ * DOMDocumentRepair extends {@link com.att.research.xacml.std.dom.DOMDocumentRepair} to repair Policy documents as well as
+ * Request and Response documents.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class DOMDocumentRepair extends com.att.research.xacml.std.dom.DOMDocumentRepair {
+	protected boolean repairPolicy(Node nodePolicy) throws DOMStructureException {
+		return DOMPolicy.repair(nodePolicy);
+	}
+	
+	protected boolean repairPolicySet(Node nodePolicySet) throws DOMStructureException {
+		return DOMPolicySet.repair(nodePolicySet);
+	}
+	
+	public DOMDocumentRepair() {
+	}
+
+	/**
+	 * Determines what kind of XACML document is represented by the given <code>Document</code> and
+	 * attempts to repair it.
+	 * 
+	 * @param document the <code>Document</code> to check
+	 * @return true if any repairs were made in the <code>Document</code>, else false
+	 * @throws DOMStructureException if there were unrecoverable errors found
+	 * @throws UnsupportedDocumentTypeException if the root element is not a XACML Request or Response.
+	 */
+	public boolean repair(Document document) throws DOMStructureException, UnsupportedDocumentTypeException {
+		Node firstChild	= DOMUtil.getFirstChildElement(document);
+		if (firstChild == null || !DOMUtil.isElement(firstChild)) {
+			return false;
+		}
+		
+		if (!DOMUtil.isInNamespace(firstChild, XACML3.XMLNS)) {
+			throw new UnsupportedDocumentTypeException("Not a XACML document: " + DOMUtil.getNodeLabel(firstChild));
+		}
+		if (XACML3.ELEMENT_REQUEST.equals(firstChild.getLocalName())) {
+			return this.repairRequest(firstChild);
+		} else if (XACML3.ELEMENT_RESPONSE.equals(firstChild.getLocalName())) {
+			return this.repairResponse(firstChild);
+		} else if (XACML3.ELEMENT_POLICY.equals(firstChild.getLocalName())) {
+			return this.repairPolicy(firstChild);
+		} else if (XACML3.ELEMENT_POLICYSET.equals(firstChild.getLocalName())) {
+			return this.repairPolicySet(firstChild);
+		} else {
+			throw new UnsupportedDocumentTypeException("Not a XACML Request or Response: " + DOMUtil.getNodeLabel(firstChild));
+		}
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMExpression.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMExpression.java
new file mode 100755
index 0000000..b9b1ac7
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMExpression.java
@@ -0,0 +1,120 @@
+/*
+ *                        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.policy.dom;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import com.att.research.xacml.api.AttributeValue;
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.dom.DOMAttributeValue;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+import com.att.research.xacmlatt.pdp.policy.Expression;
+import com.att.research.xacmlatt.pdp.policy.Policy;
+import com.att.research.xacmlatt.pdp.policy.expressions.AttributeValueExpression;
+import com.att.research.xacmlatt.pdp.policy.expressions.Function;
+import com.att.research.xacmlatt.pdp.policy.expressions.VariableReference;
+
+/**
+ * DOMExpression extends {@link com.att.research.xacmlatt.pdp.policy.Expression} with methods for creation
+ * from DOM {@link org.w3c.dom.Node}s.
+ * 
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public abstract class DOMExpression extends Expression {
+	private static final Log logger	= LogFactory.getLog(DOMExpression.class);
+	
+	protected DOMExpression() {
+	}
+	
+	public static boolean isExpression(Node nodeExpression) {
+		String nodeName	= nodeExpression.getLocalName();
+		return (XACML3.ELEMENT_APPLY.equals(nodeName) ||
+				XACML3.ELEMENT_ATTRIBUTEDESIGNATOR.equals(nodeName) ||
+				XACML3.ELEMENT_ATTRIBUTESELECTOR.equals(nodeName) ||
+				XACML3.ELEMENT_ATTRIBUTEVALUE.equals(nodeName) ||
+				XACML3.ELEMENT_FUNCTION.equals(nodeName) ||
+				XACML3.ELEMENT_VARIABLEREFERENCE.equals(nodeName)
+				);
+	}
+	
+	/**
+	 * Creates a new <code>Expression</code> of the appropriate sub-type based on the name of the given <code>Node</code>.
+	 * 
+	 * @param nodeExpression the <code>Node</code> to parse
+	 * @param policy the {@link com.att.research.xacmlatt.pdp.policy.Policy} containing the Expression element
+	 * @return a new <code>Expression</code> parsed from the given <code>Node</code>
+	 * @throws DOMStructureException if there is an error parsing the <code>Node</code>
+	 */
+	public static Expression newInstance(Node nodeExpression, Policy policy) throws DOMStructureException {
+		Element elementExpression	= DOMUtil.getElement(nodeExpression);
+		boolean bLenient			= DOMProperties.isLenient();
+	
+		if (DOMUtil.isInNamespace(elementExpression, XACML3.XMLNS)) {
+			if (elementExpression.getLocalName().equals(XACML3.ELEMENT_APPLY)) {
+				return DOMApply.newInstance(elementExpression, policy);
+			} else if (elementExpression.getLocalName().equals(XACML3.ELEMENT_ATTRIBUTEDESIGNATOR)) {
+				return DOMAttributeDesignator.newInstance(elementExpression);
+			} else if (elementExpression.getLocalName().equals(XACML3.ELEMENT_ATTRIBUTESELECTOR)) {
+				return DOMAttributeSelector.newInstance(elementExpression);
+			} else if (elementExpression.getLocalName().equals(XACML3.ELEMENT_ATTRIBUTEVALUE)) {
+				AttributeValue<?> attributeValue	= null;
+				try {
+					attributeValue	= DOMAttributeValue.newInstance(elementExpression, null);
+				} catch (DOMStructureException ex) {
+					return new AttributeValueExpression(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+				}
+				return new AttributeValueExpression(attributeValue);
+			} else if (elementExpression.getLocalName().equals(XACML3.ELEMENT_FUNCTION)) {
+				return new Function(DOMUtil.getIdentifierAttribute(elementExpression, XACML3.ATTRIBUTE_FUNCTIONID));
+			} else if (elementExpression.getLocalName().equals(XACML3.ELEMENT_VARIABLEREFERENCE)) {
+				return new VariableReference(policy, DOMUtil.getStringAttribute(elementExpression, XACML3.ATTRIBUTE_VARIABLEID));
+			} else if (!bLenient) {
+				throw DOMUtil.newUnexpectedElementException(nodeExpression);
+			} else {
+				return null;
+			}
+		} else if (!bLenient) {
+			throw DOMUtil.newUnexpectedElementException(nodeExpression);
+		} else {
+			return null;
+		}
+	}
+	
+	public static boolean repair(Node nodeExpression) throws DOMStructureException {
+		Element elementExpression	= DOMUtil.getElement(nodeExpression);
+		if (DOMUtil.isInNamespace(elementExpression, XACML3.XMLNS)) {
+			if (elementExpression.getLocalName().equals(XACML3.ELEMENT_APPLY)) {
+				return DOMApply.repair(elementExpression);
+			} else if (elementExpression.getLocalName().equals(XACML3.ELEMENT_ATTRIBUTEDESIGNATOR)) {
+				return DOMAttributeDesignator.repair(elementExpression);
+			} else if (elementExpression.getLocalName().equals(XACML3.ELEMENT_ATTRIBUTESELECTOR)) {
+				return DOMAttributeSelector.repair(elementExpression);
+			} else if (elementExpression.getLocalName().equals(XACML3.ELEMENT_ATTRIBUTEVALUE)) {
+				return DOMAttributeValue.repair(elementExpression);
+			} else if (elementExpression.getLocalName().equals(XACML3.ELEMENT_FUNCTION)) {
+				return DOMUtil.repairIdentifierAttribute(elementExpression, XACML3.ATTRIBUTE_FUNCTIONID, XACML3.ID_FUNCTION_STRING_EQUAL, logger);
+			} else if (elementExpression.getLocalName().equals(XACML3.ELEMENT_VARIABLEREFERENCE)) {
+				return DOMUtil.repairStringAttribute(elementExpression, XACML3.ATTRIBUTE_VARIABLEID, "variableId", logger);
+			} else {
+				throw DOMUtil.newUnexpectedElementException(nodeExpression);
+			}
+		} else {
+			throw DOMUtil.newUnexpectedElementException(nodeExpression);
+		}
+	}
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMMatch.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMMatch.java
new file mode 100755
index 0000000..756750a
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMMatch.java
@@ -0,0 +1,173 @@
+/*
+ *                        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.policy.dom;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.dom.DOMAttributeValue;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+import com.att.research.xacmlatt.pdp.policy.Match;
+
+/**
+ * DOMMatch extends {@link com.att.research.xacmlatt.pdp.policy.Match} with methods for creation from
+ * DOM {@link org.w3c.dom.Node}s.
+ * 
+ * @author car
+ * @version $Revision: 1.3 $
+ */
+public class DOMMatch extends Match {
+	private static Log logger	= LogFactory.getLog(DOMMatch.class);
+	
+	protected DOMMatch() {
+	}
+	
+	/**
+	 * Creates a new <code>DOMMatch</code> by parsing the given <code>Node</code> representing a XACML Match element.
+	 * 
+	 * @param nodeMatch the <code>Node</code> representing the XACML Match element
+	 * @return a new <code>DOMMatch</code> parsed from the given <code>Node</code>
+	 * @throws DOMStructureException if there is an error parsing the given <code>Node</code>
+	 */
+	public static Match newInstance(Node nodeMatch) throws DOMStructureException {
+		Element elementMatch	= DOMUtil.getElement(nodeMatch);
+		boolean bLenient		= DOMProperties.isLenient();
+		
+		DOMMatch domMatch		= new DOMMatch();
+		
+		try {
+			NodeList children	= elementMatch.getChildNodes();
+			int numChildren;
+			
+			if (children != null && (numChildren = children.getLength()) > 0) {
+				for (int i = 0 ; i < numChildren ; i++) {
+					Node child	= children.item(i);
+					if (DOMUtil.isElement(child)) {
+						if (DOMUtil.isInNamespace(child, XACML3.XMLNS)) {
+							String childName	= child.getLocalName();
+							if (XACML3.ELEMENT_ATTRIBUTEVALUE.equals(childName)) {
+								domMatch.setAttributeValue(DOMAttributeValue.newInstance(child, null));
+							} else if (XACML3.ELEMENT_ATTRIBUTEDESIGNATOR.equals(childName)) {
+								if (domMatch.getAttributeRetrievalBase() != null && !bLenient) {
+									throw DOMUtil.newUnexpectedElementException(child, nodeMatch);
+								}
+								domMatch.setAttributeRetrievalBase(DOMAttributeDesignator.newInstance(child));
+							} else if (XACML3.ELEMENT_ATTRIBUTESELECTOR.equals(childName)) {
+								if (domMatch.getAttributeRetrievalBase() != null) {
+									throw DOMUtil.newUnexpectedElementException(child, nodeMatch);
+								}
+								domMatch.setAttributeRetrievalBase(DOMAttributeSelector.newInstance(child));
+							} else if (!bLenient) {
+								throw DOMUtil.newUnexpectedElementException(child, nodeMatch);
+							}
+						} else if (!bLenient) {
+							throw DOMUtil.newUnexpectedElementException(child, nodeMatch);
+						}
+					}
+				}
+			}
+			
+			/*
+			 * We have to see exactly one of these
+			 */
+			if (domMatch.getAttributeRetrievalBase() == null && !bLenient) {
+				throw DOMUtil.newMissingElementException(nodeMatch, XACML3.XMLNS, XACML3.ELEMENT_ATTRIBUTEDESIGNATOR + " or " + XACML3.ELEMENT_ATTRIBUTESELECTOR);
+			} else if (domMatch.getAttributeValue() == null && !bLenient) {
+				throw DOMUtil.newMissingElementException(nodeMatch, XACML3.XMLNS, XACML3.ELEMENT_ATTRIBUTEVALUE);
+			}
+			
+			domMatch.setMatchId(DOMUtil.getIdentifierAttribute(elementMatch, XACML3.ATTRIBUTE_MATCHID, !bLenient));
+			
+		} catch (DOMStructureException ex) {
+			domMatch.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+			if (DOMProperties.throwsExceptions()) {
+				throw ex;
+			}
+		}
+		return domMatch;
+	}
+	
+	public static boolean repair(Node nodeMatch) throws DOMStructureException {
+		Element elementMatch	= DOMUtil.getElement(nodeMatch);
+		boolean result			= false;
+		
+		NodeList children	= elementMatch.getChildNodes();
+		int numChildren;
+		boolean sawAttributeRetrievalBase	= false;
+		boolean sawAttributeValue			= false;
+		
+		if (children != null && (numChildren = children.getLength()) > 0) {
+			for (int i = 0 ; i < numChildren ; i++) {
+				Node child	= children.item(i);
+				if (DOMUtil.isElement(child)) {
+					if (DOMUtil.isInNamespace(child, XACML3.XMLNS)) {
+						String childName	= child.getLocalName();
+						if (XACML3.ELEMENT_ATTRIBUTEVALUE.equals(childName)) {
+							if (sawAttributeValue) {
+								logger.warn("Unexpected element " + child.getNodeName());
+								elementMatch.removeChild(child);
+								result	= true;
+							} else {
+								result				= DOMAttributeValue.repair(child) || result;
+								sawAttributeValue	= true;
+							}
+						} else if (XACML3.ELEMENT_ATTRIBUTEDESIGNATOR.equals(childName)) {
+							if (sawAttributeRetrievalBase) {
+								logger.warn("Unexpected element " + child.getNodeName());
+								elementMatch.removeChild(child);
+								result	= true;
+							} else {
+								result						= DOMAttributeDesignator.repair(child) || result;
+								sawAttributeRetrievalBase	= true;
+							}
+						} else if (XACML3.ELEMENT_ATTRIBUTESELECTOR.equals(childName)) {
+							if (sawAttributeRetrievalBase) {
+								logger.warn("Unexpected element " + child.getNodeName());
+								elementMatch.removeChild(child);
+								result	= true;
+							} else {
+								result	= DOMAttributeSelector.repair(child) || result;
+								sawAttributeRetrievalBase	= true;
+							}
+						} else {
+							logger.warn("Unexpected element " + child.getNodeName());
+							elementMatch.removeChild(child);
+							result	= true;
+						}
+					} else {
+						logger.warn("Unexpected element " + child.getNodeName());
+						elementMatch.removeChild(child);
+						result	= true;
+					}
+				}
+			}
+		}
+		
+		/*
+		 * We have to see exactly one of these
+		 */
+		if (!sawAttributeRetrievalBase) {
+			throw DOMUtil.newMissingElementException(nodeMatch, XACML3.XMLNS, XACML3.ELEMENT_ATTRIBUTEDESIGNATOR + " or " + XACML3.ELEMENT_ATTRIBUTESELECTOR);
+		} else if (!sawAttributeValue) {
+			throw DOMUtil.newMissingElementException(nodeMatch, XACML3.XMLNS, XACML3.ELEMENT_ATTRIBUTEVALUE);
+		}
+		result	= DOMUtil.repairIdentifierAttribute(elementMatch, XACML3.ATTRIBUTE_MATCHID, logger) || result;
+		
+		return result;
+	}
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMObligationExpression.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMObligationExpression.java
new file mode 100755
index 0000000..7f5832c
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMObligationExpression.java
@@ -0,0 +1,195 @@
+/*
+ *                        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.policy.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+import com.att.research.xacmlatt.pdp.policy.ObligationExpression;
+import com.att.research.xacmlatt.pdp.policy.Policy;
+import com.att.research.xacmlatt.pdp.policy.RuleEffect;
+
+/**
+ * DOMObligationExpression extends {@link com.att.research.xacmlatt.pdp.policy.ObligationExpression} with methods
+ * for creation from {@link org.w3c.dom.Node}s.
+ * 
+ * @author car
+ * @version $Revision: 1.3 $
+ */
+public class DOMObligationExpression extends ObligationExpression {
+	private static final Log logger	= LogFactory.getLog(DOMObligationExpression.class);
+	
+	protected DOMObligationExpression() {
+	}
+	
+	/**
+	 * Creates a new <code>ObligationExpression</code> by parsing the given <code>Node</code> representing a XACML ObligationExpression element.
+	 * 
+	 * @param nodeObligationExpression the <code>Node</code> representing the XACML ObligationExpression element
+	 * @param policy the {@link com.att.research.xacmlatt.pdp.policy.Policy} encompassing the ObligationExpression element
+	 * @return a new <code>ObligationExpression</code> parsed from the given <code>Node</code>
+	 * @throws DOMStructureException if there is an error parsing the <code>Node</code>
+	 */
+	public static ObligationExpression newInstance(Node nodeObligationExpression, Policy policy) throws DOMStructureException {
+		Element elementObligationExpression	= DOMUtil.getElement(nodeObligationExpression);
+		boolean bLenient					= DOMProperties.isLenient();
+		
+		DOMObligationExpression domObligationExpression	= new DOMObligationExpression();
+		
+		try {
+			NodeList children	= elementObligationExpression.getChildNodes();
+			int numChildren;
+			if (children != null && (numChildren = children.getLength()) > 0) {
+				for (int i = 0 ; i < numChildren ; i++) {
+					Node child	= children.item(i);
+					if (DOMUtil.isElement(child)) {
+						if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ATTRIBUTEASSIGNMENTEXPRESSION.equals(child.getLocalName())) {
+							domObligationExpression.addAttributeAssignmentExpression(DOMAttributeAssignmentExpression.newInstance(child, policy));
+						} else if (!bLenient) {
+							throw DOMUtil.newUnexpectedElementException(child, nodeObligationExpression);
+						}
+					}
+				}
+			}
+			
+			domObligationExpression.setObligationId(DOMUtil.getIdentifierAttribute(elementObligationExpression, XACML3.ATTRIBUTE_OBLIGATIONID, !bLenient));
+			
+			String string			= DOMUtil.getStringAttribute(elementObligationExpression, XACML3.ATTRIBUTE_FULFILLON, !bLenient);
+			RuleEffect ruleEffectType	= RuleEffect.getRuleEffect(string);
+			if (ruleEffectType == null) {
+				if (!bLenient) {
+					throw new DOMStructureException(nodeObligationExpression, "Invalid EffectType \"" + string + "\" in \"" + DOMUtil.getNodeLabel(nodeObligationExpression) + "\"");
+				}
+			} else {
+				domObligationExpression.setRuleEffect(ruleEffectType);
+			}
+		} catch (DOMStructureException ex) {
+			domObligationExpression.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+			if (DOMProperties.throwsExceptions()) {
+				throw ex;
+			}
+		}
+		return domObligationExpression;
+	}
+	
+	public static boolean repair(Node nodeObligationExpression) throws DOMStructureException {
+		Element elementObligationExpression	= DOMUtil.getElement(nodeObligationExpression);
+		boolean result						= false;
+		
+		NodeList children	= elementObligationExpression.getChildNodes();
+		int numChildren;
+		if (children != null && (numChildren = children.getLength()) > 0) {
+			for (int i = 0 ; i < numChildren ; i++) {
+				Node child	= children.item(i);
+				if (DOMUtil.isElement(child)) {
+					if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ATTRIBUTEASSIGNMENTEXPRESSION.equals(child.getLocalName())) {
+						result	= DOMAttributeAssignmentExpression.repair(child) || result;
+					} else {
+						logger.warn("Unexpected element " + child.getNodeName());
+						elementObligationExpression.removeChild(child);
+						result	= true;
+					}
+				}
+			}
+		}
+		
+		result					= DOMUtil.repairIdentifierAttribute(elementObligationExpression, XACML3.ATTRIBUTE_OBLIGATIONID, logger) || result;
+		result					= DOMUtil.repairStringAttribute(elementObligationExpression, XACML3.ATTRIBUTE_FULFILLON, RuleEffect.DENY.getName(), logger) || result;
+		
+		String string			= DOMUtil.getStringAttribute(elementObligationExpression, XACML3.ATTRIBUTE_FULFILLON);
+		RuleEffect ruleEffectType	= RuleEffect.getRuleEffect(string);
+		if (ruleEffectType == null) {
+			logger.warn("Setting invalid RuleEffect " + string + " to " + RuleEffect.DENY.getName());
+			elementObligationExpression.setAttribute(XACML3.ATTRIBUTE_FULFILLON, RuleEffect.DENY.getName());
+			result	= true;
+		}
+		
+		return result;
+	}
+	
+	/**
+	 * Creates a <code>List</code> of <code>ObligationExpression</code>s by parsing the given <code>Node</code>
+	 * representing a XACML ObligationExpressions element.
+	 * 
+	 * @param nodeObligationExpressions the <code>Node</code> representing the XACML ObligationExpressions element
+	 * @param policy the <code>Policy</code> encompassing the ObligationExpressions element
+	 * @return a new <code>List</code> of <code>ObligationExpression</code>s parsed from the given <code>Node</code>
+	 * @throws DOMStructureException if there is an error parsing the <code>Node</code>
+	 */
+	public static List<ObligationExpression> newList(Node nodeObligationExpressions, Policy policy) throws DOMStructureException {
+		Element elementObligationExpressions	= DOMUtil.getElement(nodeObligationExpressions);
+		boolean bLenient						= DOMProperties.isLenient();
+		
+		List<ObligationExpression> listObligationExpressions	= new ArrayList<ObligationExpression>();
+		
+		NodeList children	= elementObligationExpressions.getChildNodes();
+		int numChildren;
+		if (children != null && (numChildren = children.getLength()) > 0) {
+			for (int i = 0 ; i < numChildren ; i++) {
+				Node child	= children.item(i);
+				if (DOMUtil.isElement(child)) {
+					if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_OBLIGATIONEXPRESSION.equals(child.getLocalName())) {
+						listObligationExpressions.add(DOMObligationExpression.newInstance(child, policy));
+					} else if (!bLenient) {
+						throw DOMUtil.newUnexpectedElementException(child, elementObligationExpressions);
+					}
+				}
+			}
+		}
+		
+		if (listObligationExpressions.size() == 0 && !bLenient) {
+			throw DOMUtil.newMissingElementException(elementObligationExpressions, XACML3.XMLNS, XACML3.ELEMENT_OBLIGATIONEXPRESSION);
+		}
+		
+		return listObligationExpressions;
+	}
+	
+	public static boolean repairList(Node nodeObligationExpressions) throws DOMStructureException {
+		Element elementObligationExpressions	= DOMUtil.getElement(nodeObligationExpressions);
+		boolean result							= false;
+		
+		boolean sawObligationExpression			= false;
+		NodeList children	= elementObligationExpressions.getChildNodes();
+		int numChildren;
+		if (children != null && (numChildren = children.getLength()) > 0) {
+			for (int i = 0 ; i < numChildren ; i++) {
+				Node child	= children.item(i);
+				if (DOMUtil.isElement(child)) {
+					if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_OBLIGATIONEXPRESSION.equals(child.getLocalName())) {
+						result					= DOMObligationExpression.repair(child) || result;
+						sawObligationExpression	= true;
+					} else {
+						logger.warn("Unexpected element " + child.getNodeName());
+						elementObligationExpressions.removeChild(child);
+						result	= true;
+					}
+				}
+			}
+		}
+		if (!sawObligationExpression) {
+			throw DOMUtil.newMissingElementException(elementObligationExpressions, XACML3.XMLNS, XACML3.ELEMENT_OBLIGATIONEXPRESSION);
+		}
+		
+		return result;
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicy.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicy.java
new file mode 100755
index 0000000..b248325
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicy.java
@@ -0,0 +1,315 @@
+/*
+ *                        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.policy.dom;
+
+import java.io.File;
+import java.util.Iterator;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+import com.att.research.xacml.util.FactoryException;
+import com.att.research.xacml.util.StringUtils;
+import com.att.research.xacmlatt.pdp.policy.CombiningAlgorithm;
+import com.att.research.xacmlatt.pdp.policy.CombiningAlgorithmFactory;
+import com.att.research.xacmlatt.pdp.policy.Policy;
+import com.att.research.xacmlatt.pdp.policy.PolicyDefaults;
+import com.att.research.xacmlatt.pdp.policy.PolicySet;
+import com.att.research.xacmlatt.pdp.policy.Rule;
+
+/**
+ * DOMPolicy extends {@link com.att.research.xacmlatt.pdp.policy.Policy} with methods for creation from a
+ * DOM {@link org.w3c.dom.Node}.
+ * 
+ * @author car
+ * @version $Revision: 1.4 $
+ */
+public class DOMPolicy {
+	private static final Log logger	= LogFactory.getLog(DOMPolicy.class);
+	
+	/**
+	 * Creates a new <code>DOMPolicy</code> to be configured from a DOM <code>Node</code>.
+	 */
+	protected DOMPolicy() {
+	}
+
+	/**
+	 * Creates a new <code>DOMPolicy</code> by parsing the given <code>Node</code> representing a XACML Policy element.
+	 * 
+	 * @param nodePolicy the <code>Node</code> representing the Policy element
+	 * @param policyDefaultsParent the <code>PolicyDefaults</code> of the parent element of the Policy element or null if this is the root
+	 * @return a new <code>DOMPolicy</code> parsed from the given <code>Node</code>
+	 * @throws DOMStructureException if there is an error parsing the <code>Node</code>
+	 */
+	public static Policy newInstance(Node nodePolicy, PolicySet policySetParent, PolicyDefaults policyDefaultsParent) throws DOMStructureException {
+		Element elementPolicy	= DOMUtil.getElement(nodePolicy);
+		boolean bLenient		= DOMProperties.isLenient();
+		
+		Policy domPolicy		= new Policy(policySetParent);
+		
+		Identifier identifier;
+		Integer integer;		
+		Iterator<?> iterator;
+	
+		try {
+			NodeList children	= elementPolicy.getChildNodes();
+			int numChildren;
+			if (children != null && (numChildren = children.getLength()) > 0) {
+				/*
+				 * Run through once, quickly, to set the PolicyDefaults for the new DOMPolicySet
+				 */
+				for (int i = 0 ; i < numChildren ; i++) {
+					Node child	= children.item(i);
+					if (DOMUtil.isNamespaceElement(child, XACML3.XMLNS) && XACML3.ELEMENT_POLICYDEFAULTS.equals(child.getLocalName())) {
+						if (domPolicy.getPolicyDefaults() != null && !bLenient) {
+							throw DOMUtil.newUnexpectedElementException(child, nodePolicy);
+						}
+						domPolicy.setPolicyDefaults(DOMPolicyDefaults.newInstance(child, policyDefaultsParent));
+					}
+				}
+				if (domPolicy.getPolicyDefaults() == null) {
+					domPolicy.setPolicyDefaults(policyDefaultsParent);
+				}
+				
+				for (int i = 0 ; i < numChildren ; i++) {
+					Node child	= children.item(i);
+					if (DOMUtil.isElement(child)) {
+						if (DOMUtil.isInNamespace(child, XACML3.XMLNS)) {
+							String childName	= child.getLocalName();
+							if (XACML3.ELEMENT_DESCRIPTION.equals(childName)) {
+								if (domPolicy.getDescription() != null && !bLenient) {
+									throw DOMUtil.newUnexpectedElementException(child, nodePolicy);
+								}
+								domPolicy.setDescription(child.getTextContent());
+							} else if (XACML3.ELEMENT_POLICYISSUER.equals(childName)) {
+								if (domPolicy.getPolicyIssuer() != null && !bLenient) {
+									throw DOMUtil.newUnexpectedElementException(child, nodePolicy);
+								}
+								domPolicy.setPolicyIssuer(DOMPolicyIssuer.newInstance(child));
+							} else if (XACML3.ELEMENT_POLICYDEFAULTS.equals(childName)) {
+							} else if (XACML3.ELEMENT_TARGET.equals(childName)) {
+								if (domPolicy.getTarget() != null && !bLenient) {
+									throw DOMUtil.newUnexpectedElementException(child, nodePolicy);
+								}
+								domPolicy.setTarget(DOMTarget.newInstance(child));
+							} else if (XACML3.ELEMENT_COMBINERPARAMETERS.equals(childName)) {
+								domPolicy.addCombinerParameters(DOMCombinerParameter.newList(child));
+							} else if (XACML3.ELEMENT_RULECOMBINERPARAMETERS.equals(childName)) {
+								domPolicy.addRuleCombinerParameter(DOMRuleCombinerParameters.newInstance(child));
+							} else if (XACML3.ELEMENT_VARIABLEDEFINITION.equals(childName)) {
+								domPolicy.addVariableDefinition(DOMVariableDefinition.newInstance(child, domPolicy));
+							} else if (XACML3.ELEMENT_RULE.equals(childName)) {
+								domPolicy.addRule(DOMRule.newInstance(child, domPolicy));
+							} else if (XACML3.ELEMENT_OBLIGATIONEXPRESSIONS.equals(childName)) {
+								if ((iterator = domPolicy.getObligationExpressions()) != null && iterator.hasNext() && !bLenient) {
+									throw DOMUtil.newUnexpectedElementException(child, nodePolicy);
+								}
+								domPolicy.setObligationExpressions(DOMObligationExpression.newList(child, domPolicy));
+							} else if (XACML3.ELEMENT_ADVICEEXPRESSIONS.equals(childName)) {
+								if ((iterator = domPolicy.getAdviceExpressions())!= null && iterator.hasNext() && !bLenient) {
+									throw DOMUtil.newUnexpectedElementException(child, nodePolicy);
+								}
+								domPolicy.setAdviceExpressions(DOMAdviceExpression.newList(child, domPolicy));
+							} else if (!bLenient) {
+								throw DOMUtil.newUnexpectedElementException(child, nodePolicy);
+							}
+						}
+					}
+				}
+			}
+			domPolicy.setIdentifier(DOMUtil.getIdentifierAttribute(elementPolicy, XACML3.ATTRIBUTE_POLICYID, !bLenient));
+			domPolicy.setVersion(DOMUtil.getVersionAttribute(elementPolicy, XACML3.ATTRIBUTE_VERSION, !bLenient));
+			
+			identifier	= DOMUtil.getIdentifierAttribute(elementPolicy, XACML3.ATTRIBUTE_RULECOMBININGALGID, !bLenient);
+			CombiningAlgorithm<Rule> combiningAlgorithmRule	= null;
+			try {
+				combiningAlgorithmRule	= CombiningAlgorithmFactory.newInstance().getRuleCombiningAlgorithm(identifier);
+			} catch (FactoryException ex) {
+				if (!bLenient) {
+					throw new DOMStructureException("Failed to get CombiningAlgorithm", ex);
+				}
+			}
+			if (combiningAlgorithmRule == null && !bLenient) {
+				throw new DOMStructureException(elementPolicy, "Unknown rule combining algorithm \"" + identifier.toString() + "\" in \"" + DOMUtil.getNodeLabel(nodePolicy));
+			} else {
+				domPolicy.setRuleCombiningAlgorithm(combiningAlgorithmRule);
+			}
+			
+			
+			if ((integer = DOMUtil.getIntegerAttribute(elementPolicy, XACML3.ATTRIBUTE_MAXDELEGATIONDEPTH)) != null) {
+				domPolicy.setMaxDelegationDepth(integer);
+			}
+		} catch (DOMStructureException ex) {
+			domPolicy.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+			if (DOMProperties.throwsExceptions()) {
+				throw ex;
+			}
+		}
+		
+		return domPolicy;
+	}
+	
+	public static boolean repair(Node nodePolicy) throws DOMStructureException {
+		Element elementPolicy	= DOMUtil.getElement(nodePolicy);
+		boolean result			= false;
+		
+		NodeList children	= elementPolicy.getChildNodes();
+		int numChildren;
+		boolean sawDescription		= false;
+		boolean sawIssuer			= false;
+		boolean sawTarget			= false;
+		boolean sawPolicyDefaults	= false;
+		boolean sawObligationExprs	= false;
+		boolean sawAdviceExprs		= false;
+		
+		if (children != null && (numChildren = children.getLength()) > 0) {
+			for (int i = 0 ; i < numChildren ; i++) {
+				Node child	= children.item(i);
+				if (DOMUtil.isElement(child)) {
+					if (DOMUtil.isInNamespace(child, XACML3.XMLNS)) {
+						String childName	= child.getLocalName();
+						if (XACML3.ELEMENT_DESCRIPTION.equals(childName)) {
+							if (sawDescription) {
+								logger.warn("Unexpected element " + child.getNodeName());
+								elementPolicy.removeChild(child);
+								result	= true;
+							} else {
+								sawDescription	= true;
+							}
+						} else if (XACML3.ELEMENT_POLICYISSUER.equals(childName)) {
+							if (sawIssuer) {
+								logger.warn("Unexpected element " + child.getNodeName());
+								elementPolicy.removeChild(child);
+								result	= true;
+							} else {
+								sawDescription	= true;
+								result	= DOMPolicyIssuer.repair(child) || result;
+							}
+						} else if (XACML3.ELEMENT_POLICYDEFAULTS.equals(childName)) {
+							if (sawPolicyDefaults) {
+								logger.warn("Unexpected element " + child.getNodeName());
+								elementPolicy.removeChild(child);
+								result	= true;
+							} else {
+								sawPolicyDefaults		= true;
+								result			= DOMPolicyDefaults.repair(child) || result;
+							}
+						} else if (XACML3.ELEMENT_TARGET.equals(childName)) {
+							if (sawTarget) {
+								logger.warn("Unexpected element " + child.getNodeName());
+								elementPolicy.removeChild(child);
+								result	= true;
+							} else {
+								sawTarget		= true;
+								result			= DOMTarget.repair(child) || result;
+							}
+						} else if (XACML3.ELEMENT_COMBINERPARAMETERS.equals(childName)) {
+							result	= DOMCombinerParameter.repair(child) || result;
+						} else if (XACML3.ELEMENT_RULECOMBINERPARAMETERS.equals(childName)) {
+							result	= DOMRuleCombinerParameters.repair(child) || result;
+						} else if (XACML3.ELEMENT_VARIABLEDEFINITION.equals(childName)) {
+							result	= DOMVariableDefinition.repair(child) || result;
+						} else if (XACML3.ELEMENT_RULE.equals(childName)) {
+							result	= DOMRule.repair(child) || result;
+						} else if (XACML3.ELEMENT_OBLIGATIONEXPRESSIONS.equals(childName)) {
+							if (sawObligationExprs) {
+								logger.warn("Unexpected element " + child.getNodeName());
+								elementPolicy.removeChild(child);
+								result	= true;
+							} else {
+								sawObligationExprs	= true;
+								result				= DOMObligationExpression.repairList(child) || result;
+							}
+						} else if (XACML3.ELEMENT_ADVICEEXPRESSIONS.equals(childName)) {
+							if (sawAdviceExprs) {
+								logger.warn("Unexpected element " + child.getNodeName());
+								elementPolicy.removeChild(child);
+								result	= true;
+							} else {
+								sawAdviceExprs		= true;
+								result				= DOMAdviceExpression.repairList(child) || result;
+							}
+						} else {
+							logger.warn("Unexpected element " + child.getNodeName());
+							elementPolicy.removeChild(child);
+							result	= true;
+						}
+					}
+				}
+			}
+		}
+		result	= DOMUtil.repairIdentifierAttribute(elementPolicy, XACML3.ATTRIBUTE_POLICYID, logger) || result;
+		result	= DOMUtil.repairVersionAttribute(elementPolicy, XACML3.ATTRIBUTE_VERSION, logger) || result;
+		result	= DOMUtil.repairIdentifierAttribute(elementPolicy, XACML3.ATTRIBUTE_RULECOMBININGALGID, XACML3.ID_RULE_DENY_OVERRIDES, logger) || result;
+		
+		Identifier identifier	= DOMUtil.getIdentifierAttribute(elementPolicy, XACML3.ATTRIBUTE_RULECOMBININGALGID);
+		CombiningAlgorithm<Rule> combiningAlgorithmRule	= null;
+		try {
+			combiningAlgorithmRule	= CombiningAlgorithmFactory.newInstance().getRuleCombiningAlgorithm(identifier);
+		} catch (FactoryException ex) {
+			combiningAlgorithmRule	= null;
+		}
+		if(combiningAlgorithmRule == null) {
+			logger.warn("Setting invalid " + XACML3.ATTRIBUTE_RULECOMBININGALGID + " attribute " + identifier.stringValue() + " to " + XACML3.ID_RULE_DENY_OVERRIDES.stringValue());
+			elementPolicy.setAttribute(XACML3.ATTRIBUTE_RULECOMBININGALGID, XACML3.ID_RULE_DENY_OVERRIDES.stringValue());
+			result	= true;
+		}
+		return result;
+	}
+	
+	public static void main(String args[]) {
+		try {
+			DocumentBuilderFactory documentBuilderFactory	= DocumentBuilderFactory.newInstance();
+			documentBuilderFactory.setNamespaceAware(true);
+			DocumentBuilder documentBuilder					= documentBuilderFactory.newDocumentBuilder();
+			
+			for (String fileName: args) {
+				File filePolicy	= new File(fileName);
+				if (filePolicy.exists() && filePolicy.canRead()) {
+					try {
+						Document documentPolicy	= documentBuilder.parse(filePolicy);
+						if (documentPolicy.getFirstChild() == null) {
+							System.err.println(fileName + ": Error: No Policy found");
+						} else if (!XACML3.ELEMENT_POLICY.equals(documentPolicy.getFirstChild().getLocalName())) {
+							System.err.println(fileName + ": Error: Not a Policy documnt");
+						} else {
+							Policy	policy	= DOMPolicy.newInstance(documentPolicy.getFirstChild(), null, null);
+							System.out.println(fileName + ": validate()=" + policy.validate());
+							System.out.println(StringUtils.prettyPrint(policy.toString()));
+						}
+					} catch (Exception ex) {
+						System.err.println("Exception processing policy file \"" + fileName + "\"");
+						ex.printStackTrace(System.err);
+					}
+				} else {
+					System.err.println("Cannot read policy file \"" + fileName + "\"");
+				}
+			}
+		} catch (Exception ex) {
+			ex.printStackTrace(System.err);
+			System.exit(1);
+		}
+		System.exit(0);
+	}
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyCombinerParameter.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyCombinerParameter.java
new file mode 100755
index 0000000..041769f
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyCombinerParameter.java
@@ -0,0 +1,124 @@
+/*
+ *                        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.policy.dom;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.dom.DOMAttributeValue;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+import com.att.research.xacmlatt.pdp.policy.PolicySetChild;
+import com.att.research.xacmlatt.pdp.policy.TargetedCombinerParameter;
+
+/**
+ * DOMPolicyCombinerParameter extends {@link com.att.research.xacmlatt.pdp.policy.TargetedCombinerParameter} for
+ * {@link com.att.research.xacmlatt.pdp.policy.Policy}s with methods for creation from DOM {@link org.w3c.dom.Node}s.
+ * 
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class DOMPolicyCombinerParameter extends TargetedCombinerParameter<Identifier, PolicySetChild> {
+	private static final Log logger	= LogFactory.getLog(DOMPolicyCombinerParameter.class);
+	
+	protected DOMPolicyCombinerParameter() {
+		
+	}
+	
+	/**
+	 * Creates a new <code>TargetedCombinerParameter</code> for <code>Policy</code>s by parsing the given <code>Node</code>
+	 * representing a XACML PolicyCombinerParameter element.
+	 * 
+	 * @param nodeCombinerParameter the <code>Node</code> representing the XACML PolicyCombinerParameter element
+	 * @return a new <code>TargetedCombinerParameter</code> for <code>Policy</code>s parsed from the given <code>Node</code>
+	 * @throws DOMStructureException if there is an error parsing the <code>Node</code>
+	 */
+	public static TargetedCombinerParameter<Identifier,PolicySetChild> newInstance(Node nodeCombinerParameter) throws DOMStructureException {
+		Element elementPolicyCombinerParameter					= DOMUtil.getElement(nodeCombinerParameter);
+		boolean bLenient										= DOMProperties.isLenient();
+		
+		DOMPolicyCombinerParameter domPolicyCombinerParameter	= new DOMPolicyCombinerParameter();
+		
+		try {
+			NodeList children	= elementPolicyCombinerParameter.getChildNodes();
+			int numChildren;
+			if (children != null && (numChildren = children.getLength()) > 0) {
+				for (int i = 0 ; i < numChildren ; i++) {
+					Node child	= children.item(i);
+					if (DOMUtil.isElement(child)) {
+						if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ATTRIBUTEVALUE.equals(child.getLocalName())) {
+							domPolicyCombinerParameter.setAttributeValue(DOMAttributeValue.newInstance(child, null));
+						} else if (!bLenient) {
+							throw DOMUtil.newUnexpectedElementException(child, nodeCombinerParameter);
+						}
+					}
+				}
+			}
+			if (domPolicyCombinerParameter.getAttributeValue() == null && !bLenient) {
+				throw DOMUtil.newMissingElementException(nodeCombinerParameter, XACML3.XMLNS, XACML3.ELEMENT_ATTRIBUTEVALUE);
+			}
+			domPolicyCombinerParameter.setName(DOMUtil.getStringAttribute(elementPolicyCombinerParameter, XACML3.ATTRIBUTE_PARAMETERNAME, !bLenient));
+			domPolicyCombinerParameter.setTargetId(DOMUtil.getIdentifierAttribute(elementPolicyCombinerParameter, XACML3.ATTRIBUTE_POLICYIDREF, !bLenient));
+			
+		} catch (DOMStructureException ex) {
+			domPolicyCombinerParameter.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+			if (DOMProperties.throwsExceptions()) {
+				throw ex;
+			}
+		}
+		
+		return domPolicyCombinerParameter;
+		
+	}
+	public static boolean repair(Node nodePolicyCombinerParameter) throws DOMStructureException {
+		Element elementPolicyCombinerParameter	= DOMUtil.getElement(nodePolicyCombinerParameter);
+		boolean result							= false;
+		
+		NodeList children			= elementPolicyCombinerParameter.getChildNodes();
+		int numChildren;
+		boolean sawAttributeValue	= false;
+		if (children != null && (numChildren = children.getLength()) > 0) {
+			for (int i = 0 ; i < numChildren ; i++) {
+				Node child	= children.item(i);
+				if (DOMUtil.isElement(child)) {
+					if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ATTRIBUTEVALUE.equals(child.getLocalName())) {
+						if (sawAttributeValue) {
+							logger.warn("Unexpected element " + child.getNodeName());
+							elementPolicyCombinerParameter.removeChild(child);
+							result	= true;
+						} else {
+							sawAttributeValue	= true;
+							result				= DOMAttributeValue.repair(child) || result;
+						}
+					} else {
+						logger.warn("Unexpected element " + child.getNodeName());
+						elementPolicyCombinerParameter.removeChild(child);
+						result	= true;
+					}
+				}
+			}
+		}
+		if (!sawAttributeValue) {
+			throw DOMUtil.newMissingElementException(nodePolicyCombinerParameter, XACML3.XMLNS, XACML3.ELEMENT_ATTRIBUTEVALUE);
+		}
+		result	= DOMUtil.repairStringAttribute(elementPolicyCombinerParameter, XACML3.ATTRIBUTE_PARAMETERNAME, "parameter", logger) || result;
+		result	= DOMUtil.repairIdentifierAttribute(elementPolicyCombinerParameter, XACML3.ATTRIBUTE_POLICYIDREF, logger) || result;
+
+		return result;
+	}
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDef.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDef.java
new file mode 100755
index 0000000..45fbc17
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDef.java
@@ -0,0 +1,129 @@
+/*
+ *                        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.policy.dom;
+
+import java.io.File;
+import java.io.InputStream;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+import com.att.research.xacmlatt.pdp.policy.PolicyDef;
+import com.att.research.xacmlatt.pdp.policy.PolicySet;
+
+/**
+ * DOMPolicyDef extends {@link com.att.research.xacmlatt.pdp.policy.PolicyDef} with methods for loading them from a <code>File</code>.
+ * 
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public abstract class DOMPolicyDef {
+	protected DOMPolicyDef() {
+	}
+	
+	protected static PolicyDef newInstance(Document document, PolicySet policySetParent) throws DOMStructureException {
+		PolicyDef policyDef	= null;
+		try {
+			Node rootNode	= document.getFirstChild();
+			if (rootNode == null) {
+				throw new Exception("No child in document");
+			}
+			
+			if (DOMUtil.isInNamespace(rootNode, XACML3.XMLNS)) {
+				if (XACML3.ELEMENT_POLICY.equals(rootNode.getLocalName())) {
+					policyDef	= DOMPolicy.newInstance(rootNode, policySetParent, null);
+					if (policyDef == null) {
+						throw new DOMStructureException("Failed to parse Policy");
+					}
+				} else if (XACML3.ELEMENT_POLICYSET.equals(rootNode.getLocalName())) {
+					policyDef	= DOMPolicySet.newInstance(rootNode, policySetParent, null);
+					if (policyDef == null) {
+						throw new DOMStructureException("Failed to parse PolicySet");
+					}
+				} else {
+					throw DOMUtil.newUnexpectedElementException(rootNode);
+				}
+			} else {
+				throw DOMUtil.newUnexpectedElementException(rootNode);
+			}
+		} catch (Exception ex) {
+			throw new DOMStructureException("Exception parsing Policy: " + ex.getMessage(), ex);
+		}
+		return policyDef;		
+	}
+	
+	public static PolicyDef load(InputStream inputStream) throws DOMStructureException {
+		/*
+		 * Get the DocumentBuilderFactory
+		 */
+		DocumentBuilderFactory documentBuilderFactory	= DocumentBuilderFactory.newInstance();
+		if (documentBuilderFactory == null) {
+			throw new DOMStructureException("No XML DocumentBuilderFactory configured");
+		}
+		documentBuilderFactory.setNamespaceAware(true);
+		
+		/*
+		 * Get the DocumentBuilder
+		 */
+		DocumentBuilder documentBuilder	= null;
+		try {
+			documentBuilder	= documentBuilderFactory.newDocumentBuilder();
+		} catch (Exception ex) {
+			throw new DOMStructureException("Exception creating DocumentBuilder: " + ex.getMessage(), ex);
+		}
+		
+		/*
+		 * Parse the XML file
+		 */
+		PolicyDef policyDef	= null;
+		try {
+			Document document	= documentBuilder.parse(inputStream);
+			if (document == null) {
+				throw new Exception("Null document returned");
+			}			
+			policyDef	= newInstance(document, null);			
+		} catch (Exception ex) {
+			throw new DOMStructureException("Exception loading Policy from input stream: " + ex.getMessage(), ex);
+		}
+		return policyDef;
+	}
+
+	/**
+	 * Creates a new <code>PolicyDef</code> derived object by loading the given <code>File</code> containing a XACML 3.0
+	 * Policy or PolicySet.
+	 * 
+	 * @param filePolicy the <code>File</code> containing the XACML Policy or PolicySet
+	 * @return the newly created <code>PolicyDef</code>
+	 * @throws DOMStructureException if there is an error loading the <code>PolicyDef</code>
+	 */
+	public static PolicyDef load(File filePolicy) throws DOMStructureException {
+		/*
+		 * Parse the XML file
+		 */
+		PolicyDef policyDef	= null;
+		try {
+			Document document	= DOMUtil.loadDocument(filePolicy);
+			if (document == null) {
+				throw new Exception("Null document returned");
+			}			
+			policyDef	= newInstance(document, null);			
+		} catch (Exception ex) {
+			throw new DOMStructureException("Exception loading Policy file \"" + filePolicy.getAbsolutePath() + "\": " + ex.getMessage(), ex);
+		}
+		return policyDef;
+	}
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDefaults.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDefaults.java
new file mode 100755
index 0000000..65a78b1
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDefaults.java
@@ -0,0 +1,103 @@
+/*
+ *                        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.policy.dom;
+
+import java.net.URI;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.att.research.xacml.api.XACML;
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+import com.att.research.xacmlatt.pdp.policy.PolicyDefaults;
+
+/**
+ * DOMPolicyDefaults extends {@link com.att.research.xacmlatt.pdp.policy.PolicyDefaults} with methods for creation from
+ * DOM {@org.w3c.dom.Node}s.
+ * 
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class DOMPolicyDefaults extends PolicyDefaults {
+	private static final Log logger	= LogFactory.getLog(DOMPolicyDefaults.class);
+	
+	protected DOMPolicyDefaults(URI xpathVersionIn, PolicyDefaults policyDefaultsParentIn) {
+		super(xpathVersionIn, policyDefaultsParentIn);
+	}
+
+	/**
+	 * Creates a new <code>DOMPolicyDefaults</code> by parsing the given <code>Node</code> representing a XACML PolicyDefaults element.
+	 * 
+	 * @param nodePolicyDefaults the <code>Node</code> representing the PolicyDefaults element.
+	 * @param policyDefaultsParent the <code>PolicyDefaults</code> parent for the new <code>DOMPolicyDefaults</code>
+	 * @return a new <code>DOMPolicyDefaults</code> parsed from the given <code>Node</code>
+	 * @throws DOMStructureException if the conversion is not possible
+	 */
+	public static PolicyDefaults newInstance(Node nodePolicyDefaults, PolicyDefaults policyDefaultsParent) throws DOMStructureException {
+		Element elementPolicyDefaults	= DOMUtil.getElement(nodePolicyDefaults);
+		boolean bLenient				= DOMProperties.isLenient();
+		
+		URI uriXPathVersion		= null;
+
+		NodeList children	= elementPolicyDefaults.getChildNodes();
+		int numChildren;
+		if (children != null && (numChildren = children.getLength()) > 0) {
+			for (int i = 0 ; i < numChildren ; i++) {
+				Node child	= children.item(i);
+				if (DOMUtil.isElement(child)) {
+					if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_XPATHVERSION.equals(child.getLocalName())) {
+						uriXPathVersion	= DOMUtil.getURIContent(child);
+					} else if (!bLenient) {
+						throw DOMUtil.newUnexpectedElementException(child, nodePolicyDefaults);
+					}
+				}
+			}
+		}
+		return new DOMPolicyDefaults(uriXPathVersion, policyDefaultsParent);
+	}
+	
+	public static boolean repair(Node nodePolicyDefaults) throws DOMStructureException {
+		Element elementPolicyDefaults	= DOMUtil.getElement(nodePolicyDefaults);
+		boolean result					= false;
+		
+		NodeList children	= elementPolicyDefaults.getChildNodes();
+		int numChildren;
+		if (children != null && (numChildren = children.getLength()) > 0) {
+			for (int i = 0 ; i < numChildren ; i++) {
+				Node child	= children.item(i);
+				if (DOMUtil.isElement(child)) {
+					if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_XPATHVERSION.equals(child.getLocalName())) {
+						try {
+							DOMUtil.getURIContent(child);
+						} catch (DOMStructureException ex) {
+							logger.warn("Setting invalid " + XACML3.ELEMENT_XPATHVERSION + " attribute " + child.getTextContent() + " to " + XACML.XPATHVERSION_2_0);
+							child.setTextContent(XACML.XPATHVERSION_2_0);
+							result	= true;
+						}
+					} else {
+						logger.warn("Unexpected element " + child.getNodeName());
+						elementPolicyDefaults.removeChild(child);
+						result	= true;
+					}
+				}
+			}
+		}
+		
+		return result;
+	}
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIdReference.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIdReference.java
new file mode 100755
index 0000000..3aa9870
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIdReference.java
@@ -0,0 +1,59 @@
+/*
+ *                        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.policy.dom;
+
+import org.w3c.dom.Node;
+
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.dom.DOMIdReferenceMatch;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacmlatt.pdp.policy.PolicyIdReference;
+import com.att.research.xacmlatt.pdp.policy.PolicySet;
+
+/**
+ * DOMPolicyIdReference extends {@link com.att.research.xacmlatt.pdp.policy.PolicyIdReference} with methods for creation
+ * from DOM {@link org.w3c.dom.Node}s.
+ * 
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class DOMPolicyIdReference {
+	
+	protected DOMPolicyIdReference() {
+	}
+
+	/**
+	 * Creates a new <code>PolicyIdReference</code> parsed from the given <code>Node</code> representing a XACML PolicyIdReference element.
+	 * 
+	 * @param nodePolicyIdReference the <code>Node</code> representing the XACML PolicyIdReference element
+	 * @return a new <code>PolicyIdReference</code> parsed from the given <code>Node</code>
+	 * @throws DOMStructureException if there is an error parsing the <code>Node</code>
+	 */
+	public static PolicyIdReference newInstance(Node nodePolicyIdReference, PolicySet policySetParent) throws DOMStructureException {
+		PolicyIdReference domPolicyIdReference	= new PolicyIdReference(policySetParent);
+		
+		try {
+			domPolicyIdReference.setIdReferenceMatch(DOMIdReferenceMatch.newInstance(nodePolicyIdReference));
+		} catch (DOMStructureException ex) {
+			domPolicyIdReference.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+			if (DOMProperties.throwsExceptions()) {
+				throw ex;
+			}
+		}
+		
+		return domPolicyIdReference;
+	}
+	
+	public static boolean repair(Node nodePolicyIdReference) throws DOMStructureException {
+		return DOMIdReferenceMatch.repair(nodePolicyIdReference);
+	}
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIssuer.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIssuer.java
new file mode 100755
index 0000000..d1e4089
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIssuer.java
@@ -0,0 +1,126 @@
+/*
+ *                        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.policy.dom;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.IdentifierImpl;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.dom.DOMAttribute;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+import com.att.research.xacmlatt.pdp.policy.PolicyIssuer;
+
+/**
+ * DOMPolicyIssuer extends {@link com.att.research.xacmlatt.pdp.policy.PolicyIsser} with methods for creation from
+ * DOM {@link org.w3c.dom.Node}s.
+ * 
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class DOMPolicyIssuer extends PolicyIssuer {
+	private static Log 			logger							= LogFactory.getLog(DOMPolicyIssuer.class);
+	private static Identifier	identifierCategoryPolicyIssuer 	= new IdentifierImpl("urn:att:names:tc:xacml:3.0:policy-issuer");
+	
+	protected DOMPolicyIssuer() {
+		super();
+	}
+	
+	/**
+	 * Creates a new <code>DOMPolicyIssuer</code> by parsing the given <code>Node</code> representing a XACML PolicyIssuer element.
+	 * 
+	 * @param nodePolicyIssuer the <code>Node</code> representing the PolicyIssuer element
+	 * @return the new <code>DOMPolicyIssuer</code> parsed from the given <code>Node</code>
+	 * @throws DOMStructureException if the conversion is not possible
+	 */
+	public static PolicyIssuer newInstance(Node nodePolicyIssuer) throws DOMStructureException {
+		Element elementPolicyIssuer		= DOMUtil.getElement(nodePolicyIssuer);
+		boolean bLenient				= DOMProperties.isLenient();
+		
+		DOMPolicyIssuer domPolicyIssuer	= new DOMPolicyIssuer();
+		
+		try {
+			NodeList children	= elementPolicyIssuer.getChildNodes();
+			int numChildren;
+			if (children != null && (numChildren = children.getLength()) > 0) {
+				for (int i = 0 ; i < numChildren ; i++) {
+					Node child	= children.item(i);
+					if (DOMUtil.isElement(child)) {
+						if (DOMUtil.isInNamespace(child, XACML3.XMLNS)) {
+							String childName	= child.getLocalName();
+							if (XACML3.ELEMENT_CONTENT.equals(childName)) {
+								if (domPolicyIssuer.getContent() != null && !bLenient) {
+									throw DOMUtil.newUnexpectedElementException(child, nodePolicyIssuer);
+								}
+								domPolicyIssuer.setContent(child);
+							} else if (XACML3.ELEMENT_ATTRIBUTE.equals(childName)) {
+								domPolicyIssuer.add(DOMAttribute.newInstance(identifierCategoryPolicyIssuer, child));
+							} else if (!bLenient) {
+								throw DOMUtil.newUnexpectedElementException(child, nodePolicyIssuer);
+							}
+						}
+					}
+				}
+			}
+		} catch (DOMStructureException ex) {
+			domPolicyIssuer.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+			if (DOMProperties.throwsExceptions()) {
+				throw ex;
+			}
+		}
+		
+		return domPolicyIssuer;		
+	}
+	
+	public static boolean repair(Node nodePolicyIssuer) throws DOMStructureException {
+		Element elementPolicyIssuer		= DOMUtil.getElement(nodePolicyIssuer);
+		boolean result					= false;
+		
+		boolean sawContent				= false;
+		NodeList children	= elementPolicyIssuer.getChildNodes();
+		int numChildren;
+		if (children != null && (numChildren = children.getLength()) > 0) {
+			for (int i = 0 ; i < numChildren ; i++) {
+				Node child	= children.item(i);
+				if (DOMUtil.isElement(child)) {
+					if (DOMUtil.isInNamespace(child, XACML3.XMLNS)) {
+						String childName	= child.getLocalName();
+						if (XACML3.ELEMENT_CONTENT.equals(childName)) {
+							if (sawContent) {
+								logger.warn("Unexpected element " + child.getNodeName());
+								elementPolicyIssuer.removeChild(child);
+								result	= true;
+							} else {
+								sawContent	= true;
+							}
+						} else if (XACML3.ELEMENT_ATTRIBUTE.equals(childName)) {
+							result	= DOMAttribute.repair(child) || result;
+						} else {
+							logger.warn("Unexpected element " + child.getNodeName());
+							elementPolicyIssuer.removeChild(child);
+							result	= true;
+						}
+					}
+				}
+			}
+		}
+		
+		return result;
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyRepair.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyRepair.java
new file mode 100755
index 0000000..20cff15
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyRepair.java
@@ -0,0 +1,113 @@
+/*
+ *                        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.policy.dom;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.dom.DOMUtil;
+
+/**
+ * DOMPolicyRepair is an application for reading a XACML Policy or PolicySet document and ensuring it has the required attributes and then writing
+ * the repaired Policy or PolicySet to an output file.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class DOMPolicyRepair {
+	private static final String	DEFAULT_VERSION	= "1.0";
+	
+	public static void main(String[] args) {
+		InputStream	inputStream		= System.in;
+		OutputStream outputStream	= System.out;
+		
+		for (int i = 0 ; i < args.length ; ) {
+			if (args[i].equals("-i")) {
+				if (i+1 < args.length) {
+					try {
+						inputStream	= new FileInputStream(args[i+1]);
+					} catch (IOException ex) {
+						System.err.println("IOException opening \"" + args[i+1] + "\" for reading.");
+						System.exit(1);
+					}
+					i	+= 2;
+				} else {
+					i++;
+				}
+			} else if (args[i].equals("-o")) {
+				if (i+1 < args.length){
+					try {
+						outputStream = new FileOutputStream(args[i+1]);
+					} catch (IOException ex) {
+						System.err.println("IOException opening \"" + args[i+1] + "\" for writing.");
+						ex.printStackTrace(System.err);
+						System.exit(1);;
+					}
+					i	+= 2;
+				} else {
+					i++;
+				}
+			} else {
+				System.err.println("Unrecognized command line option \"" + args[i] + "\"");
+				System.exit(1);
+			}
+		}
+		
+		/*
+		 * Get the XML Parser for the input file
+		 */
+		DocumentBuilderFactory documentBuilderFactory	= DocumentBuilderFactory.newInstance();
+		documentBuilderFactory.setNamespaceAware(true);
+		try {
+			DocumentBuilder documentBuilder				= documentBuilderFactory.newDocumentBuilder();
+			Document documentInput						= documentBuilder.parse(inputStream);
+			Element elementRoot							= DOMUtil.getFirstChildElement(documentInput);
+			if (elementRoot == null) {
+				System.err.println("No root element");
+				System.exit(1);
+			} else if (!XACML3.ELEMENT_POLICY.equals(elementRoot.getLocalName()) && !XACML3.ELEMENT_POLICYSET.equals(elementRoot.getLocalName())) {
+				System.err.println("Root element is not a Policy or PolicySet");
+				System.exit(1);
+			}
+			
+			/*
+			 * Make sure there is a Version attribute
+			 */
+			Node nodeVersion	= DOMUtil.getAttribute(elementRoot, XACML3.ATTRIBUTE_VERSION);
+			if (nodeVersion == null) {
+				System.out.println("Adding Version attribute with value \"" + DEFAULT_VERSION + "\"");
+				elementRoot.setAttribute(XACML3.ATTRIBUTE_VERSION, DEFAULT_VERSION);
+			}
+			
+			/*
+			 * Write out the updated document
+			 */
+			String newDocument	= DOMUtil.toString(documentInput);
+			outputStream.write(newDocument.getBytes());
+		} catch (Exception ex) {
+			ex.printStackTrace(System.err);
+			System.exit(1);
+		}
+		System.exit(0);
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySet.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySet.java
new file mode 100755
index 0000000..c69a921
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySet.java
@@ -0,0 +1,349 @@
+/*
+ *                        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.policy.dom;
+
+import java.io.File;
+import java.util.Iterator;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+import com.att.research.xacml.util.FactoryException;
+import com.att.research.xacml.util.StringUtils;
+import com.att.research.xacmlatt.pdp.policy.CombiningAlgorithm;
+import com.att.research.xacmlatt.pdp.policy.CombiningAlgorithmFactory;
+import com.att.research.xacmlatt.pdp.policy.PolicyDefaults;
+import com.att.research.xacmlatt.pdp.policy.PolicySet;
+import com.att.research.xacmlatt.pdp.policy.PolicySetChild;
+
+/**
+ * DOMPolicySet extends {@link com.att.research.xacmlatt.pdp.policy.PolicySet} with methods for creation
+ * from DOM {@link org.w3c.dom.Node}s.
+ * 
+ * @author car
+ * @version $Revision: 1.4 $
+ */
+public class DOMPolicySet {
+	private static final Log logger	= LogFactory.getLog(DOMPolicySet.class);
+	
+	protected DOMPolicySet() {
+	}
+	
+	/**
+	 * Creates a new <code>PolicySet</code> by parsing the given <code>Node</code> representing a XACML PolicySet element.
+	 * 
+	 * @param nodePolicySet the <code>Node</code> representing the XACML PolicySetelement
+	 * @param policyDefaultsParent the {@link com.att.research.xacmlatt.pdp.policy.PolicyDefaults} from the parent element
+	 * @return a new <code>PolicySet</code> parsed from the given <code>Node</code>
+	 * @throws DOMStructureException if there is an error parsing the <code>Node</code>
+	 */
+	public static PolicySet newInstance(Node nodePolicySet, PolicySet policySetParent, PolicyDefaults policyDefaultsParent) throws DOMStructureException {
+		Element elementPolicySet	= DOMUtil.getElement(nodePolicySet);
+		boolean bLenient			= DOMProperties.isLenient();
+		
+		PolicySet domPolicySet		= new PolicySet(policySetParent);
+		
+		Iterator<?> iterator;
+		Identifier identifier;
+		Integer integer;
+		
+		try {
+			NodeList children	= elementPolicySet.getChildNodes();
+			int numChildren;
+			if (children != null && (numChildren = children.getLength()) > 0) {
+				/*
+				 * Run through once, quickly, to set the PolicyDefaults for the new DOMPolicySet
+				 */
+				for (int i = 0 ; i < numChildren ; i++) {
+					Node child	= children.item(i);
+					if (DOMUtil.isNamespaceElement(child, XACML3.XMLNS) && XACML3.ELEMENT_POLICYDEFAULTS.equals(child.getLocalName())) {
+						if (domPolicySet.getPolicyDefaults() != null && !bLenient) {
+							throw DOMUtil.newUnexpectedElementException(child, nodePolicySet);
+						}
+						domPolicySet.setPolicyDefaults(DOMPolicyDefaults.newInstance(child, policyDefaultsParent));
+					}
+				}
+				if (domPolicySet.getPolicyDefaults() == null) {
+					domPolicySet.setPolicyDefaults(policyDefaultsParent);
+				}
+				
+				/*
+				 * Now process the other elements so we can pull up the parent policy defaults
+				 */
+				for (int i = 0 ; i < numChildren ; i++) {
+					Node child	= children.item(i);
+					if (DOMUtil.isElement(child)) {
+						if (DOMUtil.isInNamespace(child, XACML3.XMLNS)) {
+							String childName	= child.getLocalName();
+							if (XACML3.ELEMENT_DESCRIPTION.equals(childName)) {
+								if (domPolicySet.getDescription() != null && !bLenient) {
+									throw DOMUtil.newUnexpectedElementException(child, nodePolicySet);
+								}
+								domPolicySet.setDescription(child.getTextContent());
+							} else if (XACML3.ELEMENT_POLICYISSUER.equals(childName)) {
+								if (domPolicySet.getPolicyIssuer() != null && !bLenient) {
+									throw DOMUtil.newUnexpectedElementException(child, nodePolicySet);
+								}
+								domPolicySet.setPolicyIssuer(DOMPolicyIssuer.newInstance(child));
+							} else if (XACML3.ELEMENT_POLICYSETDEFAULTS.equals(childName)) {
+							} else if (XACML3.ELEMENT_TARGET.equals(childName)) {
+								if (domPolicySet.getTarget() != null && !bLenient) {
+									throw DOMUtil.newUnexpectedElementException(child, nodePolicySet);
+								}
+								domPolicySet.setTarget(DOMTarget.newInstance(child));
+							} else if (XACML3.ELEMENT_POLICYSET.equals(childName)) {
+								domPolicySet.addChild(DOMPolicySet.newInstance(child, domPolicySet, domPolicySet.getPolicyDefaults()));
+							} else if (XACML3.ELEMENT_POLICY.equals(childName)) {
+								domPolicySet.addChild(DOMPolicy.newInstance(child, domPolicySet, domPolicySet.getPolicyDefaults()));
+							} else if (XACML3.ELEMENT_POLICYIDREFERENCE.equals(childName)) {
+								domPolicySet.addChild(DOMPolicyIdReference.newInstance(child, domPolicySet));
+							} else if (XACML3.ELEMENT_POLICYSETIDREFERENCE.equals(childName)) {
+								domPolicySet.addChild(DOMPolicySetIdReference.newInstance(child, domPolicySet));
+							} else if (XACML3.ELEMENT_COMBINERPARAMETERS.equals(childName)) {
+								domPolicySet.addCombinerParameters(DOMCombinerParameter.newList(child));
+							} else if (XACML3.ELEMENT_POLICYCOMBINERPARAMETERS.equals(childName)) {
+								domPolicySet.addPolicyCombinerParameter(DOMPolicyCombinerParameter.newInstance(child));
+							} else if (XACML3.ELEMENT_POLICYSETCOMBINERPARAMETERS.equals(childName)) {
+								domPolicySet.addPolicyCombinerParameter(DOMPolicySetCombinerParameter.newInstance(child));
+							} else if (XACML3.ELEMENT_OBLIGATIONEXPRESSIONS.equals(childName)) {
+								if ((iterator = domPolicySet.getObligationExpressions()) != null && iterator.hasNext() && !bLenient) {
+									throw DOMUtil.newUnexpectedElementException(child, nodePolicySet);
+								}
+								domPolicySet.setObligationExpressions(DOMObligationExpression.newList(child, null));
+							} else if (XACML3.ELEMENT_ADVICEEXPRESSIONS.equals(childName)) {
+								if ((iterator = domPolicySet.getAdviceExpressions()) != null && iterator.hasNext() && !bLenient) {
+									throw DOMUtil.newUnexpectedElementException(child, nodePolicySet);
+								}
+								domPolicySet.setAdviceExpressions(DOMAdviceExpression.newList(child, null));
+							} else if (!bLenient) {
+								throw DOMUtil.newUnexpectedElementException(child, nodePolicySet);
+							}
+						} else if (!bLenient) {
+							throw DOMUtil.newUnexpectedElementException(child, nodePolicySet);
+						}
+					}
+				}
+			}
+			if (domPolicySet.getTarget() == null && !bLenient) {
+				throw DOMUtil.newMissingElementException(nodePolicySet, XACML3.XMLNS, XACML3.ELEMENT_TARGET);
+			}
+			
+			/*
+			 * Get the attributes
+			 */
+			domPolicySet.setIdentifier(DOMUtil.getIdentifierAttribute(elementPolicySet, XACML3.ATTRIBUTE_POLICYSETID, !bLenient));
+			domPolicySet.setVersion(DOMUtil.getVersionAttribute(elementPolicySet, XACML3.ATTRIBUTE_VERSION, !bLenient));
+			
+			identifier	= DOMUtil.getIdentifierAttribute(elementPolicySet, XACML3.ATTRIBUTE_POLICYCOMBININGALGID, !bLenient);
+			CombiningAlgorithm<PolicySetChild> combiningAlgorithm	= null;
+			try {
+				combiningAlgorithm	= CombiningAlgorithmFactory.newInstance().getPolicyCombiningAlgorithm(identifier);
+			} catch (FactoryException ex) {
+				if (!bLenient) {
+					throw new DOMStructureException("Failed to get CombinginAlgorithm", ex);
+				}
+			}
+			if (combiningAlgorithm == null && !bLenient) {
+				throw new DOMStructureException(elementPolicySet, "Unknown policy combining algorithm \"" + identifier.toString() + "\" in \"" + DOMUtil.getNodeLabel(nodePolicySet));
+			} else {
+				domPolicySet.setPolicyCombiningAlgorithm(combiningAlgorithm);
+			}
+			
+			if ((integer = DOMUtil.getIntegerAttribute(elementPolicySet, XACML3.ATTRIBUTE_MAXDELEGATIONDEPTH)) != null) {
+				domPolicySet.setMaxDelegationDepth(integer);
+			}
+		} catch (DOMStructureException ex) {
+			domPolicySet.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+			if (DOMProperties.throwsExceptions()) {
+				throw ex;
+			}
+		}
+		
+		return domPolicySet;
+	}
+	
+	public static boolean repair(Node nodePolicySet) throws DOMStructureException {
+		Element elementPolicySet	= DOMUtil.getElement(nodePolicySet);
+		boolean result				= false;
+		
+		NodeList children	= elementPolicySet.getChildNodes();
+		int numChildren;
+		boolean sawDescription		= false;
+		boolean sawPolicyIssuer		= false;
+		boolean sawPolicyDefaults	= false;
+		boolean sawTarget			= false;
+		boolean sawObligationExprs	= false;
+		boolean sawAdviceExprs		= false;
+		
+		if (children != null && (numChildren = children.getLength()) > 0) {
+			/*
+			 * Now process the other elements so we can pull up the parent policy defaults
+			 */
+			for (int i = 0 ; i < numChildren ; i++) {
+				Node child	= children.item(i);
+				if (DOMUtil.isElement(child)) {
+					if (DOMUtil.isInNamespace(child, XACML3.XMLNS)) {
+						String childName	= child.getLocalName();
+						if (XACML3.ELEMENT_DESCRIPTION.equals(childName)) {
+							if (sawDescription) {
+								logger.warn("Unexpected element " + child.getNodeName());
+								elementPolicySet.removeChild(child);
+								result	= true;
+							} else {
+								sawDescription	= true;
+							}
+						} else if (XACML3.ELEMENT_POLICYISSUER.equals(childName)) {
+							if (sawPolicyIssuer) {
+								logger.warn("Unexpected element " + child.getNodeName());
+								elementPolicySet.removeChild(child);
+								result	= true;
+							} else {
+								sawPolicyIssuer	= true;
+								result	= DOMPolicyIssuer.repair(child) || result;
+							}
+						} else if (XACML3.ELEMENT_POLICYSETDEFAULTS.equals(childName)) {
+							if (sawPolicyDefaults) {
+								logger.warn("Unexpected element " + child.getNodeName());
+								elementPolicySet.removeChild(child);
+								result	= true;								
+							} else {
+								sawPolicyDefaults	= true;
+								result				= DOMPolicyDefaults.repair(child) || result;
+							}
+						} else if (XACML3.ELEMENT_TARGET.equals(childName)) {
+							if (sawTarget) {
+								logger.warn("Unexpected element " + child.getNodeName());
+								elementPolicySet.removeChild(child);
+								result	= true;
+							} else {
+								sawTarget	= true;
+								result		= DOMTarget.repair(child) || result;
+							}
+						} else if (XACML3.ELEMENT_POLICYSET.equals(childName)) {
+							result	= DOMPolicySet.repair(child) || result;
+						} else if (XACML3.ELEMENT_POLICY.equals(childName)) {
+							result 	= DOMPolicy.repair(child) || result;
+						} else if (XACML3.ELEMENT_POLICYIDREFERENCE.equals(childName)) {
+							result	= DOMPolicyIdReference.repair(child) || result;
+						} else if (XACML3.ELEMENT_POLICYSETIDREFERENCE.equals(childName)) {
+							result	= DOMPolicySetIdReference.repair(child) || result;
+						} else if (XACML3.ELEMENT_COMBINERPARAMETERS.equals(childName)) {
+							result	= DOMCombinerParameter.repair(child) || result;
+						} else if (XACML3.ELEMENT_POLICYCOMBINERPARAMETERS.equals(childName)) {
+							result	= DOMPolicyCombinerParameter.repair(child) || result;
+						} else if (XACML3.ELEMENT_POLICYSETCOMBINERPARAMETERS.equals(childName)) {
+							result	= DOMPolicySetCombinerParameter.repair(child) || result;
+						} else if (XACML3.ELEMENT_OBLIGATIONEXPRESSIONS.equals(childName)) {
+							if (sawObligationExprs) {
+								logger.warn("Unexpected element " + child.getNodeName());
+								elementPolicySet.removeChild(child);
+								result	= true;
+							} else {
+								sawObligationExprs	= true;
+								result				= DOMObligationExpression.repairList(child) || result;
+							}
+						} else if (XACML3.ELEMENT_ADVICEEXPRESSIONS.equals(childName)) {
+							if (sawAdviceExprs) {
+								logger.warn("Unexpected element " + child.getNodeName());
+								elementPolicySet.removeChild(child);
+								result	= true;
+							} else {
+								sawAdviceExprs	= true;
+								result			= DOMAdviceExpression.repairList(child) || result;
+							}
+						} else {
+							logger.warn("Unexpected element " + child.getNodeName());
+							elementPolicySet.removeChild(child);
+							result	= true;
+						}
+					} else  {
+						logger.warn("Unexpected element " + child.getNodeName());
+						elementPolicySet.removeChild(child);
+						result	= true;
+					}
+				}
+			}
+		}
+		if (!sawTarget) {
+			throw DOMUtil.newMissingElementException(nodePolicySet, XACML3.XMLNS, XACML3.ELEMENT_TARGET);
+		}
+		
+		/*
+		 * Get the attributes
+		 */
+		result	= DOMUtil.repairIdentifierAttribute(elementPolicySet, XACML3.ATTRIBUTE_POLICYSETID, logger) || result;
+		result	= DOMUtil.repairVersionAttribute(elementPolicySet, XACML3.ATTRIBUTE_VERSION, logger) || result;
+		result	= DOMUtil.repairIdentifierAttribute(elementPolicySet, XACML3.ATTRIBUTE_POLICYCOMBININGALGID, XACML3.ID_POLICY_DENY_OVERRIDES, logger) || result;
+		
+		Identifier identifier	= DOMUtil.getIdentifierAttribute(elementPolicySet, XACML3.ATTRIBUTE_POLICYCOMBININGALGID);
+		CombiningAlgorithm<PolicySetChild> combiningAlgorithm	= null;
+		try {
+			combiningAlgorithm	= CombiningAlgorithmFactory.newInstance().getPolicyCombiningAlgorithm(identifier);
+		} catch (FactoryException ex) {
+			combiningAlgorithm	= null;
+		}
+		if (combiningAlgorithm == null) {
+			logger.warn("Setting invalid " + XACML3.ATTRIBUTE_POLICYCOMBININGALGID + " attribute " + identifier.stringValue() + " to " + XACML3.ID_POLICY_DENY_OVERRIDES.stringValue());
+			elementPolicySet.setAttribute(XACML3.ATTRIBUTE_POLICYCOMBININGALGID, XACML3.ID_POLICY_DENY_OVERRIDES.stringValue());
+			result	= true;
+		}
+		
+		return result;
+	}
+
+	public static void main(String args[]) {
+		try {
+			DocumentBuilderFactory documentBuilderFactory	= DocumentBuilderFactory.newInstance();
+			documentBuilderFactory.setNamespaceAware(true);
+			DocumentBuilder documentBuilder					= documentBuilderFactory.newDocumentBuilder();
+			
+			for (String fileName: args) {
+				File filePolicy	= new File(fileName);
+				if (filePolicy.exists() && filePolicy.canRead()) {
+					try {
+						Document documentPolicy	= documentBuilder.parse(filePolicy);
+						if (documentPolicy.getFirstChild() == null) {
+							System.err.println(fileName + ": Error: No PolicySet found");
+						} else if (!XACML3.ELEMENT_POLICYSET.equals(documentPolicy.getFirstChild().getLocalName())) {
+							System.err.println(fileName + ": Error: Not a PolicySet document");
+						} else {
+							PolicySet	policySet	= DOMPolicySet.newInstance(documentPolicy.getFirstChild(), null, null);
+							System.out.println(fileName + ": validate()=" + policySet.validate());
+							System.out.println(StringUtils.prettyPrint(policySet.toString()));
+						}
+					} catch (Exception ex) {
+						System.err.println("Exception processing policy set file \"" + fileName + "\"");
+						ex.printStackTrace(System.err);
+					}
+				} else {
+					System.err.println("Cannot read policy set file \"" + fileName + "\"");
+				}
+			}
+		} catch (Exception ex) {
+			ex.printStackTrace(System.err);
+			System.exit(1);
+		}
+		System.exit(0);
+	}
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetCombinerParameter.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetCombinerParameter.java
new file mode 100755
index 0000000..42d856c
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetCombinerParameter.java
@@ -0,0 +1,126 @@
+/*
+ *                        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.policy.dom;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.dom.DOMAttributeValue;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+import com.att.research.xacmlatt.pdp.policy.PolicySetChild;
+import com.att.research.xacmlatt.pdp.policy.TargetedCombinerParameter;
+
+/**
+ * DOMPolicySetCombinerParameter extends {@link com.att.research.xacmlatt.pdp.policy.TargetedCombinerParameter} for
+ * {@link com.att.research.xacmlatt.pdp.policy.PolicySet}s with methods for creation from DOM {@link org.w3c.dom.Node}s.
+ * 
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class DOMPolicySetCombinerParameter extends TargetedCombinerParameter<Identifier, PolicySetChild> {
+	public static final Log logger	= LogFactory.getLog(DOMPolicySetCombinerParameter.class);
+	
+	protected DOMPolicySetCombinerParameter() {
+		
+	}
+	
+	/**
+	 * Creates a new <code>TargetedCombinerParameter</code> for <code>PolicySet</code>s by parsing the given <code>Node</code>
+	 * representing a XACML PolicySetCombinerParameter element.
+	 * 
+	 * @param nodeCombinerParameter the <code>Node</code> representing the XACML PolicySetCombinerParameter element
+	 * @return a new <code>TargetedCombinerParameter</code> for <code>PolicySet</code>s parsed from the given <code>Node</code>
+	 * @throws DOMStructureException if there is an error parsing the <code>Node</code>
+	 */
+	public static TargetedCombinerParameter<Identifier,PolicySetChild> newInstance(Node nodeCombinerParameter) throws DOMStructureException {
+		Element elementPolicySetCombinerParameter					= DOMUtil.getElement(nodeCombinerParameter);
+		boolean bLenient											= DOMProperties.isLenient();
+		
+		DOMPolicySetCombinerParameter domPolicySetCombinerParameter	= new DOMPolicySetCombinerParameter();
+		
+		try {
+			NodeList children	= elementPolicySetCombinerParameter.getChildNodes();
+			int numChildren;
+			if (children != null && (numChildren = children.getLength()) > 0) {
+				for (int i = 0 ; i < numChildren ; i++) {
+					Node child	= children.item(i);
+					if (DOMUtil.isElement(child)) {
+						if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ATTRIBUTEVALUE.equals(child.getLocalName())) {
+							if (domPolicySetCombinerParameter.getAttributeValue() != null && !bLenient) {
+								throw DOMUtil.newUnexpectedElementException(child, nodeCombinerParameter);
+							}
+							domPolicySetCombinerParameter.setAttributeValue(DOMAttributeValue.newInstance(child, null));
+						} else if (!bLenient) {
+							throw DOMUtil.newUnexpectedElementException(child, nodeCombinerParameter);
+						}
+					}
+				}
+			}
+			if (domPolicySetCombinerParameter.getAttributeValue() == null && !bLenient) {
+				throw DOMUtil.newMissingElementException(elementPolicySetCombinerParameter, XACML3.XMLNS, XACML3.ELEMENT_ATTRIBUTEVALUE);
+			}
+			domPolicySetCombinerParameter.setName(DOMUtil.getStringAttribute(elementPolicySetCombinerParameter, XACML3.ATTRIBUTE_PARAMETERNAME, !bLenient));
+			domPolicySetCombinerParameter.setTargetId(DOMUtil.getIdentifierAttribute(elementPolicySetCombinerParameter, XACML3.ATTRIBUTE_POLICYSETIDREF, !bLenient));
+		} catch (DOMStructureException ex) {
+			domPolicySetCombinerParameter.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+			if (DOMProperties.throwsExceptions()) {
+				throw ex;
+			}
+		}
+		
+		return domPolicySetCombinerParameter;
+		
+	}
+	
+	public static boolean repair(Node nodeCombinerParameter) throws DOMStructureException {
+		Element elementPolicySetCombinerParameter	= DOMUtil.getElement(nodeCombinerParameter);
+		boolean result								= false;
+		
+		NodeList children	= elementPolicySetCombinerParameter.getChildNodes();
+		int numChildren;
+		boolean sawAttributeValue	= false;
+		if (children != null && (numChildren = children.getLength()) > 0) {
+			for (int i = 0 ; i < numChildren ; i++) {
+				Node child	= children.item(i);
+				if (DOMUtil.isElement(child)) {
+					if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ATTRIBUTEVALUE.equals(child.getLocalName())) {
+						if (sawAttributeValue) {
+							logger.warn("Unexpected element " + child.getNodeName());
+							elementPolicySetCombinerParameter.removeChild(child);
+							result	= true;
+						} else {
+							sawAttributeValue	= true;
+							result				= DOMAttributeValue.repair(child) || result;
+						}
+					} else {
+						logger.warn("Unexpected element " + child.getNodeName());
+						elementPolicySetCombinerParameter.removeChild(child);
+						result	= true;
+					}
+				}
+			}
+		}
+		if (!sawAttributeValue) {
+			throw DOMUtil.newMissingElementException(elementPolicySetCombinerParameter, XACML3.XMLNS, XACML3.ELEMENT_ATTRIBUTEVALUE);
+		}
+		result	= DOMUtil.repairStringAttribute(elementPolicySetCombinerParameter, XACML3.ATTRIBUTE_PARAMETERNAME, "parameter", logger) || result;
+		result	= DOMUtil.repairIdentifierAttribute(elementPolicySetCombinerParameter, XACML3.ATTRIBUTE_POLICYSETIDREF, logger) || result;
+		return result;
+	}
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetIdReference.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetIdReference.java
new file mode 100755
index 0000000..0f45c43
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetIdReference.java
@@ -0,0 +1,58 @@
+/*
+ *                        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.policy.dom;
+
+import org.w3c.dom.Node;
+
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.dom.DOMIdReferenceMatch;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacmlatt.pdp.policy.PolicySet;
+import com.att.research.xacmlatt.pdp.policy.PolicySetIdReference;
+
+/**
+ * DOMPolicySetIdReference extends {@link com.att.research.xacmlatt.pdp.policy.PolicySetIdReference} with methods for creation
+ * from DOM {@link org.w3c.dom.Node}s.
+ * 
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class DOMPolicySetIdReference {
+	protected DOMPolicySetIdReference() {
+	}
+
+	/**
+	 * Creates a new <code>PolicySetIdReference</code> parsed from the given <code>Node</code> representing a XACML PolicySetIdReference element.
+	 * 
+	 * @param nodePolicySetIdReference the <code>Node</code> representing the XACML PolicySetIdReference element
+	 * @return a new <code>PolicySetIdReference</code> parsed from the given <code>Node</code>
+	 * @throws DOMStructureException if there is an error parsing the <code>Node</code>
+	 */
+	public static PolicySetIdReference newInstance(Node nodePolicySetIdReference, PolicySet policySetParent) throws DOMStructureException {
+		PolicySetIdReference domPolicySetIdReference	= new PolicySetIdReference(policySetParent);
+		
+		try {
+			domPolicySetIdReference.setIdReferenceMatch(DOMIdReferenceMatch.newInstance(nodePolicySetIdReference));
+		} catch (DOMStructureException ex) {
+			domPolicySetIdReference.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+			if (DOMProperties.throwsExceptions()) {
+				throw ex;
+			}
+		}
+		
+		return domPolicySetIdReference;
+	}
+	
+	public static boolean repair(Node nodePolicySetIdReference) throws DOMStructureException {
+		return DOMIdReferenceMatch.repair(nodePolicySetIdReference);
+	}
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMRule.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMRule.java
new file mode 100755
index 0000000..102f546
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMRule.java
@@ -0,0 +1,221 @@
+/*
+ *                        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.policy.dom;
+
+import java.util.Iterator;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.IdentifierImpl;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+import com.att.research.xacmlatt.pdp.policy.Condition;
+import com.att.research.xacmlatt.pdp.policy.Policy;
+import com.att.research.xacmlatt.pdp.policy.Rule;
+import com.att.research.xacmlatt.pdp.policy.RuleEffect;
+
+/**
+ * DOMRule extends {@link com.att.research.xacmlatt.pdp.policy.Rule} with methods for creation from
+ * DOM {@link org.w3c.dom.Node}s.
+ * 
+ * @author car
+ * @version $Revision: 1.3 $
+ */
+public class DOMRule extends Rule {
+	private static final Log logger	= LogFactory.getLog(DOMRule.class);
+	
+	protected DOMRule() {
+	}
+
+	/**
+	 * Creates a new <code>Rule</code> by parsing the given <code>Node</code> representing a XACML Rule element.
+	 * 
+	 * @param nodeRule the <code>Node</code> representing the XACML Rule element
+	 * @param policy the {@link com.att.research.xacmlatt.pdp.policy.Policy} encompassing the Rule element
+	 * @return a new <code>Rule</code> parsed from the given <code>Node</code>
+	 * @throws DOMStructureException if there is an error parsing the <code>Node</code>
+	 */
+	public static Rule newInstance(Node nodeRule, Policy policy) throws DOMStructureException {
+		Element elementRule	= DOMUtil.getElement(nodeRule);
+		boolean bLenient	= DOMProperties.isLenient();
+		
+		DOMRule domRule		= new DOMRule();
+		
+		domRule.setPolicy(policy);
+		
+		Iterator<?> iterator;
+		
+		try {
+			NodeList children	= elementRule.getChildNodes();
+			int numChildren;
+			if (children != null && (numChildren = children.getLength()) > 0) {
+				for (int i = 0 ; i < numChildren ; i++) {
+					Node child	= children.item(i);
+					if (DOMUtil.isElement(child)) {
+						if (DOMUtil.isInNamespace(child, XACML3.XMLNS)) {
+							String childName	= child.getLocalName();
+							if (XACML3.ELEMENT_DESCRIPTION.equals(childName)) {
+								if (domRule.getDescription() != null && !bLenient) {
+									throw DOMUtil.newUnexpectedElementException(child, nodeRule);
+								}
+								domRule.setDescription(child.getTextContent());
+							} else if (XACML3.ELEMENT_TARGET.equals(childName)) {
+								if (domRule.getTarget() != null && !bLenient) {
+									throw DOMUtil.newUnexpectedElementException(child, nodeRule);
+								}
+								domRule.setTarget(DOMTarget.newInstance(child));
+							} else if (XACML3.ELEMENT_CONDITION.equals(childName)) {
+								if (domRule.getCondition() != null && !bLenient) {
+									throw DOMUtil.newUnexpectedElementException(child, nodeRule);
+								}
+								Node nodeExpression	= DOMUtil.getFirstChildElement(child);
+								if (nodeExpression == null && !bLenient) {
+									throw DOMUtil.newMissingElementException(child, XACML3.XMLNS, XACML3.ELEMENT_EXPRESSION);
+								}
+								domRule.setCondition(new Condition(DOMExpression.newInstance(nodeExpression, policy)));
+							} else if (XACML3.ELEMENT_OBLIGATIONEXPRESSIONS.equals(childName)) {
+								if ((iterator = domRule.getObligationExpressions()) != null && iterator.hasNext() && !bLenient) {
+									throw DOMUtil.newUnexpectedElementException(child, nodeRule);
+								}
+								domRule.setObligationExpressions(DOMObligationExpression.newList(child, policy));
+							} else if (XACML3.ELEMENT_ADVICEEXPRESSIONS.equals(childName)) {
+								if ((iterator = domRule.getAdviceExpressions()) != null && iterator.hasNext() && !bLenient) {
+									throw DOMUtil.newUnexpectedElementException(child, nodeRule);
+								}
+								domRule.setAdviceExpressions(DOMAdviceExpression.newList(child, policy));
+							} else if (!bLenient) {
+								throw DOMUtil.newUnexpectedElementException(child, nodeRule);								
+							}
+						} else if (!bLenient) {
+							throw DOMUtil.newUnexpectedElementException(child, nodeRule);
+						}
+					}
+				}
+			}
+			
+			domRule.setRuleId(DOMUtil.getStringAttribute(elementRule, XACML3.ATTRIBUTE_RULEID, !bLenient));
+			String string			= DOMUtil.getStringAttribute(elementRule, XACML3.ATTRIBUTE_EFFECT, !bLenient);
+			RuleEffect ruleEffect	= RuleEffect.getRuleEffect(string);
+			if (ruleEffect == null && !bLenient) {
+				throw new DOMStructureException(elementRule, "Unknown RuleEffect \"" + string + "\" in \"" + DOMUtil.getNodeLabel(nodeRule) + "\"");
+			} 
+			domRule.setRuleEffect(ruleEffect);
+			
+		} catch (DOMStructureException ex) {
+			domRule.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+			if (DOMProperties.throwsExceptions()) {
+				throw ex;
+			}
+		}
+		return domRule;
+	}
+	
+	public static boolean repair(Node nodeRule) throws DOMStructureException {
+		Element elementRule	= DOMUtil.getElement(nodeRule);
+		boolean result		= false;
+		
+		NodeList children	= elementRule.getChildNodes();
+		int numChildren;
+		boolean sawDescription				= false;
+		boolean sawTarget					= false;
+		boolean sawCondition				= false;
+		boolean sawObligationExpressions	= false;
+		boolean sawAdviceExpressions		= false;
+		
+		if (children != null && (numChildren = children.getLength()) > 0) {
+			for (int i = 0 ; i < numChildren ; i++) {
+				Node child	= children.item(i);
+				if (DOMUtil.isElement(child)) {
+					if (DOMUtil.isInNamespace(child, XACML3.XMLNS)) {
+						String childName	= child.getLocalName();
+						if (XACML3.ELEMENT_DESCRIPTION.equals(childName)) {
+							if (sawDescription) {
+								logger.warn("Unexpected element " + child.getNodeName());
+								elementRule.removeChild(child);
+								result	= true;
+							} else {
+								sawDescription	= true;
+							}
+						} else if (XACML3.ELEMENT_TARGET.equals(childName)) {
+							if (sawTarget) {
+								logger.warn("Unexpected element " + child.getNodeName());
+								elementRule.removeChild(child);
+								result	= true;
+							} else {
+								sawTarget	= true;
+								result		= DOMTarget.repair(child) || result;
+							}
+						} else if (XACML3.ELEMENT_CONDITION.equals(childName)) {
+							if (sawCondition) {
+								logger.warn("Unexpected element " + child.getNodeName());
+								elementRule.removeChild(child);
+								result	= true;
+							} else {
+								sawCondition		= true;
+								Node nodeExpression	= DOMUtil.getFirstChildElement(child);
+								if (nodeExpression == null) {
+									throw DOMUtil.newMissingElementException(child, XACML3.XMLNS, XACML3.ELEMENT_EXPRESSION);
+								}
+								result				= DOMExpression.repair(nodeExpression) || result;
+							}
+						} else if (XACML3.ELEMENT_OBLIGATIONEXPRESSIONS.equals(childName)) {
+							if (sawObligationExpressions) {
+								logger.warn("Unexpected element " + child.getNodeName());
+								elementRule.removeChild(child);
+								result	= true;
+							} else {
+								sawObligationExpressions	= true;
+								result						= DOMObligationExpression.repairList(child) || result;
+							}
+						} else if (XACML3.ELEMENT_ADVICEEXPRESSIONS.equals(childName)) {
+							if (sawAdviceExpressions) {
+								logger.warn("Unexpected element " + child.getNodeName());
+								elementRule.removeChild(child);
+								result	= true;
+							} else {
+								sawAdviceExpressions	= true;
+								result					= DOMAdviceExpression.repairList(child) || result;
+							}
+						} else {
+							logger.warn("Unexpected element " + child.getNodeName());
+							elementRule.removeChild(child);
+							result	= true;
+						}
+					} else {
+						logger.warn("Unexpected element " + child.getNodeName());
+						elementRule.removeChild(child);
+						result	= true;
+					}
+				}
+			}
+		}
+		
+		result	= DOMUtil.repairStringAttribute(elementRule, XACML3.ATTRIBUTE_RULEID, IdentifierImpl.gensym().stringValue(), logger) || result;
+		result	= DOMUtil.repairStringAttribute(elementRule, XACML3.ATTRIBUTE_EFFECT, RuleEffect.DENY.getName(), logger) || result;
+		
+		String string			= DOMUtil.getStringAttribute(elementRule, XACML3.ATTRIBUTE_EFFECT);
+		RuleEffect ruleEffect	= RuleEffect.getRuleEffect(string);
+		if (ruleEffect == null) {
+			logger.warn("Setting invalid " + XACML3.ATTRIBUTE_EFFECT + " attribute " + string + " to " + RuleEffect.DENY.getName());
+			elementRule.setAttribute(XACML3.ATTRIBUTE_EFFECT, RuleEffect.DENY.getName());
+			result	= true;
+		} 
+
+		return result;
+	}
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMRuleCombinerParameters.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMRuleCombinerParameters.java
new file mode 100755
index 0000000..732c8b5
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMRuleCombinerParameters.java
@@ -0,0 +1,123 @@
+/*
+ *                        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.policy.dom;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.dom.DOMAttributeValue;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+import com.att.research.xacmlatt.pdp.policy.Rule;
+import com.att.research.xacmlatt.pdp.policy.TargetedCombinerParameter;
+
+/**
+ * DOMRuleCombinerParameters extends {@link com.att.research.xacmlatt.pdp.policy.TargetedCombinerParameter} with methods
+ * for creation from DOM {@link org.w3c.dom.Node}s.
+ * 
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class DOMRuleCombinerParameters extends TargetedCombinerParameter<String,Rule> {
+	private static final Log logger	= LogFactory.getLog(DOMRuleCombinerParameters.class);
+	
+	protected DOMRuleCombinerParameters() {
+	}
+
+	/**
+	 * Creates a new <code>TargetedCombinerParameter</code> for {@link com.att.research.xacmlatt.pdp.policy.Rule}s by parsing the
+	 * given <code>Node</code> representing a XACML RuleCombinerParameters element.
+	 * 
+	 * @param nodeRuleCombinerParameters the <code>Node</code> representing the XACML RuleCombinerParameters element.
+	 * @return a new <code>TargetedCombinerParameter</code> for <code>Rule</code>s parsed from the given <code>Node</code>
+	 * @throws DOMStructureException if there is an error parsing the <code>Node</code>.
+	 */
+	public static TargetedCombinerParameter<String,Rule> newInstance(Node nodeRuleCombinerParameters) throws DOMStructureException {
+		Element elementRuleCombinerParameters	= DOMUtil.getElement(nodeRuleCombinerParameters);
+		boolean bLenient						= DOMProperties.isLenient();
+		
+		DOMRuleCombinerParameters domRuleCombinerParameters	= new DOMRuleCombinerParameters();
+		
+		try {
+			NodeList children	= elementRuleCombinerParameters.getChildNodes();
+			int numChildren;
+			if (children != null && (numChildren = children.getLength()) > 0) {
+				for (int i = 0 ; i < numChildren ; i++) {
+					Node child	= children.item(i);
+					if (DOMUtil.isElement(child)) {
+						if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ATTRIBUTEVALUE.equals(child.getLocalName())) {
+							if (domRuleCombinerParameters.getAttributeValue() != null) {
+								throw DOMUtil.newUnexpectedElementException(child, nodeRuleCombinerParameters);
+							}
+							domRuleCombinerParameters.setAttributeValue(DOMAttributeValue.newInstance(child, null));
+						} else if (!bLenient) {
+							throw DOMUtil.newUnexpectedElementException(child, nodeRuleCombinerParameters);
+						}
+					}
+				}
+			}
+			if (domRuleCombinerParameters.getAttributeValue() == null && !bLenient) {
+				throw DOMUtil.newMissingElementException(nodeRuleCombinerParameters, XACML3.XMLNS, XACML3.ELEMENT_ATTRIBUTEVALUE);
+			}
+			domRuleCombinerParameters.setName(DOMUtil.getStringAttribute(elementRuleCombinerParameters, XACML3.ATTRIBUTE_PARAMETERNAME, !bLenient));
+			domRuleCombinerParameters.setTargetId(DOMUtil.getStringAttribute(elementRuleCombinerParameters, XACML3.ATTRIBUTE_RULEIDREF, !bLenient));
+		} catch (DOMStructureException ex) {
+			domRuleCombinerParameters.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+			if (DOMProperties.throwsExceptions()) {
+				throw ex;
+			}
+		}
+		return domRuleCombinerParameters;
+	}
+	
+	public static boolean repair(Node nodeRuleCombinerParameters) throws DOMStructureException {
+		Element elementRuleCombinerParameters	= DOMUtil.getElement(nodeRuleCombinerParameters);
+		boolean result							= false;
+		
+		NodeList children			= elementRuleCombinerParameters.getChildNodes();
+		int numChildren;
+		boolean sawAttributeValue	= false;
+		if (children != null && (numChildren = children.getLength()) > 0) {
+			for (int i = 0 ; i < numChildren ; i++) {
+				Node child	= children.item(i);
+				if (DOMUtil.isElement(child)) {
+					if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ATTRIBUTEVALUE.equals(child.getLocalName())) {
+						if (sawAttributeValue) {
+							logger.warn("Unexpected element " + child.getNodeName());
+							elementRuleCombinerParameters.removeChild(child);
+							result	= true;
+						} else {
+							sawAttributeValue	= true;
+							result				= result || DOMAttributeValue.repair(child);
+						}
+					} else {
+						logger.warn("Unexpected element " + child.getNodeName());
+						elementRuleCombinerParameters.removeChild(child);
+						result	= true;
+					}
+				}
+			}
+		}
+		if (!sawAttributeValue) {
+			throw DOMUtil.newMissingElementException(nodeRuleCombinerParameters, XACML3.XMLNS, XACML3.ELEMENT_ATTRIBUTEVALUE);
+		}
+		result	= result || DOMUtil.repairStringAttribute(elementRuleCombinerParameters, XACML3.ATTRIBUTE_PARAMETERNAME, "parameter", logger);
+		result	= result || DOMUtil.repairIdentifierAttribute(elementRuleCombinerParameters, XACML3.ATTRIBUTE_RULEIDREF, logger);
+
+		return result;
+	}
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMTarget.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMTarget.java
new file mode 100755
index 0000000..599dfa5
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMTarget.java
@@ -0,0 +1,102 @@
+/*
+ *                        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.policy.dom;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+import com.att.research.xacmlatt.pdp.policy.Target;
+
+/**
+ * DOMTarget extends {@link com.att.research.xacmlatt.pdp.policy.Target} with methods for creation from
+ * DOM {@link org.w3c.dom.Node}s.
+ * 
+ * @author car
+ * @version $Revision: 1.3 $
+ */
+public class DOMTarget extends Target {
+	private static final Log logger	= LogFactory.getLog(DOMTarget.class);
+	
+	/**
+	 * Creates an empty <code>DOMTarget</code>.
+	 */
+	protected DOMTarget() {
+	}
+	
+	/**
+	 * Creates a new <code>DOMTarget</code> by parsing the given <code>Node</code> representing a XACML Target element.
+	 * 
+	 * @param nodeTarget the <code>Node</code> representing the XACML Target element
+	 * @return a new <code>DOMTarget</code> parsed from the given <code>Node</code>
+	 * @throws DOMStructureException if there is an error parsing the <code>Node</code>
+	 */
+	public static Target newInstance(Node nodeTarget) throws DOMStructureException {
+		Element elementTarget	= DOMUtil.getElement(nodeTarget);
+		boolean bLenient		= DOMProperties.isLenient();
+		
+		DOMTarget domTarget		= new DOMTarget();
+		try {
+			NodeList children	= elementTarget.getChildNodes();
+			int numChildren;
+			if (children != null && (numChildren = children.getLength()) > 0) {
+				for (int i = 0 ; i < numChildren ; i++) {
+					Node child	= children.item(i);
+					if (DOMUtil.isElement(child)) {
+						if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ANYOF.equals(child.getLocalName())) {
+							domTarget.addAnyOf(DOMAnyOf.newInstance(child));
+						} else if (!bLenient) {
+							throw DOMUtil.newUnexpectedElementException(child, nodeTarget);
+						}
+					}
+				}
+			}
+		} catch (DOMStructureException ex) {
+			domTarget.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+			if (DOMProperties.throwsExceptions()) {
+				throw ex;
+			}
+		}
+		
+		return domTarget;
+	}
+	
+	public static boolean repair(Node nodeTarget) throws DOMStructureException {
+		Element elementTarget	= DOMUtil.getElement(nodeTarget);
+		boolean result			= false;
+		
+		NodeList children	= elementTarget.getChildNodes();
+		int numChildren;
+		if (children != null && (numChildren = children.getLength()) > 0) {
+			for (int i = 0 ; i < numChildren ; i++) {
+				Node child	= children.item(i);
+				if (DOMUtil.isElement(child)) {
+					if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ANYOF.equals(child.getLocalName())) {
+						result	= DOMAnyOf.repair(child) || result;
+					} else {
+						logger.warn("Unexpected element " + child.getNodeName());
+						elementTarget.removeChild(child);
+						result	= true;
+					}
+				}
+			}
+		}
+
+		return result;
+	}
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMVariableDefinition.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMVariableDefinition.java
new file mode 100755
index 0000000..d1d32f3
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMVariableDefinition.java
@@ -0,0 +1,94 @@
+/*
+ *                        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.policy.dom;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+import com.att.research.xacmlatt.pdp.policy.Policy;
+import com.att.research.xacmlatt.pdp.policy.VariableDefinition;
+
+/**
+ * DOMVariableDefinition extends {@link com.att.research.xacmlatt.pdp.policy.VariableDefinition} with methods
+ * for creation from DOM {@link org.w3c.dom.Node}s.
+ * 
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class DOMVariableDefinition extends VariableDefinition {
+	private static final Log logger	= LogFactory.getLog(DOMVariableDefinition.class);
+	
+	protected DOMVariableDefinition() {
+	}
+
+	/**
+	 * Creates a new <code>VariableDefinition</code> by parsing the given <code>Node</code> representing a XACML VariableDefinition element.
+	 * 
+	 * @param nodeVariableDefinition the <code>Node</code> representing the XACML VariableDefinition element
+	 * @param policy the <code>Policy</code> encompassing the VariableDefinition element
+	 * @return a new <code>VariableDefinition</code> parsed from the given <code>Node</code>
+	 * @throws DOMStructureException if there is an error parsing the <code>Node</code>
+	 */
+	public static VariableDefinition newInstance(Node nodeVariableDefinition, Policy policy) throws DOMStructureException {
+		Element elementVariableDefinition			= DOMUtil.getElement(nodeVariableDefinition);
+		boolean bLenient							= DOMProperties.isLenient();
+		
+		DOMVariableDefinition domVariableDefinition	= new DOMVariableDefinition();
+		
+		try {
+			Element elementExpression	= DOMUtil.getFirstChildElement(elementVariableDefinition);
+			if (elementExpression != null) {
+				if (DOMExpression.isExpression(elementExpression)) {
+					domVariableDefinition.setExpression(DOMExpression.newInstance(elementExpression, policy));
+				} else if (!bLenient) {
+					throw DOMUtil.newUnexpectedElementException(elementExpression, elementVariableDefinition);
+				}
+			} else if (!bLenient) {
+				throw DOMUtil.newMissingElementException(elementVariableDefinition, XACML3.XMLNS, XACML3.ELEMENT_EXPRESSION);
+			}
+			domVariableDefinition.setId(DOMUtil.getStringAttribute(elementVariableDefinition, XACML3.ATTRIBUTE_VARIABLEID, !bLenient));
+		} catch (DOMStructureException ex) {
+			domVariableDefinition.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+			if (DOMProperties.throwsExceptions()) {
+				throw ex;
+			}
+		}
+		return domVariableDefinition;
+	}
+	
+	public static boolean repair(Node nodeVariableDefinition) throws DOMStructureException {
+		Element elementVariableDefinition			= DOMUtil.getElement(nodeVariableDefinition);
+		boolean result								= false;
+		
+		Element elementExpression	= DOMUtil.getFirstChildElement(elementVariableDefinition);
+		if (elementExpression != null) {
+			if (DOMExpression.isExpression(elementExpression)) {
+				result	= result || DOMExpression.repair(elementExpression);
+			} else {
+				logger.warn("Unexpected element " + elementExpression.getNodeName());
+				elementVariableDefinition.removeChild(elementExpression);
+				result	= true;
+			}
+		} else {
+			throw DOMUtil.newMissingElementException(elementVariableDefinition, XACML3.XMLNS, XACML3.ELEMENT_EXPRESSION);
+		}
+		
+		result	= result || DOMUtil.repairStringAttribute(elementVariableDefinition, XACML3.ATTRIBUTE_VARIABLEID, "variable", logger);
+		return result;
+	}
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/package-info.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/package-info.java
new file mode 100755
index 0000000..f42ce1e
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/package-info.java
@@ -0,0 +1,20 @@
+/*
+ *                        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.policy.dom;
+
+/**
+ * com.att.research.xacmlatt.pdp.policy.dom contains class definitions that extend {@link com.att.research.xacmlatt.pdp.policy} classes
+ * with methods for creation from DOM {@link org.w3c.dom.Node}s.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/Apply.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/Apply.java
new file mode 100755
index 0000000..08064fd
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/Apply.java
@@ -0,0 +1,170 @@
+/*
+ *                        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.policy.expressions;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.util.FactoryException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.policy.Expression;
+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;
+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;
+import com.att.research.xacmlatt.pdp.policy.FunctionArgumentExpression;
+import com.att.research.xacmlatt.pdp.policy.FunctionDefinition;
+import com.att.research.xacmlatt.pdp.policy.FunctionDefinitionFactory;
+import com.att.research.xacmlatt.pdp.policy.PolicyDefaults;
+
+/**
+ * Apply extends {@link com.att.research.xacmlatt.pdp.policy.Expression} to implement the XACML Apply Expression element.
+ *  
+ * @author car
+ * @version $Revision: 1.3 $
+ */
+public class Apply extends Expression {
+	private Identifier functionId;
+	private FunctionDefinition functionDefinition;
+	private String description;
+	private List<Expression> arguments	= new ArrayList<Expression>();
+	
+	protected List<Expression> getArgumentList() {
+		return this.arguments;
+	}
+	
+	protected void clearArgumentList() {
+		this.getArgumentList().clear();
+	}
+	
+	public Apply(StatusCode statusCodeIn, String statusMessageIn) {
+		super(statusCodeIn, statusMessageIn);
+	}
+
+	public Apply(StatusCode statusCodeIn) {
+		super(statusCodeIn);
+	}
+
+	public Apply() {
+	}
+	
+	public Apply(Identifier functionIdIn, String descriptionIn, Collection<Expression> argumentsIn) {
+		this.functionId		= functionIdIn;
+		this.description	= descriptionIn;
+		if (argumentsIn != null) {
+			this.arguments.addAll(argumentsIn);
+		}
+	}
+	
+	public Identifier getFunctionId() {
+		return this.functionId;
+	}
+	
+	public void setFunctionId(Identifier identifier) {
+		this.functionId			= identifier;
+		this.functionDefinition	= null;
+	}
+	
+	/**
+	 * Gets and caches the {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition} matching the
+	 * <code>Identifier</code> for the FunctionId in this <code>Apply</code>.
+	 * 
+	 * @return the <code>FunctionDefinition</code> for the <code>Identifier</code> for the Function Id for this <code>Apply</code>
+	 */
+	public FunctionDefinition getFunctionDefinition() {
+		if (this.functionDefinition == null) {
+			Identifier thisFunctionId	= this.getFunctionId();
+			if (thisFunctionId != null) {
+				try {
+					this.functionDefinition	= FunctionDefinitionFactory.newInstance().getFunctionDefinition(thisFunctionId);
+				} catch (FactoryException ex) {
+					this.setStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "FactoryException getting FunctionDefinition");
+				}
+			}
+		}
+		return this.functionDefinition;
+	}
+	
+	public String getDescription() {
+		return this.description;
+	}
+	
+	public void setDescription(String string) {
+		this.description	= string;
+	}
+	
+	public Iterator<Expression> getArguments() {
+		return this.getArgumentList().iterator();
+	}
+	
+	public void setArguments(Collection<Expression> listExpressions) {
+		this.clearArgumentList();
+		if (listExpressions != null) {
+			this.addArguments(listExpressions);
+		}
+	}
+	
+	public void addArgument(Expression expression) {
+		this.getArgumentList().add(expression);
+	}
+	
+	public void addArguments(Collection<Expression> listExpressions) {
+		this.getArgumentList().addAll(listExpressions);
+	}
+
+	@Override
+	public ExpressionResult evaluate(EvaluationContext evaluationContext, PolicyDefaults policyDefaults) throws EvaluationException {
+		if (!this.validate()) {
+			return ExpressionResult.newError(new StdStatus(this.getStatusCode(), this.getStatusMessage()));
+		}
+		
+		/*
+		 * Get the FunctionDefinition
+		 */
+		FunctionDefinition thisFunctionDefinition	= this.getFunctionDefinition();
+		if (thisFunctionDefinition == null) {
+			return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Unknown Function \"" + this.getFunctionId().toString() + "\""));
+		}
+		
+		/*
+		 * Get all of the arguments and convert them into FunctionArgument objects.
+		 */
+		List<FunctionArgument> listFunctionArguments	= new ArrayList<FunctionArgument>();
+		Iterator<Expression> iterExpressionArguments	= this.getArguments();
+		if (iterExpressionArguments != null) {
+			while (iterExpressionArguments.hasNext()) {
+				listFunctionArguments.add(new FunctionArgumentExpression(iterExpressionArguments.next(), evaluationContext, policyDefaults));
+			}
+		}
+		
+		/*
+		 * Apply the FunctionDefinition to the arguments
+		 */
+		return thisFunctionDefinition.evaluate(evaluationContext, listFunctionArguments);
+	}
+
+	@Override
+	protected boolean validateComponent() {
+		if (this.getFunctionId() == null) {
+			this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing FunctionId");
+			return false;
+		} else {
+			this.setStatus(StdStatusCode.STATUS_CODE_OK, null);
+			return true;
+		}
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeDesignator.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeDesignator.java
new file mode 100755
index 0000000..2a3e530
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeDesignator.java
@@ -0,0 +1,215 @@
+/*
+ *                        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.policy.expressions;
+
+import java.util.Collection;
+
+import com.att.research.xacml.api.Attribute;
+import com.att.research.xacml.api.AttributeValue;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.MissingAttributeDetail;
+import com.att.research.xacml.api.Status;
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacml.api.StatusDetail;
+import com.att.research.xacml.api.pip.PIPException;
+import com.att.research.xacml.api.pip.PIPRequest;
+import com.att.research.xacml.api.pip.PIPResponse;
+import com.att.research.xacml.std.StdMutableMissingAttributeDetail;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.StdStatusDetail;
+import com.att.research.xacml.std.pip.StdPIPRequest;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.policy.Bag;
+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;
+import com.att.research.xacmlatt.pdp.policy.PolicyDefaults;
+
+/**
+ * AttributeDesignator extends {@link com.att.research.xacmlatt.pdp.policy.expression.AttributeRetrievalBase} to represent the
+ * XACML AttributeDesignator element.
+ * 
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class AttributeDesignator extends AttributeRetrievalBase {
+	private Identifier attributeId;
+	private String issuer;
+	private PIPRequest pipRequestCached;
+	private MissingAttributeDetail missingAttributeDetail;
+	private StatusDetail statusDetail;
+	
+	protected PIPRequest getPIPRequest() {
+		if (this.pipRequestCached == null) {
+			this.pipRequestCached	= new StdPIPRequest(this.getCategory(), this.getAttributeId(), this.getDataTypeId(), this.getIssuer());
+		}
+		return this.pipRequestCached;
+	}
+	
+	protected MissingAttributeDetail getMissingAttributeDetail() {
+		if (this.missingAttributeDetail == null) {
+			this.missingAttributeDetail	= new StdMutableMissingAttributeDetail(this.getCategory(), this.getAttributeId(), this.getDataTypeId(), this.getIssuer());
+		}
+		return this.missingAttributeDetail;
+	}
+	
+	protected StatusDetail getStatusDetail() {
+		if (this.statusDetail == null) {
+			this.statusDetail	= new StdStatusDetail(this.getMissingAttributeDetail());
+		}
+		return this.statusDetail;
+	}
+	
+	public AttributeDesignator(StatusCode statusCodeIn, String statusMessageIn) {
+		super(statusCodeIn, statusMessageIn);
+	}
+
+	public AttributeDesignator(StatusCode statusCodeIn) {
+		super(statusCodeIn);
+	}
+
+	public AttributeDesignator() {
+	}
+	
+	public Identifier getAttributeId() {
+		return this.attributeId;
+	}
+	
+	public void setAttributeId(Identifier identifierAttributeId) {
+		this.attributeId	= identifierAttributeId;
+	}
+	
+	public String getIssuer() {
+		return this.issuer;
+	}
+	
+	public void setIssuer(String issuerIn) {
+		this.issuer	= issuerIn;
+	}
+	
+	@Override
+	protected boolean validateComponent() {
+		if (!super.validateComponent()) {
+			return false;
+		} else if (this.getAttributeId() == null) {
+			this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing AttributeId");
+			return false;
+		} else {
+			return true;
+		}
+	}
+	
+	/**
+	 * Determines if the given <code>Attribute</code> has the same category, attribute id, and issuer as this
+	 * <code>AttributeDesignator</code>.
+	 * 
+	 * @param attribute the <code>Attribute</code> to test
+	 * @return true if the <code>Attribute</code> matches, else false
+	 */
+	protected boolean match(Attribute attribute) {
+		if (!this.getCategory().equals(attribute.getCategory())) {
+			return false;
+		} else if (!this.getAttributeId().equals(attribute.getAttributeId())) {
+			return false;
+		} else if (this.getIssuer() != null && !this.getIssuer().equals(attribute.getIssuer())) {
+			return false;
+		} else {
+			return true;
+		}
+	}
+	
+	/**
+	 * Determines if the given <code>AttributeValue</code> has the same data type id as this
+	 * <code>AttributeDesignator</code>.
+	 * 
+	 * @param attributeValue the <code>AttributeValue</code> to test
+	 * @return true if the <code>AttributeValue</code> maches, else false
+	 */
+	protected boolean match(AttributeValue<?> attributeValue) {
+		if (!this.getDataTypeId().equals(attributeValue.getDataTypeId())) {
+			return false;
+		} else {
+			return true;
+		}
+	}
+
+	@Override
+	public ExpressionResult evaluate(EvaluationContext evaluationContext, PolicyDefaults policyDefaults) throws EvaluationException {
+		if (!this.validate()) {
+			return ExpressionResult.newInstance(new StdStatus(this.getStatusCode(), this.getStatusMessage()));
+		}
+		
+		/*
+		 * Set up the PIPRequest representing this
+		 */
+		PIPRequest pipRequest	= this.getPIPRequest();
+		assert(pipRequest != null);
+		
+		/*
+		 * Query the evaluation context for results
+		 */
+		PIPResponse pipResponse	= null;
+		try {
+			pipResponse	= evaluationContext.getAttributes(pipRequest);
+		} catch (PIPException ex) {
+			throw new EvaluationException("PIPException getting Attributes", ex);
+		}
+		assert(pipResponse != null);
+		
+		/*
+		 * See if the request was successful
+		 */
+		Status pipStatus		= pipResponse.getStatus();
+		if (pipStatus != null && !pipStatus.getStatusCode().equals(StdStatusCode.STATUS_CODE_OK)) {
+			return ExpressionResult.newInstance(pipStatus);
+		}
+		
+		/*
+		 * See if there were any results
+		 */
+		Bag bagAttributeValues				= new Bag();
+		Collection<Attribute> listAttributes	= pipResponse.getAttributes();
+		for (Attribute attribute : listAttributes) {
+			if (this.match(attribute)) {
+				for (AttributeValue<?> attributeValue: attribute.getValues()) {
+					if (this.match(attributeValue)) {
+						bagAttributeValues.add(attributeValue);
+					}
+				}
+			}		
+		}
+		if (this.getMustBePresent() && bagAttributeValues.size() == 0) {
+			return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE, "Missing required attribute", new StdStatusDetail(this.getMissingAttributeDetail())));
+		} else {
+			return ExpressionResult.newBag(bagAttributeValues);
+		}
+	}
+	
+	@Override
+	public String toString() {
+		StringBuilder stringBuilder	= new StringBuilder("{");
+		
+		stringBuilder.append("super=");
+		stringBuilder.append(super.toString());
+		
+		Object objectToDump;
+		if ((objectToDump = this.getAttributeId()) != null) {
+			stringBuilder.append(",attributeId=");
+			stringBuilder.append(objectToDump.toString());
+		}
+		if ((objectToDump = this.getIssuer()) != null) {
+			stringBuilder.append(",issuer=");
+			stringBuilder.append((String)objectToDump);
+		}
+		stringBuilder.append('}');
+		return stringBuilder.toString();
+	}
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeRetrievalBase.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeRetrievalBase.java
new file mode 100755
index 0000000..21ac724
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeRetrievalBase.java
@@ -0,0 +1,170 @@
+/*
+ *                        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.policy.expressions;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacml.api.StatusDetail;
+import com.att.research.xacml.api.XACML;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.datatypes.DataTypes;
+import com.att.research.xacmlatt.pdp.policy.Expression;
+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;
+
+/**
+ * AttributeRetrievalBase extends {@link com.att.research.xacmlatt.pdp.policy.PolicyComponent} and
+ * implements {@link com.att.research.xacmlatt.pdp.eval.Evaluatable} to serve as an abstract base class
+ * for the {@link com.att.research.xacmlatt.pdp.policy.AttributeSelector} and {@link com.att.research.xacmlatt.pdp.policy.AttributeDesignator}
+ * classes.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public abstract class AttributeRetrievalBase extends Expression {
+	private Identifier	category;
+	private Identifier	dataTypeId;
+	private Boolean		mustBePresent;
+	
+	protected AttributeRetrievalBase(StatusCode statusCodeIn,
+			String statusMessageIn) {
+		super(statusCodeIn, statusMessageIn);
+	}
+
+	protected AttributeRetrievalBase(StatusCode statusCodeIn) {
+		super(statusCodeIn);
+	}
+
+	protected AttributeRetrievalBase() {
+	}
+	
+	protected AttributeRetrievalBase(Identifier categoryIn, Identifier dataTypeIdIn, Boolean mustBePresentIn) {
+		this.category		= categoryIn;
+		this.dataTypeId		= dataTypeIdIn;
+		this.mustBePresent	= mustBePresentIn;
+	}
+
+	/**
+	 * Gets the {@link com.att.research.xacml.api.Identifier} for the category associated with this
+	 * <code>AttributeRetrievalBase</code>.
+	 * 
+	 * @return the <code>Identifier</code> for the category of this <code>AttributeRetrievalBase</code>.
+	 */
+	public Identifier getCategory() {
+		return this.category;
+	}
+	
+	/**
+	 * Sets the <code>Identifier</code> for the category associated with this <code>AttributeRetrievalBase</code>.
+	 * 
+	 * @param categoryIn the <code>Identifier</code> for the category associated with this <code>AttributeRetrievalBase</code>
+	 */
+	public void setCategory(Identifier categoryIn) {
+		this.category	= categoryIn;
+	}
+	
+	/**
+	 * Gets the <code>Identifier</code> for the data type associated with this <code>AttributeRetrievalBase</code>.
+	 * 
+	 * @return the <code>Identifier</code> for the data type associated with this <code>AttributeRetrievalBase</code>
+	 */
+	public Identifier getDataTypeId() {
+		return this.dataTypeId;
+	}
+	
+	/**
+	 * Sets the <code>Identifier</code> for the data type associated with this <code>AttributeRetrievalBase</code>.
+	 * 
+	 * @param dataTypeIn the <code>Identifier</code> for the data type associated with this <code>AttributeRetrievalBase</code>
+	 */
+	public void setDataTypeId(Identifier dataTypeIn) {
+		// allow old-style Ids for Durations since there is no structural or semantic changes, just a different Id.
+		if (dataTypeIn.equals(XACML.ID_DATATYPE_WD_DAYTIMEDURATION)) {
+			dataTypeIn	= DataTypes.DT_DAYTIMEDURATION.getId();
+		} else if (dataTypeIn.equals(XACML.ID_DATATYPE_WD_YEARMONTHDURATION)) {
+			dataTypeIn	= DataTypes.DT_YEARMONTHDURATION.getId();
+		}
+		this.dataTypeId	= dataTypeIn;
+	}
+	
+	/**
+	 * Determines if a value must be found for this <code>AttributeRetrievalBase</code> when it is evaluated.  If true,
+	 * and no value is found, an indeterminate result is returned, otherwise an empty bag is returned.
+	 * 
+	 * @return true if the value of this <code>AttributeRetrievalBase</code> must be found, else false
+	 */
+	public Boolean getMustBePresent() {
+		return this.mustBePresent;
+	}
+	
+	/**
+	 * Sets the flag indicating whether a value must be found for this <code>AttributeRetrievalBase</code>.
+	 * 
+	 * @param b the boolean value for the flag
+	 */
+	public void setMustBePresent(boolean b) {
+		this.mustBePresent	= b;
+	}
+
+	@Override
+	protected boolean validateComponent() {
+		if (this.getCategory() == null) {
+			this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing Category");
+			return false;
+		} else if (this.getDataTypeId() == null) {
+			this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing DataType");
+			return false;
+		} else if (this.getMustBePresent() == null) {
+			this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing MustBePresent");
+			return false;
+		} else {
+			this.setStatus(StdStatusCode.STATUS_CODE_OK, null);
+			return true;
+		}
+	}
+	
+	@Override public String toString() {
+		StringBuilder stringBuilder	= new StringBuilder("{");
+		stringBuilder.append("super=");
+		stringBuilder.append(super.toString());
+		
+		Object objectToDump;
+		if ((objectToDump = this.getCategory()) != null) {
+			stringBuilder.append(",category=");
+			stringBuilder.append(objectToDump.toString());
+		}
+		if ((objectToDump = this.getDataTypeId()) != null) {
+			stringBuilder.append(",dataType=");
+			stringBuilder.append(objectToDump.toString());
+		}
+		if ((objectToDump = this.getMustBePresent()) != null) {
+			stringBuilder.append(",mustBePresent=");
+			stringBuilder.append(objectToDump.toString());
+		}
+		stringBuilder.append('}');
+		return stringBuilder.toString();
+	}
+
+	/**
+	 * Creates the appropriate {@link com.att.research.xacmlatt.pdp.policy.ExpressionResult} for an empty list based
+	 * on the <code>getMustBePresent</code> value.
+	 * 
+	 * @return an appropriate <code>ExpressionResult</code>
+	 */
+	protected ExpressionResult getEmptyResult(String statusMessage, StatusDetail statusDetail) {
+		if (this.getMustBePresent() != null && this.getMustBePresent().booleanValue()) {
+			return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE, statusMessage, statusDetail));
+		} else {
+			return ExpressionResult.newEmpty();
+		}
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeSelector.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeSelector.java
new file mode 100755
index 0000000..d5f94e2
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeSelector.java
@@ -0,0 +1,283 @@
+/*
+ *                        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.policy.expressions;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+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.Request;
+import com.att.research.xacml.api.RequestAttributes;
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.datatypes.DataTypes;
+import com.att.research.xacml.std.datatypes.NodeNamespaceContext;
+import com.att.research.xacml.std.datatypes.XPathExpressionWrapper;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+import com.att.research.xacml.util.FactoryException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.policy.Bag;
+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;
+import com.att.research.xacmlatt.pdp.policy.PolicyDefaults;
+
+/**
+ * AttributeSelector extends {@link com.att.research.xacmlatt.pdp.policy.expressions.AttributeRetrievalBase} to implement
+ * the XACML AttributeSelector element.
+ * 
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class AttributeSelector extends AttributeRetrievalBase {
+	private Identifier 		contextSelectorId;
+	private String			path;
+	@SuppressWarnings("unused")
+	private DataType<?> 	dataType;
+	
+	protected DataType<?> getDataType() {
+		Identifier dataTypeIdThis	= this.getDataTypeId();
+		if (dataTypeIdThis == null) {
+			return null;
+		} else {
+			DataTypeFactory dataTypeFactory		= null;
+			try {
+				dataTypeFactory	= DataTypeFactory.newInstance();
+				if (dataTypeFactory == null) {
+					return null;
+				}
+			} catch (FactoryException ex) {
+				return null;
+			}
+			return (this.dataType	= dataTypeFactory.getDataType(dataTypeIdThis));
+		}
+	}
+
+	public AttributeSelector(StatusCode statusCodeIn, String statusMessageIn) {
+		super(statusCodeIn, statusMessageIn);
+	}
+
+	public AttributeSelector(StatusCode statusCodeIn) {
+		super(statusCodeIn);
+	}
+
+	public AttributeSelector() {
+	}
+	
+	public Identifier getContextSelectorId() {
+		return this.contextSelectorId;
+	}
+	
+	public void setContextSelectorId(Identifier identifier) {
+		this.contextSelectorId	= identifier;
+	}
+	
+	public String getPath() {
+		return this.path;
+	}
+	
+	public void setPath(String pathIn) {
+		this.path	= pathIn;
+	}
+	
+	@Override
+	protected boolean validateComponent() {
+		if (!super.validateComponent()) {
+			return false;
+		} else if (this.getPath() == null) {
+			this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing Path");
+			return false;
+		} else {
+			return true;
+		}
+	}
+	
+	/**
+	 * If there is a context selector ID, get the attributes from the given <code>RequestAttributes</code> with that
+	 * ID, ensure they are <code>XPathExpression</code>s and return them.
+	 * 
+	 * @param requestAttributes
+	 * @return
+	 */
+	protected List<XPathExpression> getContextSelectorValues(RequestAttributes requestAttributes) {
+		Identifier thisContextSelectorId	= this.getContextSelectorId();
+		if (thisContextSelectorId == null) {
+			return null;
+		}
+		List<XPathExpression> listXPathExpressions	= null;
+		Iterator<Attribute> iterAttributes	= requestAttributes.getAttributes(thisContextSelectorId);
+		if (iterAttributes != null) {
+			while (iterAttributes.hasNext()) {
+				Attribute attribute	= iterAttributes.next();
+				Iterator<AttributeValue<XPathExpressionWrapper>> iterXPathExpressions	= attribute.findValues(DataTypes.DT_XPATHEXPRESSION);
+				if (iterXPathExpressions != null && iterXPathExpressions.hasNext()) {
+					if (listXPathExpressions == null) {
+						listXPathExpressions	= new ArrayList<XPathExpression>();
+					}
+					listXPathExpressions.add(iterXPathExpressions.next().getValue());
+				}
+			}
+		}
+		return listXPathExpressions;
+	}
+
+	@Override
+	public ExpressionResult evaluate(EvaluationContext evaluationContext, PolicyDefaults policyDefaults) throws EvaluationException {
+		if (!this.validate()) {
+			return ExpressionResult.newError(new StdStatus(this.getStatusCode(), this.getStatusMessage()));
+		}
+		
+		/*
+		 * Get the DataType for this AttributeSelector for converting the resulting nodes into AttributeValues
+		 */
+		DataType<?> thisDataType	= this.getDataType();
+		
+		/*
+		 * Get the Request so we can find the XPathExpression to locate the root node and to find the Content element
+		 * of the requested category.
+		 */
+		Request request	= evaluationContext.getRequest();
+		assert(request != null);
+		
+		/*
+		 * Get the RequestAttributes objects for our Category.  If none are found, then we abort quickly with either
+		 * an empty or indeterminate result.
+		 */
+		Iterator<RequestAttributes> iterRequestAttributes	= request.getRequestAttributes(this.getCategory());
+		if (iterRequestAttributes == null || !iterRequestAttributes.hasNext()) {
+			return this.getEmptyResult("No Attributes with Category " + this.getCategory().toString(), null);
+		}
+		
+		/*
+		 * Section 5.30 of the XACML 3.0 specification is a little vague about how to use the
+		 * ContextSelectorId in the face of having multiple Attributes elements with the same CategoryId.  My interpretation
+		 * is that each is distinct, so we look for an attribute matching the ContextSelectorId in each matching Attributes element
+		 * and use that to search the Content in that particular Attributes element.  If either an Attribute matching the context selector id
+		 * is not found or there is no Content, then that particular Attributes element is skipped.
+		 */
+		Bag bagAttributeValues						= new Bag();
+		StdStatus statusFirstError					= null;
+		while (iterRequestAttributes.hasNext()) {
+			RequestAttributes requestAttributes	= iterRequestAttributes.next();
+			
+			/*
+			 * See if we have a Content element to query.
+			 */
+			Node nodeContentRoot	= requestAttributes.getContentRoot();
+			if (nodeContentRoot != null) {
+				List<Node> listNodesToQuery					= new ArrayList<Node>();
+				List<XPathExpression> listXPathExpressions	= this.getContextSelectorValues(requestAttributes);
+				if (listXPathExpressions == null) {
+					listNodesToQuery.add(nodeContentRoot);
+				} else {
+					Iterator<XPathExpression> iterXPathExpressions	= listXPathExpressions.iterator();
+					while (iterXPathExpressions.hasNext()) {
+						XPathExpression xpathExpression	= iterXPathExpressions.next();
+						Node nodeContent	= requestAttributes.getContentNodeByXpathExpression(xpathExpression);
+						if (nodeContent != null) {
+							listNodesToQuery.add(nodeContent);
+						}
+					}
+				}
+				
+				/*
+				 * If there are any nodes to query, do so now and add the results
+				 */
+				if (listNodesToQuery.size() > 0) {
+					for (Node nodeToQuery : listNodesToQuery) {
+						NodeList nodeList	= null;
+						try {
+							XPath xPath	= XPathFactory.newInstance().newXPath();
+							xPath.setNamespaceContext(new NodeNamespaceContext(nodeToQuery.getOwnerDocument()));
+							XPathExpression xPathExpression	= xPath.compile(this.getPath());
+							Node nodeToQueryDocumentRoot	= null;
+							try {
+								nodeToQueryDocumentRoot	= DOMUtil.getDirectDocumentChild(nodeToQuery);
+							} catch (DOMStructureException ex) {
+								return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Exception processing context node: " + ex.getMessage()));
+							}
+							nodeList	= (NodeList)xPathExpression.evaluate(nodeToQueryDocumentRoot, XPathConstants.NODESET);
+						} catch (XPathExpressionException ex) {
+							if (statusFirstError == null) {
+								statusFirstError	= new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "XPathExpressionException: " + ex.getMessage());
+							}
+						}
+						if (nodeList != null && nodeList.getLength() > 0) {
+							for (int i = 0 ; i < nodeList.getLength() ; i++) {
+								AttributeValue<?> attributeValueNode	= null;
+								try {
+									attributeValueNode	= thisDataType.createAttributeValue(nodeList.item(i));
+								} catch (DataTypeException ex) {
+									if (statusFirstError == null) {
+										statusFirstError	= new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, ex.getMessage());
+									}
+								}
+								if (attributeValueNode != null) {
+									bagAttributeValues.add(attributeValueNode);
+								} else if (statusFirstError == null) {
+									statusFirstError	= new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Unable to convert node to " + this.getDataTypeId().toString());
+								}
+							}
+						}
+					}
+				}
+			}
+			
+		}
+		
+		if (bagAttributeValues.size() == 0) {
+			if (statusFirstError == null) {
+				return this.getEmptyResult("No Content found", null);
+			} else {
+				return ExpressionResult.newError(statusFirstError);
+			}
+		} else {
+			return ExpressionResult.newBag(bagAttributeValues);
+		}
+	}
+	
+	@Override
+	public String toString() {
+		StringBuilder stringBuilder	= new StringBuilder("{");
+		
+		stringBuilder.append("super=");
+		stringBuilder.append(super.toString());
+		
+		Object objectToDump;
+		if ((objectToDump = this.getContextSelectorId()) != null) {
+			stringBuilder.append(",contextSelectorId=");
+			stringBuilder.append(objectToDump.toString());
+		}
+		if ((objectToDump = this.getPath()) != null) {
+			stringBuilder.append(",path=");
+			stringBuilder.append((String)objectToDump);
+		}
+		stringBuilder.append('}');
+		return stringBuilder.toString();
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeValueExpression.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeValueExpression.java
new file mode 100755
index 0000000..73cf5b8
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeValueExpression.java
@@ -0,0 +1,89 @@
+/*
+ *                        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.policy.expressions;
+
+import com.att.research.xacml.api.AttributeValue;
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.policy.Expression;
+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;
+import com.att.research.xacmlatt.pdp.policy.PolicyDefaults;
+
+/**
+ * AttributeValueExpression extends {@link com.att.research.xacmlatt.pdp.policy.Expression} to represent XACML
+ * AttributeValue elements in an Expression context.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class AttributeValueExpression extends Expression {
+	private AttributeValue<?> attributeValue;
+	
+	public AttributeValueExpression(StatusCode statusCodeIn, String statusMessageIn) {
+		super(statusCodeIn, statusMessageIn);
+	}
+
+	public AttributeValueExpression(StatusCode statusCodeIn) {
+		super(statusCodeIn);
+	}
+
+	public AttributeValueExpression() {
+	}
+	
+	public AttributeValueExpression(AttributeValue<?> attributeValueIn) {
+		this.attributeValue	= attributeValueIn;
+	}
+	
+	public AttributeValue<?> getAttributeValue() {
+		return this.attributeValue;
+	}
+	
+	public void setAttributeValue(AttributeValue<?> attributeValueIn) {
+		this.attributeValue	= attributeValueIn;
+	}
+	
+	@Override
+	public ExpressionResult evaluate(EvaluationContext evaluationContext, PolicyDefaults policyDefaults) throws EvaluationException {
+		if (!this.validate()) {
+			return ExpressionResult.newError(new StdStatus(this.getStatusCode(), this.getStatusMessage()));
+		}
+		
+		return ExpressionResult.newSingle(this.getAttributeValue());
+	}
+
+	@Override
+	protected boolean validateComponent() {
+		if (this.getAttributeValue() == null) {
+			this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing AttributeValue");
+			return false;
+		} else {
+			this.setStatus(StdStatusCode.STATUS_CODE_OK, null);
+			return true;
+		}
+	}
+	
+	@Override
+	public String toString() {
+		StringBuilder stringBuilder	= new StringBuilder("{");
+		
+		Object objectToDump;
+		if ((objectToDump = this.getAttributeValue()) != null) {
+			stringBuilder.append("attributeValue=");
+			stringBuilder.append(objectToDump.toString());
+		}
+		stringBuilder.append('}');
+		return stringBuilder.toString();
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/Function.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/Function.java
new file mode 100755
index 0000000..16cf506
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/Function.java
@@ -0,0 +1,105 @@
+/*
+ *                        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.policy.expressions;
+
+import java.net.URI;
+
+import com.att.research.xacml.api.AttributeValue;
+import com.att.research.xacml.api.DataTypeException;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.datatypes.DataTypes;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.policy.Expression;
+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;
+import com.att.research.xacmlatt.pdp.policy.PolicyDefaults;
+
+/**
+ * Function extends {@link com.att.research.xacmlatt.pdp.policy.Expression} to implement the XACML Function element.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class Function extends Expression {
+	private Identifier functionId;
+	private AttributeValue<URI> attributeValue;
+	private ExpressionResult expressionResultOk;
+	
+	protected ExpressionResult getExpressionResultOk() {
+		if (this.expressionResultOk == null) {
+			this.expressionResultOk	= ExpressionResult.newSingle(this.getAttributeValue());
+		}
+		return this.expressionResultOk;
+	}
+	
+	public Function(StatusCode statusCodeIn, String statusMessageIn) {
+		super(statusCodeIn, statusMessageIn);
+	}
+
+	public Function(StatusCode statusCodeIn) {
+		super(statusCodeIn);
+	}
+
+	public Function() {
+	}
+	
+	public Function(Identifier functionIdIn) {
+		this.functionId	= functionIdIn;
+	}
+	
+	public Identifier getFunctionId() {
+		return this.functionId;
+	}
+	
+	public void setFunctionId(Identifier identifier) {
+		this.functionId	= identifier;
+		this.attributeValue	= null;
+		this.expressionResultOk	= null;
+	}
+	
+	public AttributeValue<URI> getAttributeValue() {
+		if (this.attributeValue == null) {
+			Identifier thisFunctionId	= this.getFunctionId();
+			if (thisFunctionId != null) {
+				try {
+					this.attributeValue	= DataTypes.DT_ANYURI.createAttributeValue(thisFunctionId);
+				} catch (DataTypeException ex) {
+					this.attributeValue	= null;
+				}
+			}
+		}
+		return this.attributeValue;
+	}
+
+	@Override
+	public ExpressionResult evaluate(EvaluationContext evaluationContext, PolicyDefaults policyDefaults) throws EvaluationException {
+		if (!this.validate()) {
+			return ExpressionResult.newError(new StdStatus(this.getStatusCode(), this.getStatusMessage()));
+		} else {
+			return this.getExpressionResultOk();
+		}
+	}
+
+	@Override
+	protected boolean validateComponent() {
+		if (this.getFunctionId() == null) {
+			this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing FunctionId");
+			return false;
+		} else {
+			this.setStatus(StdStatusCode.STATUS_CODE_OK, null);
+			return true;
+		}
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/VariableReference.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/VariableReference.java
new file mode 100755
index 0000000..be322e9
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/VariableReference.java
@@ -0,0 +1,149 @@
+/*
+ *                        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.policy.expressions;
+
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacml.api.trace.Traceable;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.trace.StdTraceEvent;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.policy.Expression;
+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;
+import com.att.research.xacmlatt.pdp.policy.Policy;
+import com.att.research.xacmlatt.pdp.policy.PolicyDefaults;
+import com.att.research.xacmlatt.pdp.policy.VariableDefinition;
+
+/**
+ * VariableReference extends {@link com.att.research.xacmlatt.pdp.policy.Expression} to implement the XACML VariableReference
+ * element.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class VariableReference extends Expression implements Traceable {
+	private static final ExpressionResult ER_SE_NO_EXPRESSION	= ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing Expression for VariableDefinition"));
+	
+	private Policy policy;
+	private String variableId;
+	private VariableDefinition variableDefinition;
+	
+	protected VariableDefinition getVariableDefinition() {
+		if (this.variableDefinition == null) {
+			Policy thisPolicy	= this.getPolicy();
+			if (thisPolicy != null) {
+				String thisVariableId	= this.getVariableId();
+				if (thisVariableId != null) {
+					this.variableDefinition	= thisPolicy.getVariableDefinition(thisVariableId);
+				}
+			}
+		}
+		return this.variableDefinition;
+	}
+	
+	public VariableReference(StatusCode statusCodeIn, String statusMessageIn) {
+		super(statusCodeIn, statusMessageIn);
+	}
+
+	public VariableReference(StatusCode statusCodeIn) {
+		super(statusCodeIn);
+	}
+
+	public VariableReference() {
+	}
+	
+	public VariableReference(Policy policyIn, String variableIdIn) {
+		this.policy		= policyIn;
+		this.variableId	= variableIdIn;
+	}
+	
+	public Policy getPolicy() {
+		return this.policy;
+	}
+	
+	public void setPolicy(Policy policyIn) {
+		this.policy	= policyIn;
+	}
+	
+	public String getVariableId() {
+		return this.variableId;
+	}
+	
+	public void setVariableId(String variableIdIn) {
+		this.variableId	= variableIdIn;
+	}
+
+	@Override
+	public ExpressionResult evaluate(EvaluationContext evaluationContext, PolicyDefaults policyDefaults) throws EvaluationException {
+		if (!this.validate()) {
+			return ExpressionResult.newError(new StdStatus(this.getStatusCode(), this.getStatusMessage()));
+		}
+		
+		VariableDefinition variableDefinition	= this.getVariableDefinition();
+		if (variableDefinition == null) {
+			return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "No VariableDefinition found for \"" + this.getVariableId() + "\""));
+		}
+		Expression expression					= variableDefinition.getExpression();
+		if (expression == null) {
+			return ER_SE_NO_EXPRESSION;
+		}
+		
+		ExpressionResult result = expression.evaluate(evaluationContext, policyDefaults);
+		
+		if (evaluationContext.isTracing()) {
+			evaluationContext.trace(new StdTraceEvent<ExpressionResult>("Variable", this, result));
+		}
+		
+		return result;
+	}
+
+	@Override
+	protected boolean validateComponent() {
+		if (this.getVariableId() == null) {
+			this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing VariableId");
+			return false;
+		} else if (this.getPolicy() == null) {
+			this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "VariableReference not in a Policy");
+			return false;
+		} else {
+			this.setStatus(StdStatusCode.STATUS_CODE_OK, null);
+			return true;
+		}
+	}
+	
+	@Override
+	public String toString() {
+		StringBuilder stringBuilder	= new StringBuilder("{");
+		
+		stringBuilder.append("super=");
+		stringBuilder.append(super.toString());
+		
+		String stringToDump;
+		if ((stringToDump = this.getVariableId()) != null) {
+			stringBuilder.append(",variableId=");
+			stringBuilder.append(stringToDump);
+		}
+		stringBuilder.append('}');
+		return stringBuilder.toString();
+	}
+
+	@Override
+	public String getTraceId() {
+		return this.variableId;
+	}
+
+	@Override
+	public Traceable getCause() {
+		return this.policy;
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/package-info.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/package-info.java
new file mode 100755
index 0000000..0abd0ec
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/package-info.java
@@ -0,0 +1,20 @@
+/*
+ *                        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.policy.expressions;
+
+/**
+ * com.att.research.xacmlatt.pdp.policy.expressions contains class definitions that represent specific XACML elements sub-typed from
+ * the Expression element.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/package-info.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/package-info.java
new file mode 100755
index 0000000..bb4a5ba
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/package-info.java
@@ -0,0 +1,20 @@
+/*
+ *                        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.policy;
+
+/**
+ * com.att.research.xacmlatt.pdp.policy contains class definitions that represent a XACML 3.0 Policy such that it can be
+ * used to implement the {@link com.att.research.xacml.pdp.PDPEngine} <code>decide</code> method.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithmFactory.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithmFactory.java
new file mode 100755
index 0000000..9312e31
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithmFactory.java
@@ -0,0 +1,89 @@
+/*
+ *                        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.std;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacmlatt.pdp.policy.CombiningAlgorithm;
+import com.att.research.xacmlatt.pdp.policy.CombiningAlgorithmFactory;
+import com.att.research.xacmlatt.pdp.policy.PolicySetChild;
+import com.att.research.xacmlatt.pdp.policy.Rule;
+
+/**
+ * StdCombiningAlgorithmFactory extends {@link com.att.research.xacmlatt.pdp.policy.CombiningAlgorithmFactory} to implement
+ * a mapping from {@link com.att.research.xacml.api.Identifier}s to 
+ * the standard {@link com.att.research.xacmlatt.pdp.policy.CombiningAlgorithm} implementations.
+ * 
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class StdCombiningAlgorithmFactory extends CombiningAlgorithmFactory {
+	private static Map<Identifier,CombiningAlgorithm<Rule>> 				mapRuleCombiningAlgorithms	
+		= new HashMap<Identifier,CombiningAlgorithm<Rule>>();
+	private static Map<Identifier,CombiningAlgorithm<PolicySetChild>> 		mapPolicyCombiningAlgorithms	
+		= new HashMap<Identifier,CombiningAlgorithm<PolicySetChild>>();
+	private static boolean needInit	= true;
+	
+	protected static void registerRuleCombiningAlgorithm(CombiningAlgorithm<Rule> ruleCombiningAlgorithm) {
+		mapRuleCombiningAlgorithms.put(ruleCombiningAlgorithm.getId(), ruleCombiningAlgorithm);
+	}
+	
+	protected static void registerPolicyCombiningAlgorithm(CombiningAlgorithm<PolicySetChild> policyCombiningAlgorithm) {
+		mapPolicyCombiningAlgorithms.put(policyCombiningAlgorithm.getId(), policyCombiningAlgorithm);
+	}
+	
+	@SuppressWarnings("unchecked")
+	private static void initMap() {
+		if (needInit) {
+			synchronized(mapRuleCombiningAlgorithms) {
+				if (needInit) {
+					needInit	= false;
+					Field[]	declaredFields	= StdCombiningAlgorithms.class.getFields();
+					for (Field field : declaredFields) {
+						if (Modifier.isStatic(field.getModifiers()) &&
+							Modifier.isPublic(field.getModifiers()) &&
+							field.getName().startsWith(StdCombiningAlgorithms.PREFIX_CA) &&
+							CombiningAlgorithm.class.isAssignableFrom(field.getType())
+								) {
+							try {
+								if (field.getName().startsWith(StdCombiningAlgorithms.PREFIX_RULE)) {
+									registerRuleCombiningAlgorithm((CombiningAlgorithm<Rule>)field.get(null));
+								} else if (field.getName().startsWith(StdCombiningAlgorithms.PREFIX_POLICY)) {
+									registerPolicyCombiningAlgorithm((CombiningAlgorithm<PolicySetChild>)field.get(null));
+								}
+							} catch (IllegalAccessException ex) {
+								
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+	
+	public StdCombiningAlgorithmFactory() {
+		initMap();
+	}
+
+	@Override
+	public CombiningAlgorithm<Rule> getRuleCombiningAlgorithm(Identifier combiningAlgorithmId) {
+		return mapRuleCombiningAlgorithms.get(combiningAlgorithmId);
+	}
+
+	@Override
+	public CombiningAlgorithm<PolicySetChild> getPolicyCombiningAlgorithm(Identifier combiningAlgorithmId) {
+		return mapPolicyCombiningAlgorithms.get(combiningAlgorithmId);
+	}	
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithms.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithms.java
new file mode 100755
index 0000000..450c1f2
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithms.java
@@ -0,0 +1,125 @@
+/*
+ *                        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.std;
+
+import com.att.research.xacml.api.XACML1;
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacmlatt.pdp.policy.CombiningAlgorithm;
+import com.att.research.xacmlatt.pdp.policy.PolicySetChild;
+import com.att.research.xacmlatt.pdp.policy.Rule;
+import com.att.research.xacmlatt.pdp.std.combiners.CombinedPermitOverrides;
+import com.att.research.xacmlatt.pdp.std.combiners.DenyOverrides;
+import com.att.research.xacmlatt.pdp.std.combiners.DenyUnlessPermit;
+import com.att.research.xacmlatt.pdp.std.combiners.FirstApplicable;
+import com.att.research.xacmlatt.pdp.std.combiners.LegacyDenyOverridesPolicy;
+import com.att.research.xacmlatt.pdp.std.combiners.LegacyDenyOverridesRule;
+import com.att.research.xacmlatt.pdp.std.combiners.LegacyPermitOverridesPolicy;
+import com.att.research.xacmlatt.pdp.std.combiners.LegacyPermitOverridesRule;
+import com.att.research.xacmlatt.pdp.std.combiners.OnlyOneApplicable;
+import com.att.research.xacmlatt.pdp.std.combiners.PermitOverrides;
+import com.att.research.xacmlatt.pdp.std.combiners.PermitUnlessDeny;
+import com.att.research.xacmlatt.pdp.util.ATTPDPProperties;
+
+/**
+ * StdCombiningAlgorithms contains single instances of each of the {@link com.att.research.xacmlatt.pdp.policy.CombiningAlgorithm}
+ * implementations in the {@link com.att.research.xacmlatt.pdp.std.combiners} package.
+ * 
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class StdCombiningAlgorithms {
+
+	protected StdCombiningAlgorithms() {
+	}
+	
+	public static final String	PREFIX_CA		= "CA_";
+	public static final String	PREFIX_RULE		= PREFIX_CA + "RULE_";
+	public static final String	PREFIX_POLICY	= PREFIX_CA + "POLICY_";
+
+	// C.2 Deny-overrides
+	public static final CombiningAlgorithm<Rule> CA_RULE_DENY_OVERRIDES				
+		= new DenyOverrides<Rule>(XACML3.ID_RULE_DENY_OVERRIDES);
+	public static final CombiningAlgorithm<PolicySetChild> CA_POLICY_DENY_OVERRIDES	
+		= new DenyOverrides<PolicySetChild>(XACML3.ID_POLICY_DENY_OVERRIDES);
+	
+	// C.3 Ordered-deny-overrides
+	public static final CombiningAlgorithm<Rule> CA_RULE_ORDERED_DENY_OVERRIDES
+		= new DenyOverrides<Rule>(XACML3.ID_RULE_ORDERED_DENY_OVERRIDES);
+	public static final CombiningAlgorithm<PolicySetChild> CA_POLICY_ORDERED_DENY_OVERRIDES
+		= new DenyOverrides<PolicySetChild>(XACML3.ID_POLICY_ORDERED_DENY_OVERRIDES);
+	
+	// C.4 Permit-overrides
+	public static final CombiningAlgorithm<Rule> CA_RULE_PERMIT_OVERRIDES				
+		= new PermitOverrides<Rule>(XACML3.ID_RULE_PERMIT_OVERRIDES);
+	public static final CombiningAlgorithm<PolicySetChild> CA_POLICY_PERMIT_OVERRIDES	
+		= new PermitOverrides<PolicySetChild>(XACML3.ID_POLICY_PERMIT_OVERRIDES);
+	
+	// C.5 Ordered-permit-overrides
+	public static final CombiningAlgorithm<Rule> CA_RULE_ORDERED_PERMIT_OVERRIDES
+		= new PermitOverrides<Rule>(XACML3.ID_RULE_ORDERED_PERMIT_OVERRIDES);
+	public static final CombiningAlgorithm<PolicySetChild> CA_POLICY_ORDERED_PERMIT_OVERRIDES
+		= new PermitOverrides<PolicySetChild>(XACML3.ID_POLICY_ORDERED_PERMIT_OVERRIDES);
+	
+	// C.6 Deny-unless-permit
+	public static final CombiningAlgorithm<Rule> CA_RULE_DENY_UNLESS_PERMIT
+		= new DenyUnlessPermit<Rule>(XACML3.ID_RULE_DENY_UNLESS_PERMIT);
+	public static final CombiningAlgorithm<PolicySetChild> CA_POLICY_DENY_UNLESS_PERMIT
+		= new DenyUnlessPermit<PolicySetChild>(XACML3.ID_POLICY_DENY_UNLESS_PERMIT);
+	
+	// C.7 Permit-unles-deny
+	public static final CombiningAlgorithm<Rule> CA_RULE_PERMIT_UNLESS_DENY
+		= new PermitUnlessDeny<Rule>(XACML3.ID_RULE_PERMIT_UNLESS_DENY);
+	public static final CombiningAlgorithm<PolicySetChild> CA_POLICY_PERMIT_UNLESS_DENY
+		= new PermitUnlessDeny<PolicySetChild>(XACML3.ID_POLICY_PERMIT_UNLESS_DENY);
+	
+	// C.8 First-applicable
+	public static final CombiningAlgorithm<Rule> CA_RULE_FIRST_APPLICABLE
+		= new FirstApplicable<Rule>(XACML1.ID_RULE_FIRST_APPLICABLE);
+	public static final CombiningAlgorithm<PolicySetChild> CA_POLICY_FIRST_APPLICABLE
+		= new FirstApplicable<PolicySetChild>(XACML1.ID_POLICY_FIRST_APPLICABLE);
+	
+	// C.9 Only-one-applicable
+	//public static final CombiningAlgorithm<Rule> CA_RULE_ONLY_ONE_APPLICABLE
+	//	= new OnlyOneApplicable<Rule>(XACML1.ID_RULE_ONLY_ONE_APPLICABLE);
+	public static final CombiningAlgorithm<PolicySetChild> CA_POLICY_ONLY_ONE_APPLICABLE
+		= new OnlyOneApplicable(XACML1.ID_POLICY_ONLY_ONE_APPLICABLE);
+	
+	// C.10 Legacy Deny-overrides
+	public static final CombiningAlgorithm<Rule> CA_RULE_LEGACY_DENY_OVERRIDES		
+		= new LegacyDenyOverridesRule(XACML1.ID_RULE_DENY_OVERRIDES);
+	public static final CombiningAlgorithm<PolicySetChild> CA_POLICY_LEGACY_DENY_OVERRIDES	
+		= new LegacyDenyOverridesPolicy(XACML1.ID_POLICY_DENY_OVERRIDES);
+	
+	// C.11 Legacy Ordered-deny-overrides
+	public static final CombiningAlgorithm<Rule> CA_RULE_LEGACY_ORDERED_DENY_OVERRIDES		
+		= new LegacyDenyOverridesRule(XACML1.ID_RULE_ORDERED_DENY_OVERRIDES);
+	public static final CombiningAlgorithm<PolicySetChild> CA_POLICY_LEGACY_ORDERED_DENY_OVERRIDES	
+		= new LegacyDenyOverridesPolicy(XACML1.ID_POLICY_ORDERED_DENY_OVERRIDES);
+	
+	// C.12 Legacy Permit-overrides
+	public static final CombiningAlgorithm<Rule> CA_RULE_LEGACY_PERMIT_OVERRIDES		
+		= new LegacyPermitOverridesRule(XACML1.ID_RULE_PERMIT_OVERRIDES);
+	public static final CombiningAlgorithm<PolicySetChild> CA_POLICY_LEGACY_PERMIT_OVERRIDES	
+		= new LegacyPermitOverridesPolicy(XACML1.ID_POLICY_PERMIT_OVERRIDES);
+	
+	// C.13 Legacy Ordered-permit-overrides
+	public static final CombiningAlgorithm<Rule> CA_RULE_LEGACY_ORDERED_PERMIT_OVERRIDES		
+		= new LegacyPermitOverridesRule(XACML1.ID_RULE_ORDERED_PERMIT_OVERRIDES);
+	public static final CombiningAlgorithm<PolicySetChild> CA_POLICY_LEGACY_ORDERED_PERMIT_OVERRIDES	
+		= new LegacyPermitOverridesPolicy(XACML1.ID_POLICY_ORDERED_PERMIT_OVERRIDES);
+	
+	//
+	// Custom AT&T Policy Combing Algorithms
+	//
+	public static final CombiningAlgorithm<PolicySetChild> CA_POLICY_COMBINED_PERMIT_OVERRIDES
+		= new CombinedPermitOverrides<PolicySetChild>(ATTPDPProperties.ID_POLICY_COMBINEDPERMITOVERRIDES);
+	
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdEvaluationContext.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdEvaluationContext.java
new file mode 100755
index 0000000..7266227
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdEvaluationContext.java
@@ -0,0 +1,150 @@
+/*
+ *                        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.std;
+
+import com.att.research.xacml.api.IdReferenceMatch;
+import com.att.research.xacml.api.Request;
+import com.att.research.xacml.api.pip.*;
+import com.att.research.xacml.api.trace.TraceEngine;
+import com.att.research.xacml.api.trace.TraceEngineFactory;
+import com.att.research.xacml.api.trace.TraceEvent;
+import com.att.research.xacml.std.pip.engines.RequestEngine;
+import com.att.research.xacml.std.pip.finders.RequestFinder;
+import com.att.research.xacml.util.FactoryException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.policy.*;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.util.Collection;
+import java.util.Properties;
+
+/**
+ * StdEvaluationContext implements the {@link com.att.research.xacmlatt.pdp.eval.EvaluationContext} interface using
+ * default factories to load the XACML policies, and get the PIP engines.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class StdEvaluationContext implements EvaluationContext {
+	private Log logger	= LogFactory.getLog(this.getClass());
+	private Properties properties;
+	private Request request;
+	private RequestFinder requestFinder;
+	private PolicyFinder policyFinder;
+	private TraceEngine traceEngine;
+	
+	/**
+	 * Creates a new <code>StdEvaluationContext</code> with the given {@link com.att.research.xacml.api.Request} and
+	 * {@link com.att.research.xacmlatt.pdp.policy.PolicyDef}.
+	 * 
+	 * @param requestIn the <code>Request</code>
+	 * @param policyDef the <code>PolicyDef</code>
+	 */
+	public StdEvaluationContext(Request requestIn, PolicyFinder policyFinderIn, PIPFinder pipFinder, TraceEngine traceEngineIn, Properties properties) {
+		this.properties		= properties;
+		this.request		= requestIn;
+		this.policyFinder	= policyFinderIn;
+		if (traceEngineIn != null) {
+			this.traceEngine	= traceEngineIn;
+		} else {
+			try {
+				if (this.properties == null) {
+					this.traceEngine	= TraceEngineFactory.newInstance().getTraceEngine();
+				} else {
+					this.traceEngine	= TraceEngineFactory.newInstance(this.properties).getTraceEngine(this.properties);
+				}
+			} catch (FactoryException ex) {
+				this.logger.error("FactoryException creating TraceEngine: " + ex.toString(), ex);
+			}
+		}
+		
+		if (pipFinder == null) {
+			this.requestFinder		= new RequestFinder(null, new RequestEngine(requestIn));
+		} else {
+			if (pipFinder instanceof RequestFinder) {
+				this.requestFinder	= (RequestFinder)pipFinder;
+			} else {
+				this.requestFinder	= new RequestFinder(pipFinder, new RequestEngine(requestIn));
+			}
+		}
+	}
+	
+	public StdEvaluationContext(Request requestIn, PolicyFinder policyFinderIn, PIPFinder pipFinder, TraceEngine traceEngineIn) {
+		this(requestIn, policyFinderIn, pipFinder, traceEngineIn, null);
+	}
+	
+	public StdEvaluationContext(Request requestIn, PolicyFinder policyFinderIn, PIPFinder pipFinder) {
+		this(requestIn, policyFinderIn, pipFinder, null);
+	}
+
+	@Override
+	public Request getRequest() {
+		return this.request;
+	}
+
+	@Override
+	public PIPResponse getAttributes(PIPRequest pipRequest) throws PIPException {
+		return this.requestFinder.getAttributes(pipRequest, null);
+	}
+	
+	@Override
+	public PIPResponse getAttributes(PIPRequest pipRequest, PIPEngine exclude) throws PIPException {
+		return this.requestFinder.getAttributes(pipRequest, exclude);
+	}
+	
+	@Override
+	public PIPResponse getAttributes(PIPRequest pipRequest, PIPEngine exclude, PIPFinder pipFinderRoot) throws PIPException {
+		return this.requestFinder.getAttributes(pipRequest, exclude, pipFinderRoot);
+	}
+
+	@Override
+	public PolicyFinderResult<PolicyDef> getRootPolicyDef() {
+		return this.policyFinder.getRootPolicyDef(this);
+	}
+
+	@Override
+	public PolicyFinderResult<Policy> getPolicy(IdReferenceMatch idReferenceMatch) {
+		return this.policyFinder.getPolicy(idReferenceMatch);
+	}
+
+	@Override
+	public PolicyFinderResult<PolicySet> getPolicySet(IdReferenceMatch idReferenceMatch) {
+		return this.policyFinder.getPolicySet(idReferenceMatch);
+	}
+
+	@Override
+	public void trace(TraceEvent<?> traceEvent) {
+		if (this.traceEngine != null) {
+			this.traceEngine.trace(traceEvent);
+		}
+	}
+
+	@Override
+	public boolean isTracing() {
+		return (this.traceEngine == null ? false : this.traceEngine.isTracing());
+	}
+
+	@Override
+	public PIPResponse getMatchingAttributes(PIPRequest pipRequest, PIPEngine exclude) throws PIPException {
+		return this.requestFinder.getMatchingAttributes(pipRequest, exclude);
+	}
+
+	@Override
+	public PIPResponse getMatchingAttributes(PIPRequest pipRequest, PIPEngine exclude, PIPFinder pipFinderParent) throws PIPException {
+		return this.requestFinder.getMatchingAttributes(pipRequest, exclude, pipFinderParent);
+	}
+
+	@Override
+	public Collection<PIPEngine> getPIPEngines() {
+		return this.requestFinder.getPIPEngines();
+	}
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdEvaluationContextFactory.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdEvaluationContextFactory.java
new file mode 100755
index 0000000..ea68162
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdEvaluationContextFactory.java
@@ -0,0 +1,163 @@
+/*
+ *                        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.std;
+
+import java.util.Properties;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.att.research.xacml.api.Request;
+import com.att.research.xacml.api.pip.PIPFinder;
+import com.att.research.xacml.api.pip.PIPFinderFactory;
+import com.att.research.xacml.api.trace.TraceEngine;
+import com.att.research.xacml.api.trace.TraceEngineFactory;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContextFactory;
+import com.att.research.xacmlatt.pdp.policy.PolicyFinder;
+import com.att.research.xacmlatt.pdp.policy.PolicyFinderFactory;
+
+/**
+ * StdEvaluationContextFactory extends {@link com.att.research.xacmlatt.pdp.eval.EvaluationContextFactory} to implement
+ * the <code>getEvaluationContext</code> method with a standard {@link com.att.research.xacmlatt.pdp.eval.EvaluationContext}.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class StdEvaluationContextFactory extends EvaluationContextFactory {
+	private Log logger					= LogFactory.getLog(this.getClass());
+	private PolicyFinder policyFinder;
+	private PIPFinder pipFinder;
+	private TraceEngine traceEngine;
+	
+	/**
+	 * Should this properties file be passed onward when instantiating the PolicyFinder 
+	 * and the PIPFinder?
+	 * 
+	 * If yes, then we are assuming that the given properties were not just meant to
+	 * configure the evaluation context, but all the other engines that get created.
+	 * 
+	 * If no, then we are assuming the given properties were only meant for the evaluation
+	 * context. But this implementation as of 7/14 does not even need the properties for
+	 * configuring itseof.
+	 * 
+	 * The problem is, the caller does not have the ability to instantiate the PIPFinder
+	 * and PolicyFinder engines. This is done internally by the evaluation context. So how
+	 * can they have the ability to customize PIP/Policy factories with their own properties 
+	 * object if the properties file isn't passed on?
+	 * 
+	 * Thus, this class will pass on the properties file if given in the constructor.
+	 * 
+	 */
+	protected Properties properties = null;
+
+	protected PolicyFinder getPolicyFinder() {
+		if (this.policyFinder == null) {
+			synchronized(this) {
+				if (this.policyFinder == null) {
+					try {
+						if (this.properties == null) {
+							if (this.logger.isDebugEnabled()) {
+								this.logger.debug("getting Policy finder using default properties");
+							}
+							PolicyFinderFactory policyFinderFactory	= PolicyFinderFactory.newInstance();
+							this.policyFinder	= policyFinderFactory.getPolicyFinder();
+						} else {
+							if (this.logger.isDebugEnabled()) {
+								this.logger.debug("getting Policy finder using properties: " + this.properties);
+							}
+							PolicyFinderFactory policyFinderFactory	= PolicyFinderFactory.newInstance(this.properties);
+							this.policyFinder	= policyFinderFactory.getPolicyFinder(this.properties);
+						}
+					} catch (Exception ex) {
+						this.logger.error("Exception getting PolicyFinder: " + ex.getMessage(), ex);
+					}
+				}
+			}
+		}
+		return this.policyFinder;
+	}
+	
+	protected PIPFinder getPIPFinder() {
+		if (this.pipFinder == null) {
+			synchronized(this) {
+				if (this.pipFinder == null) {
+					try {
+						if (this.properties == null) {
+							if (this.logger.isDebugEnabled()) {
+								this.logger.debug("getting PIP finder using default properties");
+							}
+							PIPFinderFactory pipFinderFactory	= PIPFinderFactory.newInstance();
+							this.pipFinder						= pipFinderFactory.getFinder();
+						} else {
+							if (this.logger.isDebugEnabled()) {
+								this.logger.debug("getting PIP finder using properties: " + this.properties);
+							}
+							PIPFinderFactory pipFinderFactory	= PIPFinderFactory.newInstance(this.properties);
+							this.pipFinder						= pipFinderFactory.getFinder(this.properties);
+						}
+					} catch (Exception ex) {
+						this.logger.error("Exception getting PIPFinder: " + ex.toString(), ex);
+					}
+				}
+			}
+		}
+		return this.pipFinder;
+	}
+	
+	protected TraceEngine getTraceEngine() {
+		if (this.traceEngine == null) {
+			synchronized(this) {
+				if (this.traceEngine == null) {
+					try {
+						if (this.properties == null) {
+							TraceEngineFactory traceEngineFactory	= TraceEngineFactory.newInstance();
+							this.traceEngine	= traceEngineFactory.getTraceEngine();
+						} else {
+							TraceEngineFactory traceEngineFactory	= TraceEngineFactory.newInstance(this.properties);
+							this.traceEngine	= traceEngineFactory.getTraceEngine(this.properties);
+						}
+					} catch (Exception ex) {
+						this.logger.error("Exception getting TraceEngine: " + ex.toString(), ex);
+					}
+				}
+			}
+		}
+		return this.traceEngine;
+	}
+	
+	public StdEvaluationContextFactory() {
+	}
+
+	public StdEvaluationContextFactory(Properties properties) {
+		this.properties = properties;
+	}
+
+	@Override
+	public EvaluationContext getEvaluationContext(Request request) {
+		if (this.properties == null) {
+			return new StdEvaluationContext(request, this.getPolicyFinder(), this.getPIPFinder(), this.getTraceEngine());
+		} else {
+			return new StdEvaluationContext(request, this.getPolicyFinder(), this.getPIPFinder(), this.getTraceEngine(), this.properties);
+		}
+	}
+
+	@Override
+	public void setPolicyFinder(PolicyFinder policyFinderIn) {
+		this.policyFinder	= policyFinderIn;
+	}
+
+	@Override
+	public void setPIPFinder(PIPFinder pipFinderIn) {
+		this.pipFinder		= pipFinderIn;
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdFunctionDefinitionFactory.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdFunctionDefinitionFactory.java
new file mode 100755
index 0000000..04f8001
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdFunctionDefinitionFactory.java
@@ -0,0 +1,70 @@
+/*
+ *                        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.std;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacmlatt.pdp.policy.FunctionDefinition;
+import com.att.research.xacmlatt.pdp.policy.FunctionDefinitionFactory;
+
+/**
+ * StdFunctionDefinitionFactory is the default {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinitionFactory} implementation
+ * used if no other <code>FunctionDefinitionFactory</code> implementation is supplied.  It contains all of the standard XACML 3.0
+ * functions.
+ * 
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class StdFunctionDefinitionFactory extends FunctionDefinitionFactory {
+	private static Map<Identifier,FunctionDefinition> 	mapFunctionDefinitions	= new HashMap<Identifier,FunctionDefinition>();
+	private static boolean								needMapInit				= true;
+	
+	private static void register(FunctionDefinition functionDefinition) {
+		mapFunctionDefinitions.put(functionDefinition.getId(), functionDefinition);
+	}
+		
+	private static void initMap() {
+		if (needMapInit) {
+			synchronized(mapFunctionDefinitions) {
+				if (needMapInit) {
+					needMapInit	= false;
+					Field[] declaredFields	= StdFunctions.class.getDeclaredFields();
+					for (Field field : declaredFields) {
+						if (Modifier.isStatic(field.getModifiers()) && 
+							field.getName().startsWith(StdFunctions.FD_PREFIX) &&
+							FunctionDefinition.class.isAssignableFrom(field.getType()) &&
+							Modifier.isPublic(field.getModifiers())
+						) {
+							try {
+								register((FunctionDefinition)(field.get(null)));
+							} catch (IllegalAccessException ex) {
+								
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+	
+	public StdFunctionDefinitionFactory() {
+		initMap();
+	}
+
+	@Override
+	public FunctionDefinition getFunctionDefinition(Identifier functionId) {
+		return mapFunctionDefinitions.get(functionId);
+	}
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdFunctions.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdFunctions.java
new file mode 100755
index 0000000..b46dab1
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdFunctions.java
@@ -0,0 +1,479 @@
+/*
+ *                        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.std;
+
+import java.math.BigInteger;
+import java.net.URI;
+
+import javax.security.auth.x500.X500Principal;
+
+import com.att.research.xacml.api.XACML1;
+import com.att.research.xacml.api.XACML2;
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.datatypes.Base64Binary;
+import com.att.research.xacml.std.datatypes.DataTypes;
+import com.att.research.xacml.std.datatypes.HexBinary;
+import com.att.research.xacml.std.datatypes.IPAddress;
+import com.att.research.xacml.std.datatypes.ISO8601Date;
+import com.att.research.xacml.std.datatypes.ISO8601DateTime;
+import com.att.research.xacml.std.datatypes.ISO8601Time;
+import com.att.research.xacml.std.datatypes.RFC2396DomainName;
+import com.att.research.xacml.std.datatypes.RFC822Name;
+import com.att.research.xacml.std.datatypes.XPathDayTimeDuration;
+import com.att.research.xacml.std.datatypes.XPathYearMonthDuration;
+import com.att.research.xacmlatt.pdp.policy.FunctionDefinition;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionAccessPermitted;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionArithmetic;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionBag;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionBagIsIn;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionBagOneAndOnly;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionBagSize;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionComparison;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionDateTimeArithmetic;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionEquality;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionHigherOrderBag;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionLogical;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionNumberTypeConversion;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionRFC822NameMatch;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionRegexpMatch;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionSet;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionStringConversion;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionStringEqualIgnoreCase;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionStringFunctions;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionStringNormalize;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionTimeInRange;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionURIStringConcatenate;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionX500NameMatch;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionXPath;
+
+/**
+ * StdFunctions contains the {@link com.att.research.xacml.api.Identifier} values for the standard XACML functions.
+ * 
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+@SuppressWarnings("deprecation")
+public class StdFunctions {
+	protected StdFunctions() {
+	}
+	
+	public static final String FD_PREFIX	= "FD_";
+	
+	/*
+	 * A.3.1 Equality predicates
+	 */
+	
+	public static final FunctionDefinition	FD_STRING_EQUAL				= new FunctionDefinitionEquality<String>(XACML3.ID_FUNCTION_STRING_EQUAL, DataTypes.DT_STRING);
+	public static final FunctionDefinition	FD_STRING_EQUAL_IGNORE_CASE	= new FunctionDefinitionStringEqualIgnoreCase(XACML3.ID_FUNCTION_STRING_EQUAL_IGNORE_CASE);
+	public static final FunctionDefinition	FD_BOOLEAN_EQUAL			= new FunctionDefinitionEquality<Boolean>(XACML3.ID_FUNCTION_BOOLEAN_EQUAL, DataTypes.DT_BOOLEAN);
+	public static final FunctionDefinition	FD_INTEGER_EQUAL			= new FunctionDefinitionEquality<BigInteger>(XACML3.ID_FUNCTION_INTEGER_EQUAL, DataTypes.DT_INTEGER);
+	public static final FunctionDefinition	FD_DOUBLE_EQUAL				= new FunctionDefinitionEquality<Double>(XACML3.ID_FUNCTION_DOUBLE_EQUAL, DataTypes.DT_DOUBLE);
+	public static final FunctionDefinition	FD_DATE_EQUAL				= new FunctionDefinitionEquality<ISO8601Date>(XACML3.ID_FUNCTION_DATE_EQUAL, DataTypes.DT_DATE);
+	public static final FunctionDefinition	FD_TIME_EQUAL				= new FunctionDefinitionEquality<ISO8601Time>(XACML3.ID_FUNCTION_TIME_EQUAL, DataTypes.DT_TIME);
+	public static final FunctionDefinition	FD_DATETIME_EQUAL			= new FunctionDefinitionEquality<ISO8601DateTime>(XACML3.ID_FUNCTION_DATETIME_EQUAL, DataTypes.DT_DATETIME);
+
+	// only difference between R3 and older (R1) versions of durations seem to be the identifiers, so send calls to the same place in either case
+	public static final FunctionDefinition	FD_DAYTIMEDURATION_EQUAL_VERSION1	= new FunctionDefinitionEquality<XPathDayTimeDuration>(XACML1.ID_FUNCTION_DAYTIMEDURATION_EQUAL, DataTypes.DT_DAYTIMEDURATION);
+	public static final FunctionDefinition	FD_DAYTIMEDURATION_EQUAL	= new FunctionDefinitionEquality<XPathDayTimeDuration>(XACML3.ID_FUNCTION_DAYTIMEDURATION_EQUAL, DataTypes.DT_DAYTIMEDURATION);
+	public static final FunctionDefinition	FD_YEARMONTHDURATION_EQUAL_VERSION1	= new FunctionDefinitionEquality<XPathYearMonthDuration>(XACML1.ID_FUNCTION_YEARMONTHDURATION_EQUAL, DataTypes.DT_YEARMONTHDURATION);
+	public static final FunctionDefinition	FD_YEARMONTHDURATION_EQUAL	= new FunctionDefinitionEquality<XPathYearMonthDuration>(XACML3.ID_FUNCTION_YEARMONTHDURATION_EQUAL, DataTypes.DT_YEARMONTHDURATION);
+	
+	// continue on with latest versions
+	public static final FunctionDefinition	FD_ANYURI_EQUAL				= new FunctionDefinitionEquality<URI>(XACML3.ID_FUNCTION_ANYURI_EQUAL, DataTypes.DT_ANYURI);
+	public static final FunctionDefinition	FD_X500NAME_EQUAL			= new FunctionDefinitionEquality<X500Principal>(XACML3.ID_FUNCTION_X500NAME_EQUAL, DataTypes.DT_X500NAME);
+	public static final FunctionDefinition	FD_RFC822NAME_EQUAL			= new FunctionDefinitionEquality<RFC822Name>(XACML3.ID_FUNCTION_RFC822NAME_EQUAL, DataTypes.DT_RFC822NAME);
+	public static final FunctionDefinition	FD_HEXBINARY_EQUAL			= new FunctionDefinitionEquality<HexBinary>(XACML3.ID_FUNCTION_HEXBINARY_EQUAL, DataTypes.DT_HEXBINARY);
+	public static final FunctionDefinition	FD_BASE64BINARY_EQUAL		= new FunctionDefinitionEquality<Base64Binary>(XACML3.ID_FUNCTION_BASE64BINARY_EQUAL, DataTypes.DT_BASE64BINARY);
+
+
+	
+		
+	/*
+	 * Arithmetic Functions (See A.3.2)
+	 */
+	
+	public static final FunctionDefinition	FD_INTEGER_ADD		= new FunctionDefinitionArithmetic<BigInteger>(XACML3.ID_FUNCTION_INTEGER_ADD, DataTypes.DT_INTEGER, FunctionDefinitionArithmetic.OPERATION.ADD, 2);
+	public static final FunctionDefinition	FD_DOUBLE_ADD		= new FunctionDefinitionArithmetic<Double>(XACML3.ID_FUNCTION_DOUBLE_ADD, DataTypes.DT_DOUBLE, FunctionDefinitionArithmetic.OPERATION.ADD, 2);
+	public static final FunctionDefinition	FD_INTEGER_SUBTRACT		= new FunctionDefinitionArithmetic<BigInteger>(XACML3.ID_FUNCTION_INTEGER_SUBTRACT, DataTypes.DT_INTEGER, FunctionDefinitionArithmetic.OPERATION.SUBTRACT, 2);
+	public static final FunctionDefinition	FD_DOUBLE_SUBTRACT		= new FunctionDefinitionArithmetic<Double>(XACML3.ID_FUNCTION_DOUBLE_SUBTRACT, DataTypes.DT_DOUBLE, FunctionDefinitionArithmetic.OPERATION.SUBTRACT, 2);
+	public static final FunctionDefinition	FD_INTEGER_MULTIPLY		= new FunctionDefinitionArithmetic<BigInteger>(XACML3.ID_FUNCTION_INTEGER_MULTIPLY, DataTypes.DT_INTEGER, FunctionDefinitionArithmetic.OPERATION.MULTIPLY, 2);
+	public static final FunctionDefinition	FD_DOUBLE_MULTIPLY		= new FunctionDefinitionArithmetic<Double>(XACML3.ID_FUNCTION_DOUBLE_MULTIPLY, DataTypes.DT_DOUBLE, FunctionDefinitionArithmetic.OPERATION.MULTIPLY, 2);
+	public static final FunctionDefinition	FD_INTEGER_DIVIDE		= new FunctionDefinitionArithmetic<BigInteger>(XACML3.ID_FUNCTION_INTEGER_DIVIDE, DataTypes.DT_INTEGER, FunctionDefinitionArithmetic.OPERATION.DIVIDE, 2);
+	public static final FunctionDefinition	FD_DOUBLE_DIVIDE		= new FunctionDefinitionArithmetic<Double>(XACML3.ID_FUNCTION_DOUBLE_DIVIDE, DataTypes.DT_DOUBLE, FunctionDefinitionArithmetic.OPERATION.DIVIDE, 2);
+	public static final FunctionDefinition	FD_INTEGER_MOD			= new FunctionDefinitionArithmetic<BigInteger>(XACML3.ID_FUNCTION_INTEGER_MOD, DataTypes.DT_INTEGER, FunctionDefinitionArithmetic.OPERATION.MOD, 2);
+	public static final FunctionDefinition	FD_INTEGER_ABS		= new FunctionDefinitionArithmetic<BigInteger>(XACML3.ID_FUNCTION_INTEGER_ABS, DataTypes.DT_INTEGER, FunctionDefinitionArithmetic.OPERATION.ABS, 1);
+	public static final FunctionDefinition	FD_DOUBLE_ABS		= new FunctionDefinitionArithmetic<Double>(XACML3.ID_FUNCTION_DOUBLE_ABS, DataTypes.DT_DOUBLE, FunctionDefinitionArithmetic.OPERATION.ABS, 1);
+	public static final FunctionDefinition	FD_ROUND		= new FunctionDefinitionArithmetic<Double>(XACML3.ID_FUNCTION_ROUND, DataTypes.DT_DOUBLE, FunctionDefinitionArithmetic.OPERATION.ROUND, 1);
+	public static final FunctionDefinition	FD_FLOOR		= new FunctionDefinitionArithmetic<Double>(XACML3.ID_FUNCTION_FLOOR, DataTypes.DT_DOUBLE, FunctionDefinitionArithmetic.OPERATION.FLOOR, 1);
+
+
+
+	
+	/*
+	 * String Conversion Functions (See A.3.3)
+	 */
+	public static final FunctionDefinition	FD_STRING_NORMALIZE_SPACE		= new FunctionDefinitionStringNormalize(XACML3.ID_FUNCTION_STRING_NORMALIZE_SPACE, FunctionDefinitionStringNormalize.OPERATION.SPACE);
+	public static final FunctionDefinition	FD_STRING_NORMALIZE_TO_LOWER_CASE	= new FunctionDefinitionStringNormalize(XACML3.ID_FUNCTION_STRING_NORMALIZE_TO_LOWER_CASE, FunctionDefinitionStringNormalize.OPERATION.LOWER_CASE);
+
+	/*
+	 * Numeric Data-Type Conversion Functions (See A.3.4)
+	 */
+	public static final FunctionDefinition	FD_DOUBLE_TO_INTEGER		= new FunctionDefinitionNumberTypeConversion<BigInteger,Double>(XACML3.ID_FUNCTION_DOUBLE_TO_INTEGER, DataTypes.DT_INTEGER, DataTypes.DT_DOUBLE);
+	public static final FunctionDefinition	FD_INTEGER_TO_DOUBLE		= new FunctionDefinitionNumberTypeConversion<Double,BigInteger>(XACML3.ID_FUNCTION_INTEGER_TO_DOUBLE, DataTypes.DT_DOUBLE, DataTypes.DT_INTEGER);
+
+
+	/*
+	 * Logical Functions (See A.3.5)
+	 */
+	public static final FunctionDefinition	FD_OR		= new FunctionDefinitionLogical(XACML3.ID_FUNCTION_OR, FunctionDefinitionLogical.OPERATION.OR);
+	public static final FunctionDefinition	FD_AND		= new FunctionDefinitionLogical(XACML3.ID_FUNCTION_AND, FunctionDefinitionLogical.OPERATION.AND);
+	public static final FunctionDefinition	FD_N_OF		= new FunctionDefinitionLogical(XACML3.ID_FUNCTION_N_OF, FunctionDefinitionLogical.OPERATION.N_OF);
+	public static final FunctionDefinition	FD_NOT		= new FunctionDefinitionLogical(XACML3.ID_FUNCTION_NOT, FunctionDefinitionLogical.OPERATION.NOT);
+	
+
+	/*
+	 * Numeric Comparison Functions (See A.3.6 of xacml-3.0-core-spec-os-en.doc)
+	 */
+	public static final FunctionDefinition	FD_INTEGER_GREATER_THAN		= new FunctionDefinitionComparison<BigInteger>(XACML3.ID_FUNCTION_INTEGER_GREATER_THAN, DataTypes.DT_INTEGER, FunctionDefinitionComparison.OPERATION.GREATER_THAN);
+	public static final FunctionDefinition	FD_INTEGER_GREATER_THAN_OR_EQUAL		= new FunctionDefinitionComparison<BigInteger>(XACML3.ID_FUNCTION_INTEGER_GREATER_THAN_OR_EQUAL, DataTypes.DT_INTEGER, FunctionDefinitionComparison.OPERATION.GREATER_THAN_EQUAL);
+	public static final FunctionDefinition	FD_INTEGER_LESS_THAN		= new FunctionDefinitionComparison<BigInteger>(XACML3.ID_FUNCTION_INTEGER_LESS_THAN, DataTypes.DT_INTEGER, FunctionDefinitionComparison.OPERATION.LESS_THAN);
+	public static final FunctionDefinition	FD_INTEGER_LESS_THAN_OR_EQUAL		= new FunctionDefinitionComparison<BigInteger>(XACML3.ID_FUNCTION_INTEGER_LESS_THAN_OR_EQUAL, DataTypes.DT_INTEGER, FunctionDefinitionComparison.OPERATION.LESS_THAN_EQUAL);
+	public static final FunctionDefinition	FD_DOUBLE_GREATER_THAN		= new FunctionDefinitionComparison<Double>(XACML3.ID_FUNCTION_DOUBLE_GREATER_THAN, DataTypes.DT_DOUBLE, FunctionDefinitionComparison.OPERATION.GREATER_THAN);
+	public static final FunctionDefinition	FD_DOUBLE_GREATER_THAN_OR_EQUAL		= new FunctionDefinitionComparison<Double>(XACML3.ID_FUNCTION_DOUBLE_GREATER_THAN_OR_EQUAL, DataTypes.DT_DOUBLE, FunctionDefinitionComparison.OPERATION.GREATER_THAN_EQUAL);
+	public static final FunctionDefinition	FD_DOUBLE_LESS_THAN		= new FunctionDefinitionComparison<Double>(XACML3.ID_FUNCTION_DOUBLE_LESS_THAN, DataTypes.DT_DOUBLE, FunctionDefinitionComparison.OPERATION.LESS_THAN);
+	public static final FunctionDefinition	FD_DOUBLE_LESS_THAN_OR_EQUAL		= new FunctionDefinitionComparison<Double>(XACML3.ID_FUNCTION_DOUBLE_LESS_THAN_OR_EQUAL, DataTypes.DT_DOUBLE, FunctionDefinitionComparison.OPERATION.LESS_THAN_EQUAL);
+	
+
+	/*
+	 * Date and Time Arithmetic Functions (See A.3.7)
+	 */
+	public static final FunctionDefinition	FD_DATETIME_ADD_DAYTIMEDURATION					= new FunctionDefinitionDateTimeArithmetic<ISO8601DateTime,XPathDayTimeDuration>(XACML3.ID_FUNCTION_DATETIME_ADD_DAYTIMEDURATION, DataTypes.DT_DATETIME, DataTypes.DT_DAYTIMEDURATION, FunctionDefinitionDateTimeArithmetic.OPERATION.ADD);
+	public static final FunctionDefinition	FD_DATETIME_ADD_DAYTIMEDURATION_VERSION1		= new FunctionDefinitionDateTimeArithmetic<ISO8601DateTime,XPathDayTimeDuration>(XACML1.ID_FUNCTION_DATETIME_ADD_DAYTIMEDURATION, DataTypes.DT_DATETIME, DataTypes.DT_DAYTIMEDURATION, FunctionDefinitionDateTimeArithmetic.OPERATION.ADD);
+	public static final FunctionDefinition	FD_DATETIME_ADD_YEARMONTHDURATION				= new FunctionDefinitionDateTimeArithmetic<ISO8601DateTime,XPathYearMonthDuration>(XACML3.ID_FUNCTION_DATETIME_ADD_YEARMONTHDURATION, DataTypes.DT_DATETIME, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionDateTimeArithmetic.OPERATION.ADD);
+	public static final FunctionDefinition	FD_DATETIME_ADD_YEARMONTHDURATION_VERSION1		= new FunctionDefinitionDateTimeArithmetic<ISO8601DateTime,XPathYearMonthDuration>(XACML1.ID_FUNCTION_DATETIME_ADD_YEARMONTHDURATION, DataTypes.DT_DATETIME, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionDateTimeArithmetic.OPERATION.ADD);
+
+	public static final FunctionDefinition	FD_DATETIME_SUBTRACT_DAYTIMEDURATION				= new FunctionDefinitionDateTimeArithmetic<ISO8601DateTime,XPathDayTimeDuration>(XACML3.ID_FUNCTION_DATETIME_SUBTRACT_DAYTIMEDURATION, DataTypes.DT_DATETIME, DataTypes.DT_DAYTIMEDURATION, FunctionDefinitionDateTimeArithmetic.OPERATION.SUBTRACT);
+	public static final FunctionDefinition	FD_DATETIME_SUBTRACT_DAYTIMEDURATION_VERSION1		= new FunctionDefinitionDateTimeArithmetic<ISO8601DateTime,XPathDayTimeDuration>(XACML1.ID_FUNCTION_DATETIME_SUBTRACT_DAYTIMEDURATION, DataTypes.DT_DATETIME, DataTypes.DT_DAYTIMEDURATION, FunctionDefinitionDateTimeArithmetic.OPERATION.SUBTRACT);
+	public static final FunctionDefinition	FD_DATETIME_SUBTRACT_YEARMONTHDURATION				= new FunctionDefinitionDateTimeArithmetic<ISO8601DateTime,XPathYearMonthDuration>(XACML3.ID_FUNCTION_DATETIME_SUBTRACT_YEARMONTHDURATION, DataTypes.DT_DATETIME, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionDateTimeArithmetic.OPERATION.SUBTRACT);
+	public static final FunctionDefinition	FD_DATETIME_SUBTRACT_YEARMONTHDURATION_VERSION1		= new FunctionDefinitionDateTimeArithmetic<ISO8601DateTime,XPathYearMonthDuration>(XACML1.ID_FUNCTION_DATETIME_SUBTRACT_YEARMONTHDURATION, DataTypes.DT_DATETIME, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionDateTimeArithmetic.OPERATION.SUBTRACT);
+
+	public static final FunctionDefinition	FD_DATE_ADD_YEARMONTHDURATION				= new FunctionDefinitionDateTimeArithmetic<ISO8601Date,XPathYearMonthDuration>(XACML3.ID_FUNCTION_DATE_ADD_YEARMONTHDURATION, DataTypes.DT_DATE, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionDateTimeArithmetic.OPERATION.ADD);
+	public static final FunctionDefinition	FD_DATE_ADD_YEARMONTHDURATION_VERSION1		= new FunctionDefinitionDateTimeArithmetic<ISO8601Date,XPathYearMonthDuration>(XACML1.ID_FUNCTION_DATE_ADD_YEARMONTHDURATION, DataTypes.DT_DATE, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionDateTimeArithmetic.OPERATION.ADD);
+	public static final FunctionDefinition	FD_DATE_SUBTRACT_YEARMONTHDURATION				= new FunctionDefinitionDateTimeArithmetic<ISO8601Date,XPathYearMonthDuration>(XACML3.ID_FUNCTION_DATE_SUBTRACT_YEARMONTHDURATION, DataTypes.DT_DATE, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionDateTimeArithmetic.OPERATION.SUBTRACT);
+	public static final FunctionDefinition	FD_DATE_SUBTRACT_YEARMONTHDURATION_VERSION1		= new FunctionDefinitionDateTimeArithmetic<ISO8601Date,XPathYearMonthDuration>(XACML1.ID_FUNCTION_DATE_SUBTRACT_YEARMONTHDURATION, DataTypes.DT_DATE, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionDateTimeArithmetic.OPERATION.SUBTRACT);
+
+
+	/*
+	 * Non Numeric Comparison Functions (See A.3.8)
+	 */
+	public static final FunctionDefinition	FD_STRING_GREATER_THAN		= new FunctionDefinitionComparison<String>(XACML3.ID_FUNCTION_STRING_GREATER_THAN, DataTypes.DT_STRING, FunctionDefinitionComparison.OPERATION.GREATER_THAN);
+	public static final FunctionDefinition	FD_STRING_GREATER_THAN_OR_EQUAL		= new FunctionDefinitionComparison<String>(XACML3.ID_FUNCTION_STRING_GREATER_THAN_OR_EQUAL, DataTypes.DT_STRING, FunctionDefinitionComparison.OPERATION.GREATER_THAN_EQUAL);
+	public static final FunctionDefinition	FD_STRING_LESS_THAN		= new FunctionDefinitionComparison<String>(XACML3.ID_FUNCTION_STRING_LESS_THAN, DataTypes.DT_STRING, FunctionDefinitionComparison.OPERATION.LESS_THAN);
+	public static final FunctionDefinition	FD_STRING_LESS_THAN_OR_EQUAL		= new FunctionDefinitionComparison<String>(XACML3.ID_FUNCTION_STRING_LESS_THAN_OR_EQUAL, DataTypes.DT_STRING, FunctionDefinitionComparison.OPERATION.LESS_THAN_EQUAL);
+	public static final FunctionDefinition	FD_TIME_GREATER_THAN		= new FunctionDefinitionComparison<ISO8601Time>(XACML3.ID_FUNCTION_TIME_GREATER_THAN, DataTypes.DT_TIME, FunctionDefinitionComparison.OPERATION.GREATER_THAN);
+	public static final FunctionDefinition	FD_TIME_GREATER_THAN_OR_EQUAL		= new FunctionDefinitionComparison<ISO8601Time>(XACML3.ID_FUNCTION_TIME_GREATER_THAN_OR_EQUAL, DataTypes.DT_TIME, FunctionDefinitionComparison.OPERATION.GREATER_THAN_EQUAL);
+	public static final FunctionDefinition	FD_TIME_LESS_THAN		= new FunctionDefinitionComparison<ISO8601Time>(XACML3.ID_FUNCTION_TIME_LESS_THAN, DataTypes.DT_TIME, FunctionDefinitionComparison.OPERATION.LESS_THAN);
+	public static final FunctionDefinition	FD_TIME_LESS_THAN_OR_EQUAL		= new FunctionDefinitionComparison<ISO8601Time>(XACML3.ID_FUNCTION_TIME_LESS_THAN_OR_EQUAL, DataTypes.DT_TIME, FunctionDefinitionComparison.OPERATION.LESS_THAN_EQUAL);
+	public static final FunctionDefinition	FD_TIME_IN_RANGE		= new FunctionDefinitionTimeInRange<ISO8601Time>(XACML3.ID_FUNCTION_TIME_IN_RANGE, DataTypes.DT_TIME);
+	public static final FunctionDefinition	FD_DATE_GREATER_THAN		= new FunctionDefinitionComparison<ISO8601Date>(XACML3.ID_FUNCTION_DATE_GREATER_THAN, DataTypes.DT_DATE, FunctionDefinitionComparison.OPERATION.GREATER_THAN);
+	public static final FunctionDefinition	FD_DATE_GREATER_THAN_OR_EQUAL		= new FunctionDefinitionComparison<ISO8601Date>(XACML3.ID_FUNCTION_DATE_GREATER_THAN_OR_EQUAL, DataTypes.DT_DATE, FunctionDefinitionComparison.OPERATION.GREATER_THAN_EQUAL);
+	public static final FunctionDefinition	FD_DATE_LESS_THAN		= new FunctionDefinitionComparison<ISO8601Date>(XACML3.ID_FUNCTION_DATE_LESS_THAN, DataTypes.DT_DATE, FunctionDefinitionComparison.OPERATION.LESS_THAN);
+	public static final FunctionDefinition	FD_DATE_LESS_THAN_OR_EQUAL		= new FunctionDefinitionComparison<ISO8601Date>(XACML3.ID_FUNCTION_DATE_LESS_THAN_OR_EQUAL, DataTypes.DT_DATE, FunctionDefinitionComparison.OPERATION.LESS_THAN_EQUAL);
+	public static final FunctionDefinition	FD_DATETIME_GREATER_THAN		= new FunctionDefinitionComparison<ISO8601DateTime>(XACML3.ID_FUNCTION_DATETIME_GREATER_THAN, DataTypes.DT_DATETIME, FunctionDefinitionComparison.OPERATION.GREATER_THAN);
+	public static final FunctionDefinition	FD_DATETIME_GREATER_THAN_OR_EQUAL		= new FunctionDefinitionComparison<ISO8601DateTime>(XACML3.ID_FUNCTION_DATETIME_GREATER_THAN_OR_EQUAL, DataTypes.DT_DATETIME, FunctionDefinitionComparison.OPERATION.GREATER_THAN_EQUAL);
+	public static final FunctionDefinition	FD_DATETIME_LESS_THAN		= new FunctionDefinitionComparison<ISO8601DateTime>(XACML3.ID_FUNCTION_DATETIME_LESS_THAN, DataTypes.DT_DATETIME, FunctionDefinitionComparison.OPERATION.LESS_THAN);
+	public static final FunctionDefinition	FD_DATETIME_LESS_THAN_OR_EQUAL		= new FunctionDefinitionComparison<ISO8601DateTime>(XACML3.ID_FUNCTION_DATETIME_LESS_THAN_OR_EQUAL, DataTypes.DT_DATETIME, FunctionDefinitionComparison.OPERATION.LESS_THAN_EQUAL);
+
+	
+
+	/*
+	 * String functions (See A.3.9 of xacml-3.0-core-spec-os-en.doc)
+	 */
+	public static final FunctionDefinition	FD_BOOLEAN_FROM_STRING		= new FunctionDefinitionStringConversion<Boolean,String>(XACML3.ID_FUNCTION_BOOLEAN_FROM_STRING, DataTypes.DT_BOOLEAN, DataTypes.DT_STRING);
+	public static final FunctionDefinition	FD_STRING_FROM_BOOLEAN		= new FunctionDefinitionStringConversion<String,Boolean>(XACML3.ID_FUNCTION_STRING_FROM_BOOLEAN, DataTypes.DT_STRING, DataTypes.DT_BOOLEAN);
+	public static final FunctionDefinition	FD_INTEGER_FROM_STRING		= new FunctionDefinitionStringConversion<BigInteger,String>(XACML3.ID_FUNCTION_INTEGER_FROM_STRING, DataTypes.DT_INTEGER, DataTypes.DT_STRING);
+	public static final FunctionDefinition	FD_STRING_FROM_INTEGER		= new FunctionDefinitionStringConversion<String,BigInteger>(XACML3.ID_FUNCTION_STRING_FROM_INTEGER, DataTypes.DT_STRING, DataTypes.DT_INTEGER);
+	public static final FunctionDefinition	FD_DOUBLE_FROM_STRING		= new FunctionDefinitionStringConversion<Double,String>(XACML3.ID_FUNCTION_DOUBLE_FROM_STRING, DataTypes.DT_DOUBLE, DataTypes.DT_STRING);
+	public static final FunctionDefinition	FD_STRING_FROM_DOUBLE		= new FunctionDefinitionStringConversion<String,Double>(XACML3.ID_FUNCTION_STRING_FROM_DOUBLE, DataTypes.DT_STRING, DataTypes.DT_DOUBLE);
+	public static final FunctionDefinition	FD_TIME_FROM_STRING		= new FunctionDefinitionStringConversion<ISO8601Time,String>(XACML3.ID_FUNCTION_TIME_FROM_STRING, DataTypes.DT_TIME, DataTypes.DT_STRING);
+	public static final FunctionDefinition	FD_STRING_FROM_TIME		= new FunctionDefinitionStringConversion<String,ISO8601Time>(XACML3.ID_FUNCTION_STRING_FROM_TIME, DataTypes.DT_STRING, DataTypes.DT_TIME);
+	public static final FunctionDefinition	FD_DATE_FROM_STRING		= new FunctionDefinitionStringConversion<ISO8601Date,String>(XACML3.ID_FUNCTION_DATE_FROM_STRING, DataTypes.DT_DATE, DataTypes.DT_STRING);
+	public static final FunctionDefinition	FD_STRING_FROM_DATE		= new FunctionDefinitionStringConversion<String,ISO8601Date>(XACML3.ID_FUNCTION_STRING_FROM_DATE, DataTypes.DT_STRING, DataTypes.DT_DATE);
+	public static final FunctionDefinition	FD_DATETIME_FROM_STRING		= new FunctionDefinitionStringConversion<ISO8601DateTime,String>(XACML3.ID_FUNCTION_DATETIME_FROM_STRING, DataTypes.DT_DATETIME, DataTypes.DT_STRING);
+	public static final FunctionDefinition	FD_STRING_FROM_DATETIME		= new FunctionDefinitionStringConversion<String,ISO8601DateTime>(XACML3.ID_FUNCTION_STRING_FROM_DATETIME, DataTypes.DT_STRING, DataTypes.DT_DATETIME);
+	public static final FunctionDefinition	FD_ANYURI_FROM_STRING		= new FunctionDefinitionStringConversion<URI,String>(XACML3.ID_FUNCTION_ANYURI_FROM_STRING, DataTypes.DT_ANYURI, DataTypes.DT_STRING);
+	public static final FunctionDefinition	FD_STRING_FROM_ANYURI		= new FunctionDefinitionStringConversion<String,URI>(XACML3.ID_FUNCTION_STRING_FROM_ANYURI, DataTypes.DT_STRING, DataTypes.DT_ANYURI);
+	public static final FunctionDefinition	FD_DAYTIMEDURATION_FROM_STRING		= new FunctionDefinitionStringConversion<XPathDayTimeDuration,String>(XACML3.ID_FUNCTION_DAYTIMEDURATION_FROM_STRING, DataTypes.DT_DAYTIMEDURATION, DataTypes.DT_STRING);
+	public static final FunctionDefinition	FD_STRING_FROM_DAYTIMEDURATION		= new FunctionDefinitionStringConversion<String,XPathDayTimeDuration>(XACML3.ID_FUNCTION_STRING_FROM_DAYTIMEDURATION, DataTypes.DT_STRING, DataTypes.DT_DAYTIMEDURATION);
+	public static final FunctionDefinition	FD_YEARMONTHDURATION_FROM_STRING		= new FunctionDefinitionStringConversion<XPathYearMonthDuration,String>(XACML3.ID_FUNCTION_YEARMONTHDURATION_FROM_STRING, DataTypes.DT_YEARMONTHDURATION, DataTypes.DT_STRING);
+	public static final FunctionDefinition	FD_STRING_FROM_YEARMONTHDURATION		= new FunctionDefinitionStringConversion<String,XPathYearMonthDuration>(XACML3.ID_FUNCTION_STRING_FROM_YEARMONTHDURATION, DataTypes.DT_STRING, DataTypes.DT_YEARMONTHDURATION);
+	public static final FunctionDefinition	FD_X500NAME_FROM_STRING		= new FunctionDefinitionStringConversion<X500Principal,String>(XACML3.ID_FUNCTION_X500NAME_FROM_STRING, DataTypes.DT_X500NAME, DataTypes.DT_STRING);
+	public static final FunctionDefinition	FD_STRING_FROM_X500NAME		= new FunctionDefinitionStringConversion<String,X500Principal>(XACML3.ID_FUNCTION_STRING_FROM_X500NAME, DataTypes.DT_STRING, DataTypes.DT_X500NAME);
+	public static final FunctionDefinition	FD_RFC822NAME_FROM_STRING		= new FunctionDefinitionStringConversion<RFC822Name,String>(XACML3.ID_FUNCTION_RFC822NAME_FROM_STRING, DataTypes.DT_RFC822NAME, DataTypes.DT_STRING);
+	public static final FunctionDefinition	FD_STRING_FROM_RFC822NAME		= new FunctionDefinitionStringConversion<String,RFC822Name>(XACML3.ID_FUNCTION_STRING_FROM_RFC822NAME, DataTypes.DT_STRING, DataTypes.DT_RFC822NAME);
+	public static final FunctionDefinition	FD_IPADDRESS_FROM_STRING		= new FunctionDefinitionStringConversion<IPAddress,String>(XACML3.ID_FUNCTION_IPADDRESS_FROM_STRING, DataTypes.DT_IPADDRESS, DataTypes.DT_STRING);
+	public static final FunctionDefinition	FD_STRING_FROM_IPADDRESS		= new FunctionDefinitionStringConversion<String,IPAddress>(XACML3.ID_FUNCTION_STRING_FROM_IPADDRESS, DataTypes.DT_STRING, DataTypes.DT_IPADDRESS);
+	public static final FunctionDefinition	FD_DNSNAME_FROM_STRING		= new FunctionDefinitionStringConversion<RFC2396DomainName,String>(XACML3.ID_FUNCTION_DNSNAME_FROM_STRING, DataTypes.DT_DNSNAME, DataTypes.DT_STRING);
+	public static final FunctionDefinition	FD_STRING_FROM_DNSNAME		= new FunctionDefinitionStringConversion<String,RFC2396DomainName>(XACML3.ID_FUNCTION_STRING_FROM_DNSNAME, DataTypes.DT_STRING, DataTypes.DT_DNSNAME);
+
+	// String Functions not converting Strings to/from DataType objects
+	public static final FunctionDefinition	FD_STRING_CONCATENATE		= new FunctionDefinitionStringFunctions<String,String>(XACML3.ID_FUNCTION_STRING_CONCATENATE, DataTypes.DT_STRING, DataTypes.DT_STRING, FunctionDefinitionStringFunctions.OPERATION.CONCATENATE);
+	public static final FunctionDefinition	FD_STRING_STARTS_WITH		= new FunctionDefinitionStringFunctions<Boolean,String>(XACML3.ID_FUNCTION_STRING_STARTS_WITH, DataTypes.DT_BOOLEAN, DataTypes.DT_STRING, FunctionDefinitionStringFunctions.OPERATION.STARTS_WITH);
+	public static final FunctionDefinition	FD_ANYURI_STARTS_WITH		= new FunctionDefinitionStringFunctions<Boolean, URI>(XACML3.ID_FUNCTION_ANYURI_STARTS_WITH, DataTypes.DT_BOOLEAN, DataTypes.DT_ANYURI, FunctionDefinitionStringFunctions.OPERATION.STARTS_WITH);
+	public static final FunctionDefinition	FD_STRING_ENDS_WITH		= new FunctionDefinitionStringFunctions<Boolean,String>(XACML3.ID_FUNCTION_STRING_ENDS_WITH, DataTypes.DT_BOOLEAN, DataTypes.DT_STRING, FunctionDefinitionStringFunctions.OPERATION.ENDS_WITH);
+	public static final FunctionDefinition	FD_ANYURI_ENDS_WITH		= new FunctionDefinitionStringFunctions<Boolean, URI>(XACML3.ID_FUNCTION_ANYURI_ENDS_WITH, DataTypes.DT_BOOLEAN, DataTypes.DT_ANYURI, FunctionDefinitionStringFunctions.OPERATION.ENDS_WITH);
+	public static final FunctionDefinition	FD_STRING_CONTAINS		= new FunctionDefinitionStringFunctions<Boolean,String>(XACML3.ID_FUNCTION_STRING_CONTAINS, DataTypes.DT_BOOLEAN, DataTypes.DT_STRING, FunctionDefinitionStringFunctions.OPERATION.CONTAINS);
+	public static final FunctionDefinition	FD_ANYURI_CONTAINS		= new FunctionDefinitionStringFunctions<Boolean, URI>(XACML3.ID_FUNCTION_ANYURI_CONTAINS, DataTypes.DT_BOOLEAN, DataTypes.DT_ANYURI, FunctionDefinitionStringFunctions.OPERATION.CONTAINS);
+	public static final FunctionDefinition	FD_STRING_SUBSTRING		= new FunctionDefinitionStringFunctions<String,String>(XACML3.ID_FUNCTION_STRING_SUBSTRING, DataTypes.DT_STRING, DataTypes.DT_STRING, FunctionDefinitionStringFunctions.OPERATION.SUBSTRING);
+	public static final FunctionDefinition	FD_ANYURI_SUBSTRING		= new FunctionDefinitionStringFunctions<String, URI>(XACML3.ID_FUNCTION_ANYURI_SUBSTRING, DataTypes.DT_STRING, DataTypes.DT_ANYURI, FunctionDefinitionStringFunctions.OPERATION.SUBSTRING);
+	
+	/*
+	 * Bag functions (See A.3.10)
+	 */
+	public static final FunctionDefinition	FD_STRING_ONE_AND_ONLY		= new FunctionDefinitionBagOneAndOnly<String>(XACML3.ID_FUNCTION_STRING_ONE_AND_ONLY, DataTypes.DT_STRING);
+	public static final FunctionDefinition	FD_BOOLEAN_ONE_AND_ONLY		= new FunctionDefinitionBagOneAndOnly<Boolean>(XACML3.ID_FUNCTION_BOOLEAN_ONE_AND_ONLY, DataTypes.DT_BOOLEAN);
+	public static final FunctionDefinition	FD_INTEGER_ONE_AND_ONLY		= new FunctionDefinitionBagOneAndOnly<BigInteger>(XACML3.ID_FUNCTION_INTEGER_ONE_AND_ONLY, DataTypes.DT_INTEGER);
+	public static final FunctionDefinition	FD_DOUBLE_ONE_AND_ONLY		= new FunctionDefinitionBagOneAndOnly<Double>(XACML3.ID_FUNCTION_DOUBLE_ONE_AND_ONLY, DataTypes.DT_DOUBLE);
+	public static final FunctionDefinition	FD_TIME_ONE_AND_ONLY		= new FunctionDefinitionBagOneAndOnly<ISO8601Time>(XACML3.ID_FUNCTION_TIME_ONE_AND_ONLY, DataTypes.DT_TIME);
+	public static final FunctionDefinition	FD_DATE_ONE_AND_ONLY		= new FunctionDefinitionBagOneAndOnly<ISO8601Date>(XACML3.ID_FUNCTION_DATE_ONE_AND_ONLY, DataTypes.DT_DATE);
+	public static final FunctionDefinition	FD_DATETIME_ONE_AND_ONLY		= new FunctionDefinitionBagOneAndOnly<ISO8601DateTime>(XACML3.ID_FUNCTION_DATETIME_ONE_AND_ONLY, DataTypes.DT_DATETIME);	
+	public static final FunctionDefinition	FD_ANYURI_ONE_AND_ONLY		= new FunctionDefinitionBagOneAndOnly<URI>(XACML3.ID_FUNCTION_ANYURI_ONE_AND_ONLY, DataTypes.DT_ANYURI);
+	public static final FunctionDefinition	FD_HEXBINARY_ONE_AND_ONLY		= new FunctionDefinitionBagOneAndOnly<HexBinary>(XACML3.ID_FUNCTION_HEXBINARY_ONE_AND_ONLY, DataTypes.DT_HEXBINARY);
+	public static final FunctionDefinition	FD_BASE64BINARY_ONE_AND_ONLY		= new FunctionDefinitionBagOneAndOnly<Base64Binary>(XACML3.ID_FUNCTION_BASE64BINARY_ONE_AND_ONLY, DataTypes.DT_BASE64BINARY);
+	public static final FunctionDefinition	FD_DAYTIMEDURATION_ONE_AND_ONLY		= new FunctionDefinitionBagOneAndOnly<XPathDayTimeDuration>(XACML3.ID_FUNCTION_DAYTIMEDURATION_ONE_AND_ONLY, DataTypes.DT_DAYTIMEDURATION);
+	public static final FunctionDefinition	FD_DAYTIMEDURATION_ONE_AND_ONLY_VERSION1		= new FunctionDefinitionBagOneAndOnly<XPathDayTimeDuration>(XACML1.ID_FUNCTION_DAYTIMEDURATION_ONE_AND_ONLY, DataTypes.DT_DAYTIMEDURATION);
+	public static final FunctionDefinition	FD_YEARMONTHDURATION_ONE_AND_ONLY		= new FunctionDefinitionBagOneAndOnly<XPathYearMonthDuration>(XACML3.ID_FUNCTION_YEARMONTHDURATION_ONE_AND_ONLY, DataTypes.DT_YEARMONTHDURATION);
+	public static final FunctionDefinition	FD_YEARMONTHDURATION_ONE_AND_ONLY_VERSION1		= new FunctionDefinitionBagOneAndOnly<XPathYearMonthDuration>(XACML1.ID_FUNCTION_YEARMONTHDURATION_ONE_AND_ONLY, DataTypes.DT_YEARMONTHDURATION);
+	public static final FunctionDefinition	FD_X500NAME_ONE_AND_ONLY		= new FunctionDefinitionBagOneAndOnly<X500Principal>(XACML3.ID_FUNCTION_X500NAME_ONE_AND_ONLY, DataTypes.DT_X500NAME);
+	public static final FunctionDefinition	FD_RFC822NAME_ONE_AND_ONLY		= new FunctionDefinitionBagOneAndOnly<RFC822Name>(XACML3.ID_FUNCTION_RFC822NAME_ONE_AND_ONLY, DataTypes.DT_RFC822NAME);
+	public static final FunctionDefinition	FD_IPADDRESS_ONE_AND_ONLY		= new FunctionDefinitionBagOneAndOnly<IPAddress>(XACML3.ID_FUNCTION_IPADDRESS_ONE_AND_ONLY, DataTypes.DT_IPADDRESS);
+	public static final FunctionDefinition	FD_DNSNAME_ONE_AND_ONLY		= new FunctionDefinitionBagOneAndOnly<RFC2396DomainName>(XACML3.ID_FUNCTION_DNSNAME_ONE_AND_ONLY, DataTypes.DT_DNSNAME);
+	
+	public static final FunctionDefinition	FD_STRING_BAG_SIZE		= new FunctionDefinitionBagSize<String>(XACML3.ID_FUNCTION_STRING_BAG_SIZE, DataTypes.DT_STRING);
+	public static final FunctionDefinition	FD_BOOLEAN_BAG_SIZE		= new FunctionDefinitionBagSize<Boolean>(XACML3.ID_FUNCTION_BOOLEAN_BAG_SIZE, DataTypes.DT_BOOLEAN);
+	public static final FunctionDefinition	FD_INTEGER_BAG_SIZE		= new FunctionDefinitionBagSize<BigInteger>(XACML3.ID_FUNCTION_INTEGER_BAG_SIZE, DataTypes.DT_INTEGER);
+	public static final FunctionDefinition	FD_DOUBLE_BAG_SIZE		= new FunctionDefinitionBagSize<Double>(XACML3.ID_FUNCTION_DOUBLE_BAG_SIZE, DataTypes.DT_DOUBLE);
+	public static final FunctionDefinition	FD_TIME_BAG_SIZE			= new FunctionDefinitionBagSize<ISO8601Time>(XACML3.ID_FUNCTION_TIME_BAG_SIZE, DataTypes.DT_TIME);
+	public static final FunctionDefinition	FD_DATE_BAG_SIZE			= new FunctionDefinitionBagSize<ISO8601Date>(XACML3.ID_FUNCTION_DATE_BAG_SIZE, DataTypes.DT_DATE);
+	public static final FunctionDefinition	FD_DATETIME_BAG_SIZE		= new FunctionDefinitionBagSize<ISO8601DateTime>(XACML3.ID_FUNCTION_DATETIME_BAG_SIZE, DataTypes.DT_DATETIME);	
+	public static final FunctionDefinition	FD_ANYURI_BAG_SIZE		= new FunctionDefinitionBagSize<URI>(XACML3.ID_FUNCTION_ANYURI_BAG_SIZE, DataTypes.DT_ANYURI);
+	public static final FunctionDefinition	FD_HEXBINARY_BAG_SIZE		= new FunctionDefinitionBagSize<HexBinary>(XACML3.ID_FUNCTION_HEXBINARY_BAG_SIZE, DataTypes.DT_HEXBINARY);
+	public static final FunctionDefinition	FD_BASE64BINARY_BAG_SIZE		= new FunctionDefinitionBagSize<Base64Binary>(XACML3.ID_FUNCTION_BASE64BINARY_BAG_SIZE, DataTypes.DT_BASE64BINARY);
+	public static final FunctionDefinition	FD_DAYTIMEDURATION_BAG_SIZE	= new FunctionDefinitionBagSize<XPathDayTimeDuration>(XACML3.ID_FUNCTION_DAYTIMEDURATION_BAG_SIZE, DataTypes.DT_DAYTIMEDURATION);
+	public static final FunctionDefinition	FD_DAYTIMEDURATION_BAG_SIZE_VERSION1		= new FunctionDefinitionBagSize<XPathDayTimeDuration>(XACML1.ID_FUNCTION_DAYTIMEDURATION_BAG_SIZE, DataTypes.DT_DAYTIMEDURATION);
+	public static final FunctionDefinition	FD_YEARMONTHDURATION_BAG_SIZE		= new FunctionDefinitionBagSize<XPathYearMonthDuration>(XACML3.ID_FUNCTION_YEARMONTHDURATION_BAG_SIZE, DataTypes.DT_YEARMONTHDURATION);
+	public static final FunctionDefinition	FD_YEARMONTHDURATION_BAG_SIZE_VERSION1		= new FunctionDefinitionBagSize<XPathYearMonthDuration>(XACML1.ID_FUNCTION_YEARMONTHDURATION_BAG_SIZE, DataTypes.DT_YEARMONTHDURATION);
+	public static final FunctionDefinition	FD_X500NAME_BAG_SIZE		= new FunctionDefinitionBagSize<X500Principal>(XACML3.ID_FUNCTION_X500NAME_BAG_SIZE, DataTypes.DT_X500NAME);
+	public static final FunctionDefinition	FD_RFC822NAME_BAG_SIZE		= new FunctionDefinitionBagSize<RFC822Name>(XACML3.ID_FUNCTION_RFC822NAME_BAG_SIZE, DataTypes.DT_RFC822NAME);
+	public static final FunctionDefinition	FD_IPADDRESS_BAG_SIZE		= new FunctionDefinitionBagSize<IPAddress>(XACML3.ID_FUNCTION_IPADDRESS_BAG_SIZE, DataTypes.DT_IPADDRESS);
+	public static final FunctionDefinition	FD_DNSNAME_BAG_SIZE		= new FunctionDefinitionBagSize<RFC2396DomainName>(XACML3.ID_FUNCTION_DNSNAME_BAG_SIZE, DataTypes.DT_DNSNAME);
+	
+	public static final FunctionDefinition	FD_STRING_IS_IN		= new FunctionDefinitionBagIsIn<String>(XACML3.ID_FUNCTION_STRING_IS_IN, DataTypes.DT_STRING);
+	public static final FunctionDefinition	FD_BOOLEAN_IS_IN		= new FunctionDefinitionBagIsIn<Boolean>(XACML3.ID_FUNCTION_BOOLEAN_IS_IN, DataTypes.DT_BOOLEAN);
+	public static final FunctionDefinition	FD_INTEGER_IS_IN		= new FunctionDefinitionBagIsIn<BigInteger>(XACML3.ID_FUNCTION_INTEGER_IS_IN, DataTypes.DT_INTEGER);
+	public static final FunctionDefinition	FD_DOUBLE_IS_IN		= new FunctionDefinitionBagIsIn<Double>(XACML3.ID_FUNCTION_DOUBLE_IS_IN, DataTypes.DT_DOUBLE);
+	public static final FunctionDefinition	FD_TIME_IS_IN			= new FunctionDefinitionBagIsIn<ISO8601Time>(XACML3.ID_FUNCTION_TIME_IS_IN, DataTypes.DT_TIME);
+	public static final FunctionDefinition	FD_DATE_IS_IN			= new FunctionDefinitionBagIsIn<ISO8601Date>(XACML3.ID_FUNCTION_DATE_IS_IN, DataTypes.DT_DATE);
+	public static final FunctionDefinition	FD_DATETIME_IS_IN		= new FunctionDefinitionBagIsIn<ISO8601DateTime>(XACML3.ID_FUNCTION_DATETIME_IS_IN, DataTypes.DT_DATETIME);	
+	public static final FunctionDefinition	FD_ANYURI_IS_IN		= new FunctionDefinitionBagIsIn<URI>(XACML3.ID_FUNCTION_ANYURI_IS_IN, DataTypes.DT_ANYURI);
+	public static final FunctionDefinition	FD_HEXBINARY_IS_IN		= new FunctionDefinitionBagIsIn<HexBinary>(XACML3.ID_FUNCTION_HEXBINARY_IS_IN, DataTypes.DT_HEXBINARY);
+	public static final FunctionDefinition	FD_BASE64BINARY_IS_IN		= new FunctionDefinitionBagIsIn<Base64Binary>(XACML3.ID_FUNCTION_BASE64BINARY_IS_IN, DataTypes.DT_BASE64BINARY);
+	public static final FunctionDefinition	FD_DAYTIMEDURATION_IS_IN	= new FunctionDefinitionBagIsIn<XPathDayTimeDuration>(XACML3.ID_FUNCTION_DAYTIMEDURATION_IS_IN, DataTypes.DT_DAYTIMEDURATION);
+	public static final FunctionDefinition	FD_DAYTIMEDURATION_IS_IN_VERSION1		= new FunctionDefinitionBagIsIn<XPathDayTimeDuration>(XACML1.ID_FUNCTION_DAYTIMEDURATION_IS_IN, DataTypes.DT_DAYTIMEDURATION);
+	public static final FunctionDefinition	FD_YEARMONTHDURATION_IS_IN		= new FunctionDefinitionBagIsIn<XPathYearMonthDuration>(XACML3.ID_FUNCTION_YEARMONTHDURATION_IS_IN, DataTypes.DT_YEARMONTHDURATION);
+	public static final FunctionDefinition	FD_YEARMONTHDURATION_IS_IN_VERSION1		= new FunctionDefinitionBagIsIn<XPathYearMonthDuration>(XACML1.ID_FUNCTION_YEARMONTHDURATION_IS_IN, DataTypes.DT_YEARMONTHDURATION);
+	public static final FunctionDefinition	FD_X500NAME_IS_IN		= new FunctionDefinitionBagIsIn<X500Principal>(XACML3.ID_FUNCTION_X500NAME_IS_IN, DataTypes.DT_X500NAME);
+	public static final FunctionDefinition	FD_RFC822NAME_IS_IN		= new FunctionDefinitionBagIsIn<RFC822Name>(XACML3.ID_FUNCTION_RFC822NAME_IS_IN, DataTypes.DT_RFC822NAME);
+	public static final FunctionDefinition	FD_IPADDRESS_IS_IN		= new FunctionDefinitionBagIsIn<IPAddress>(XACML3.ID_FUNCTION_IPADDRESS_IS_IN, DataTypes.DT_IPADDRESS);
+	public static final FunctionDefinition	FD_DNSNAME_IS_IN		= new FunctionDefinitionBagIsIn<RFC2396DomainName>(XACML3.ID_FUNCTION_DNSNAME_IS_IN, DataTypes.DT_DNSNAME);
+	
+	public static final FunctionDefinition	FD_STRING_BAG		= new FunctionDefinitionBag<String>(XACML3.ID_FUNCTION_STRING_BAG, DataTypes.DT_STRING);
+	public static final FunctionDefinition	FD_BOOLEAN_BAG		= new FunctionDefinitionBag<Boolean>(XACML3.ID_FUNCTION_BOOLEAN_BAG, DataTypes.DT_BOOLEAN);
+	public static final FunctionDefinition	FD_INTEGER_BAG		= new FunctionDefinitionBag<BigInteger>(XACML3.ID_FUNCTION_INTEGER_BAG, DataTypes.DT_INTEGER);
+	public static final FunctionDefinition	FD_DOUBLE_BAG		= new FunctionDefinitionBag<Double>(XACML3.ID_FUNCTION_DOUBLE_BAG, DataTypes.DT_DOUBLE);
+	public static final FunctionDefinition	FD_TIME_BAG			= new FunctionDefinitionBag<ISO8601Time>(XACML3.ID_FUNCTION_TIME_BAG, DataTypes.DT_TIME);
+	public static final FunctionDefinition	FD_DATE_BAG			= new FunctionDefinitionBag<ISO8601Date>(XACML3.ID_FUNCTION_DATE_BAG, DataTypes.DT_DATE);
+	public static final FunctionDefinition	FD_DATETIME_BAG		= new FunctionDefinitionBag<ISO8601DateTime>(XACML3.ID_FUNCTION_DATETIME_BAG, DataTypes.DT_DATETIME);	
+	public static final FunctionDefinition	FD_ANYURI_BAG		= new FunctionDefinitionBag<URI>(XACML3.ID_FUNCTION_ANYURI_BAG, DataTypes.DT_ANYURI);
+	public static final FunctionDefinition	FD_HEXBINARY_BAG		= new FunctionDefinitionBag<HexBinary>(XACML3.ID_FUNCTION_HEXBINARY_BAG, DataTypes.DT_HEXBINARY);
+	public static final FunctionDefinition	FD_BASE64BINARY_BAG		= new FunctionDefinitionBag<Base64Binary>(XACML3.ID_FUNCTION_BASE64BINARY_BAG, DataTypes.DT_BASE64BINARY);
+	public static final FunctionDefinition	FD_DAYTIMEDURATION_BAG	= new FunctionDefinitionBag<XPathDayTimeDuration>(XACML3.ID_FUNCTION_DAYTIMEDURATION_BAG, DataTypes.DT_DAYTIMEDURATION);
+	public static final FunctionDefinition	FD_DAYTIMEDURATION_BAG_VERSION1		= new FunctionDefinitionBag<XPathDayTimeDuration>(XACML1.ID_FUNCTION_DAYTIMEDURATION_BAG, DataTypes.DT_DAYTIMEDURATION);
+	public static final FunctionDefinition	FD_YEARMONTHDURATION_BAG		= new FunctionDefinitionBag<XPathYearMonthDuration>(XACML3.ID_FUNCTION_YEARMONTHDURATION_BAG, DataTypes.DT_YEARMONTHDURATION);
+	public static final FunctionDefinition	FD_YEARMONTHDURATION_BAG_VERSION1		= new FunctionDefinitionBag<XPathYearMonthDuration>(XACML1.ID_FUNCTION_YEARMONTHDURATION_BAG, DataTypes.DT_YEARMONTHDURATION);
+	public static final FunctionDefinition	FD_X500NAME_BAG		= new FunctionDefinitionBag<X500Principal>(XACML3.ID_FUNCTION_X500NAME_BAG, DataTypes.DT_X500NAME);
+	public static final FunctionDefinition	FD_RFC822NAME_BAG		= new FunctionDefinitionBag<RFC822Name>(XACML3.ID_FUNCTION_RFC822NAME_BAG, DataTypes.DT_RFC822NAME);
+	public static final FunctionDefinition	FD_IPADDRESS_BAG		= new FunctionDefinitionBag<IPAddress>(XACML3.ID_FUNCTION_IPADDRESS_BAG, DataTypes.DT_IPADDRESS);
+	public static final FunctionDefinition	FD_DNSNAME_BAG		= new FunctionDefinitionBag<RFC2396DomainName>(XACML3.ID_FUNCTION_DNSNAME_BAG, DataTypes.DT_DNSNAME);
+
+	
+	/*
+	 * Set Functions (See A.3.11)
+	 * 
+	 * (According to section 10.2.8, this doesn't seem to include
+	 * IPAddress or DNSName datatype). This is because Xacml 3.0 did NOT
+	 * define an equality operator for these 2 types. See discussion:
+	 * 
+	 * https://lists.oasis-open.org/archives/xacml/201104/msg00014.html
+	 * 
+	 * Also section 10.2.8 is missing XPathExpression versions of these functions.
+	 * 
+	 */
+	public static final FunctionDefinition	FD_STRING_INTERSECTION			= new FunctionDefinitionSet<String,String>(XACML3.ID_FUNCTION_STRING_INTERSECTION, DataTypes.DT_STRING, DataTypes.DT_STRING, FunctionDefinitionSet.OPERATION.INTERSECTION);
+	public static final FunctionDefinition	FD_BOOLEAN_INTERSECTION			= new FunctionDefinitionSet<Boolean,Boolean>(XACML3.ID_FUNCTION_BOOLEAN_INTERSECTION, DataTypes.DT_BOOLEAN, DataTypes.DT_BOOLEAN, FunctionDefinitionSet.OPERATION.INTERSECTION);
+	public static final FunctionDefinition	FD_INTEGER_INTERSECTION			= new FunctionDefinitionSet<BigInteger,BigInteger>(XACML3.ID_FUNCTION_INTEGER_INTERSECTION, DataTypes.DT_INTEGER, DataTypes.DT_INTEGER, FunctionDefinitionSet.OPERATION.INTERSECTION);
+	public static final FunctionDefinition	FD_DOUBLE_INTERSECTION			= new FunctionDefinitionSet<Double,Double>(XACML3.ID_FUNCTION_DOUBLE_INTERSECTION, DataTypes.DT_DOUBLE, DataTypes.DT_DOUBLE, FunctionDefinitionSet.OPERATION.INTERSECTION);
+	public static final FunctionDefinition	FD_TIME_INTERSECTION			= new FunctionDefinitionSet<ISO8601Time,ISO8601Time>(XACML3.ID_FUNCTION_TIME_INTERSECTION, DataTypes.DT_TIME, DataTypes.DT_TIME, FunctionDefinitionSet.OPERATION.INTERSECTION);
+	public static final FunctionDefinition	FD_DATE_INTERSECTION			= new FunctionDefinitionSet<ISO8601Date,ISO8601Date>(XACML3.ID_FUNCTION_DATE_INTERSECTION, DataTypes.DT_DATE, DataTypes.DT_DATE, FunctionDefinitionSet.OPERATION.INTERSECTION);
+	public static final FunctionDefinition	FD_DATETIME_INTERSECTION		= new FunctionDefinitionSet<ISO8601DateTime, ISO8601DateTime>(XACML3.ID_FUNCTION_DATETIME_INTERSECTION, DataTypes.DT_DATETIME, DataTypes.DT_DATETIME, FunctionDefinitionSet.OPERATION.INTERSECTION);
+	public static final FunctionDefinition	FD_ANYURI_INTERSECTION			= new FunctionDefinitionSet<URI, URI>(XACML3.ID_FUNCTION_ANYURI_INTERSECTION, DataTypes.DT_ANYURI, DataTypes.DT_ANYURI, FunctionDefinitionSet.OPERATION.INTERSECTION);
+	public static final FunctionDefinition	FD_HEXBINARY_INTERSECTION		= new FunctionDefinitionSet<HexBinary,HexBinary>(XACML3.ID_FUNCTION_HEXBINARY_INTERSECTION, DataTypes.DT_HEXBINARY, DataTypes.DT_HEXBINARY, FunctionDefinitionSet.OPERATION.INTERSECTION);
+	public static final FunctionDefinition	FD_BASE64BINARY_INTERSECTION		= new FunctionDefinitionSet<Base64Binary,Base64Binary>(XACML3.ID_FUNCTION_BASE64BINARY_INTERSECTION, DataTypes.DT_BASE64BINARY, DataTypes.DT_BASE64BINARY, FunctionDefinitionSet.OPERATION.INTERSECTION);
+	public static final FunctionDefinition	FD_DAYTIMEDURATION_INTERSECTION		= new FunctionDefinitionSet<XPathDayTimeDuration,XPathDayTimeDuration>(XACML3.ID_FUNCTION_DAYTIMEDURATION_INTERSECTION, DataTypes.DT_DAYTIMEDURATION, DataTypes.DT_DAYTIMEDURATION, FunctionDefinitionSet.OPERATION.INTERSECTION);
+	public static final FunctionDefinition	FD_DAYTIMEDURATION_INTERSECTION_VERSION1	= new FunctionDefinitionSet<XPathDayTimeDuration,XPathDayTimeDuration>(XACML1.ID_FUNCTION_DAYTIMEDURATION_INTERSECTION, DataTypes.DT_DAYTIMEDURATION, DataTypes.DT_DAYTIMEDURATION, FunctionDefinitionSet.OPERATION.INTERSECTION);
+	public static final FunctionDefinition	FD_YEARMONTHDURATION_INTERSECTION	= new FunctionDefinitionSet<XPathYearMonthDuration,XPathYearMonthDuration>(XACML3.ID_FUNCTION_YEARMONTHDURATION_INTERSECTION, DataTypes.DT_YEARMONTHDURATION, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionSet.OPERATION.INTERSECTION);
+	public static final FunctionDefinition	FD_YEARMONTHDURATION_INTERSECTION_VERSION1	= new FunctionDefinitionSet<XPathYearMonthDuration,XPathYearMonthDuration>(XACML1.ID_FUNCTION_YEARMONTHDURATION_INTERSECTION, DataTypes.DT_YEARMONTHDURATION, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionSet.OPERATION.INTERSECTION);
+	public static final FunctionDefinition	FD_X500NAME_INTERSECTION			= new FunctionDefinitionSet<X500Principal,X500Principal>(XACML3.ID_FUNCTION_X500NAME_INTERSECTION, DataTypes.DT_X500NAME, DataTypes.DT_X500NAME, FunctionDefinitionSet.OPERATION.INTERSECTION);
+	public static final FunctionDefinition	FD_RFC822NAME_INTERSECTION			= new FunctionDefinitionSet<RFC822Name,RFC822Name>(XACML3.ID_FUNCTION_RFC822NAME_INTERSECTION, DataTypes.DT_RFC822NAME, DataTypes.DT_RFC822NAME, FunctionDefinitionSet.OPERATION.INTERSECTION);
+
+	public static final FunctionDefinition	FD_STRING_AT_LEAST_ONE_MEMBER_OF		= new FunctionDefinitionSet<Boolean,String>(XACML3.ID_FUNCTION_STRING_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_STRING, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF);
+	public static final FunctionDefinition	FD_BOOLEAN_AT_LEAST_ONE_MEMBER_OF		= new FunctionDefinitionSet<Boolean,Boolean>(XACML3.ID_FUNCTION_BOOLEAN_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_BOOLEAN, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF);
+	public static final FunctionDefinition	FD_INTEGER_AT_LEAST_ONE_MEMBER_OF		= new FunctionDefinitionSet<Boolean,BigInteger>(XACML3.ID_FUNCTION_INTEGER_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_INTEGER, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF);
+	public static final FunctionDefinition	FD_DOUBLE_AT_LEAST_ONE_MEMBER_OF		= new FunctionDefinitionSet<Boolean,Double>(XACML3.ID_FUNCTION_DOUBLE_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_DOUBLE, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF);
+	public static final FunctionDefinition	FD_TIME_AT_LEAST_ONE_MEMBER_OF			= new FunctionDefinitionSet<Boolean,ISO8601Time>(XACML3.ID_FUNCTION_TIME_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_TIME, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF);
+	public static final FunctionDefinition	FD_DATE_AT_LEAST_ONE_MEMBER_OF			= new FunctionDefinitionSet<Boolean,ISO8601Date>(XACML3.ID_FUNCTION_DATE_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_DATE, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF);
+	public static final FunctionDefinition	FD_DATETIME_AT_LEAST_ONE_MEMBER_OF		= new FunctionDefinitionSet<Boolean, ISO8601DateTime>(XACML3.ID_FUNCTION_DATETIME_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_DATETIME, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF);
+	public static final FunctionDefinition	FD_ANYURI_AT_LEAST_ONE_MEMBER_OF		= new FunctionDefinitionSet<Boolean, URI>(XACML3.ID_FUNCTION_ANYURI_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_ANYURI, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF);
+	public static final FunctionDefinition	FD_HEXBINARY_AT_LEAST_ONE_MEMBER_OF		= new FunctionDefinitionSet<Boolean,HexBinary>(XACML3.ID_FUNCTION_HEXBINARY_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_HEXBINARY, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF);
+	public static final FunctionDefinition	FD_BASE64BINARY_AT_LEAST_ONE_MEMBER_OF		= new FunctionDefinitionSet<Boolean,Base64Binary>(XACML3.ID_FUNCTION_BASE64BINARY_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_BASE64BINARY, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF);
+	public static final FunctionDefinition	FD_DAYTIMEDURATION_AT_LEAST_ONE_MEMBER_OF	= new FunctionDefinitionSet<Boolean,XPathDayTimeDuration>(XACML3.ID_FUNCTION_DAYTIMEDURATION_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_DAYTIMEDURATION, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF);
+	public static final FunctionDefinition	FD_DAYTIMEDURATION_AT_LEAST_ONE_MEMBER_OF_VERSION1	= new FunctionDefinitionSet<Boolean,XPathDayTimeDuration>(XACML1.ID_FUNCTION_DAYTIMEDURATION_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_DAYTIMEDURATION, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF);
+	public static final FunctionDefinition	FD_YEARMONTHDURATION_AT_LEAST_ONE_MEMBER_OF	= new FunctionDefinitionSet<Boolean,XPathYearMonthDuration>(XACML3.ID_FUNCTION_YEARMONTHDURATION_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF);
+	public static final FunctionDefinition	FD_YEARMONTHDURATION_AT_LEAST_ONE_MEMBER_OF_VERSION1	= new FunctionDefinitionSet<Boolean,XPathYearMonthDuration>(XACML1.ID_FUNCTION_YEARMONTHDURATION_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF);
+	public static final FunctionDefinition	FD_X500NAME_AT_LEAST_ONE_MEMBER_OF			= new FunctionDefinitionSet<Boolean,X500Principal>(XACML3.ID_FUNCTION_X500NAME_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_X500NAME, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF);
+	public static final FunctionDefinition	FD_RFC822NAME_AT_LEAST_ONE_MEMBER_OF		= new FunctionDefinitionSet<Boolean,RFC822Name>(XACML3.ID_FUNCTION_RFC822NAME_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_RFC822NAME, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF);
+
+	public static final FunctionDefinition	FD_STRING_UNION			= new FunctionDefinitionSet<String,String>(XACML3.ID_FUNCTION_STRING_UNION, DataTypes.DT_STRING, DataTypes.DT_STRING, FunctionDefinitionSet.OPERATION.UNION);
+	public static final FunctionDefinition	FD_BOOLEAN_UNION		= new FunctionDefinitionSet<Boolean,Boolean>(XACML3.ID_FUNCTION_BOOLEAN_UNION, DataTypes.DT_BOOLEAN, DataTypes.DT_BOOLEAN, FunctionDefinitionSet.OPERATION.UNION);
+	public static final FunctionDefinition	FD_INTEGER_UNION		= new FunctionDefinitionSet<BigInteger,BigInteger>(XACML3.ID_FUNCTION_INTEGER_UNION, DataTypes.DT_INTEGER, DataTypes.DT_INTEGER, FunctionDefinitionSet.OPERATION.UNION);
+	public static final FunctionDefinition	FD_DOUBLE_UNION			= new FunctionDefinitionSet<Double,Double>(XACML3.ID_FUNCTION_DOUBLE_UNION, DataTypes.DT_DOUBLE, DataTypes.DT_DOUBLE, FunctionDefinitionSet.OPERATION.UNION);
+	public static final FunctionDefinition	FD_TIME_UNION			= new FunctionDefinitionSet<ISO8601Time,ISO8601Time>(XACML3.ID_FUNCTION_TIME_UNION, DataTypes.DT_TIME, DataTypes.DT_TIME, FunctionDefinitionSet.OPERATION.UNION);
+	public static final FunctionDefinition	FD_DATE_UNION			= new FunctionDefinitionSet<ISO8601Date,ISO8601Date>(XACML3.ID_FUNCTION_DATE_UNION, DataTypes.DT_DATE, DataTypes.DT_DATE, FunctionDefinitionSet.OPERATION.UNION);
+	public static final FunctionDefinition	FD_DATETIME_UNION		= new FunctionDefinitionSet<ISO8601DateTime, ISO8601DateTime>(XACML3.ID_FUNCTION_DATETIME_UNION, DataTypes.DT_DATETIME, DataTypes.DT_DATETIME, FunctionDefinitionSet.OPERATION.UNION);
+	public static final FunctionDefinition	FD_ANYURI_UNION			= new FunctionDefinitionSet<URI, URI>(XACML3.ID_FUNCTION_ANYURI_UNION, DataTypes.DT_ANYURI, DataTypes.DT_ANYURI, FunctionDefinitionSet.OPERATION.UNION);
+	public static final FunctionDefinition	FD_HEXBINARY_UNION		= new FunctionDefinitionSet<HexBinary,HexBinary>(XACML3.ID_FUNCTION_HEXBINARY_UNION, DataTypes.DT_HEXBINARY, DataTypes.DT_HEXBINARY, FunctionDefinitionSet.OPERATION.UNION);
+	public static final FunctionDefinition	FD_BASE64BINARY_UNION		= new FunctionDefinitionSet<Base64Binary,Base64Binary>(XACML3.ID_FUNCTION_BASE64BINARY_UNION, DataTypes.DT_BASE64BINARY, DataTypes.DT_BASE64BINARY, FunctionDefinitionSet.OPERATION.UNION);
+	public static final FunctionDefinition	FD_DAYTIMEDURATION_UNION	= new FunctionDefinitionSet<XPathDayTimeDuration,XPathDayTimeDuration>(XACML3.ID_FUNCTION_DAYTIMEDURATION_UNION, DataTypes.DT_DAYTIMEDURATION, DataTypes.DT_DAYTIMEDURATION, FunctionDefinitionSet.OPERATION.UNION);
+	public static final FunctionDefinition	FD_DAYTIMEDURATION_UNION_VERSION1	= new FunctionDefinitionSet<XPathDayTimeDuration,XPathDayTimeDuration>(XACML1.ID_FUNCTION_DAYTIMEDURATION_UNION, DataTypes.DT_DAYTIMEDURATION, DataTypes.DT_DAYTIMEDURATION, FunctionDefinitionSet.OPERATION.UNION);
+	public static final FunctionDefinition	FD_YEARMONTHDURATION_UNION	= new FunctionDefinitionSet<XPathYearMonthDuration,XPathYearMonthDuration>(XACML3.ID_FUNCTION_YEARMONTHDURATION_UNION, DataTypes.DT_YEARMONTHDURATION, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionSet.OPERATION.UNION);
+	public static final FunctionDefinition	FD_YEARMONTHDURATION_UNION_VERSION1	= new FunctionDefinitionSet<XPathYearMonthDuration,XPathYearMonthDuration>(XACML1.ID_FUNCTION_YEARMONTHDURATION_UNION, DataTypes.DT_YEARMONTHDURATION, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionSet.OPERATION.UNION);
+	public static final FunctionDefinition	FD_X500NAME_UNION		= new FunctionDefinitionSet<X500Principal,X500Principal>(XACML3.ID_FUNCTION_X500NAME_UNION, DataTypes.DT_X500NAME, DataTypes.DT_X500NAME, FunctionDefinitionSet.OPERATION.UNION);
+	public static final FunctionDefinition	FD_RFC822NAME_UNION		= new FunctionDefinitionSet<RFC822Name,RFC822Name>(XACML3.ID_FUNCTION_RFC822NAME_UNION, DataTypes.DT_RFC822NAME, DataTypes.DT_RFC822NAME, FunctionDefinitionSet.OPERATION.UNION);
+
+	public static final FunctionDefinition	FD_STRING_SUBSET		= new FunctionDefinitionSet<Boolean,String>(XACML3.ID_FUNCTION_STRING_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_STRING, FunctionDefinitionSet.OPERATION.SUBSET);
+	public static final FunctionDefinition	FD_BOOLEAN_SUBSET		= new FunctionDefinitionSet<Boolean,Boolean>(XACML3.ID_FUNCTION_BOOLEAN_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_BOOLEAN, FunctionDefinitionSet.OPERATION.SUBSET);
+	public static final FunctionDefinition	FD_INTEGER_SUBSET		= new FunctionDefinitionSet<Boolean,BigInteger>(XACML3.ID_FUNCTION_INTEGER_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_INTEGER, FunctionDefinitionSet.OPERATION.SUBSET);
+	public static final FunctionDefinition	FD_DOUBLE_SUBSET		= new FunctionDefinitionSet<Boolean,Double>(XACML3.ID_FUNCTION_DOUBLE_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_DOUBLE, FunctionDefinitionSet.OPERATION.SUBSET);
+	public static final FunctionDefinition	FD_TIME_SUBSET			= new FunctionDefinitionSet<Boolean,ISO8601Time>(XACML3.ID_FUNCTION_TIME_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_TIME, FunctionDefinitionSet.OPERATION.SUBSET);
+	public static final FunctionDefinition	FD_DATE_SUBSET			= new FunctionDefinitionSet<Boolean,ISO8601Date>(XACML3.ID_FUNCTION_DATE_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_DATE, FunctionDefinitionSet.OPERATION.SUBSET);
+	public static final FunctionDefinition	FD_DATETIME_SUBSET		= new FunctionDefinitionSet<Boolean, ISO8601DateTime>(XACML3.ID_FUNCTION_DATETIME_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_DATETIME, FunctionDefinitionSet.OPERATION.SUBSET);
+	public static final FunctionDefinition	FD_ANYURI_SUBSET		= new FunctionDefinitionSet<Boolean, URI>(XACML3.ID_FUNCTION_ANYURI_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_ANYURI, FunctionDefinitionSet.OPERATION.SUBSET);
+	public static final FunctionDefinition	FD_HEXBINARY_SUBSET		= new FunctionDefinitionSet<Boolean,HexBinary>(XACML3.ID_FUNCTION_HEXBINARY_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_HEXBINARY, FunctionDefinitionSet.OPERATION.SUBSET);
+	public static final FunctionDefinition	FD_BASE64BINARY_SUBSET		= new FunctionDefinitionSet<Boolean,Base64Binary>(XACML3.ID_FUNCTION_BASE64BINARY_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_BASE64BINARY, FunctionDefinitionSet.OPERATION.SUBSET);
+	public static final FunctionDefinition	FD_DAYTIMEDURATION_SUBSET	= new FunctionDefinitionSet<Boolean,XPathDayTimeDuration>(XACML3.ID_FUNCTION_DAYTIMEDURATION_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_DAYTIMEDURATION, FunctionDefinitionSet.OPERATION.SUBSET);
+	public static final FunctionDefinition	FD_DAYTIMEDURATION_SUBSET_VERSION1	= new FunctionDefinitionSet<Boolean,XPathDayTimeDuration>(XACML1.ID_FUNCTION_DAYTIMEDURATION_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_DAYTIMEDURATION, FunctionDefinitionSet.OPERATION.SUBSET);
+	public static final FunctionDefinition	FD_YEARMONTHDURATION_SUBSET	= new FunctionDefinitionSet<Boolean,XPathYearMonthDuration>(XACML3.ID_FUNCTION_YEARMONTHDURATION_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionSet.OPERATION.SUBSET);
+	public static final FunctionDefinition	FD_YEARMONTHDURATION_SUBSET_VERSION1	= new FunctionDefinitionSet<Boolean,XPathYearMonthDuration>(XACML1.ID_FUNCTION_YEARMONTHDURATION_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionSet.OPERATION.SUBSET);
+	public static final FunctionDefinition	FD_X500NAME_SUBSET			= new FunctionDefinitionSet<Boolean,X500Principal>(XACML3.ID_FUNCTION_X500NAME_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_X500NAME, FunctionDefinitionSet.OPERATION.SUBSET);
+	public static final FunctionDefinition	FD_RFC822NAME_SUBSET		= new FunctionDefinitionSet<Boolean,RFC822Name>(XACML3.ID_FUNCTION_RFC822NAME_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_RFC822NAME, FunctionDefinitionSet.OPERATION.SUBSET);
+
+	public static final FunctionDefinition	FD_STRING_SET_EQUALS		= new FunctionDefinitionSet<Boolean,String>(XACML3.ID_FUNCTION_STRING_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_STRING, FunctionDefinitionSet.OPERATION.SET_EQUALS);
+	public static final FunctionDefinition	FD_BOOLEAN_SET_EQUALS		= new FunctionDefinitionSet<Boolean,Boolean>(XACML3.ID_FUNCTION_BOOLEAN_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_BOOLEAN, FunctionDefinitionSet.OPERATION.SET_EQUALS);
+	public static final FunctionDefinition	FD_INTEGER_SET_EQUALS		= new FunctionDefinitionSet<Boolean,BigInteger>(XACML3.ID_FUNCTION_INTEGER_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_INTEGER, FunctionDefinitionSet.OPERATION.SET_EQUALS);
+	public static final FunctionDefinition	FD_DOUBLE_SET_EQUALS		= new FunctionDefinitionSet<Boolean,Double>(XACML3.ID_FUNCTION_DOUBLE_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_DOUBLE, FunctionDefinitionSet.OPERATION.SET_EQUALS);
+	public static final FunctionDefinition	FD_TIME_SET_EQUALS			= new FunctionDefinitionSet<Boolean,ISO8601Time>(XACML3.ID_FUNCTION_TIME_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_TIME, FunctionDefinitionSet.OPERATION.SET_EQUALS);
+	public static final FunctionDefinition	FD_DATE_SET_EQUALS			= new FunctionDefinitionSet<Boolean,ISO8601Date>(XACML3.ID_FUNCTION_DATE_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_DATE, FunctionDefinitionSet.OPERATION.SET_EQUALS);
+	public static final FunctionDefinition	FD_DATETIME_SET_EQUALS		= new FunctionDefinitionSet<Boolean, ISO8601DateTime>(XACML3.ID_FUNCTION_DATETIME_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_DATETIME, FunctionDefinitionSet.OPERATION.SET_EQUALS);
+	public static final FunctionDefinition	FD_ANYURI_SET_EQUALS		= new FunctionDefinitionSet<Boolean, URI>(XACML3.ID_FUNCTION_ANYURI_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_ANYURI, FunctionDefinitionSet.OPERATION.SET_EQUALS);
+	public static final FunctionDefinition	FD_HEXBINARY_SET_EQUALS		= new FunctionDefinitionSet<Boolean,HexBinary>(XACML3.ID_FUNCTION_HEXBINARY_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_HEXBINARY, FunctionDefinitionSet.OPERATION.SET_EQUALS);
+	public static final FunctionDefinition	FD_BASE64BINARY_SET_EQUALS		= new FunctionDefinitionSet<Boolean,Base64Binary>(XACML3.ID_FUNCTION_BASE64BINARY_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_BASE64BINARY, FunctionDefinitionSet.OPERATION.SET_EQUALS);
+	public static final FunctionDefinition	FD_DAYTIMEDURATION_SET_EQUALS	= new FunctionDefinitionSet<Boolean,XPathDayTimeDuration>(XACML3.ID_FUNCTION_DAYTIMEDURATION_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_DAYTIMEDURATION, FunctionDefinitionSet.OPERATION.SET_EQUALS);
+	public static final FunctionDefinition	FD_DAYTIMEDURATION_SET_EQUALS_VERSION1	= new FunctionDefinitionSet<Boolean,XPathDayTimeDuration>(XACML1.ID_FUNCTION_DAYTIMEDURATION_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_DAYTIMEDURATION, FunctionDefinitionSet.OPERATION.SET_EQUALS);
+	public static final FunctionDefinition	FD_YEARMONTHDURATION_SET_EQUALS	= new FunctionDefinitionSet<Boolean,XPathYearMonthDuration>(XACML3.ID_FUNCTION_YEARMONTHDURATION_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionSet.OPERATION.SET_EQUALS);
+	public static final FunctionDefinition	FD_YEARMONTHDURATION_SET_EQUALS_VERSION1	= new FunctionDefinitionSet<Boolean,XPathYearMonthDuration>(XACML1.ID_FUNCTION_YEARMONTHDURATION_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionSet.OPERATION.SET_EQUALS);
+	public static final FunctionDefinition	FD_X500NAME_SET_EQUALS			= new FunctionDefinitionSet<Boolean,X500Principal>(XACML3.ID_FUNCTION_X500NAME_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_X500NAME, FunctionDefinitionSet.OPERATION.SET_EQUALS);
+	public static final FunctionDefinition	FD_RFC822NAME_SET_EQUALS		= new FunctionDefinitionSet<Boolean,RFC822Name>(XACML3.ID_FUNCTION_RFC822NAME_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_RFC822NAME, FunctionDefinitionSet.OPERATION.SET_EQUALS);
+
+	
+	/*
+	 * Higher Order Bag functions (See A.3.12)
+	 */
+	public static final FunctionDefinition	FD_ANY_OF		= new FunctionDefinitionHigherOrderBag<Boolean,Object>(XACML3.ID_FUNCTION_ANY_OF, DataTypes.DT_BOOLEAN, null, FunctionDefinitionHigherOrderBag.OPERATION.ANY_OF);
+	public static final FunctionDefinition	FD_ANY_OF_VERSION1	= new FunctionDefinitionHigherOrderBag<Boolean,Object>(XACML1.ID_FUNCTION_ANY_OF, DataTypes.DT_BOOLEAN, null, FunctionDefinitionHigherOrderBag.OPERATION.ANY_OF);
+	public static final FunctionDefinition	FD_ALL_OF		= new FunctionDefinitionHigherOrderBag<Boolean,Object>(XACML3.ID_FUNCTION_ALL_OF, DataTypes.DT_BOOLEAN, null, FunctionDefinitionHigherOrderBag.OPERATION.ALL_OF);
+	public static final FunctionDefinition	FD_ALL_OF_VERSION1	= new FunctionDefinitionHigherOrderBag<Boolean,Object>(XACML1.ID_FUNCTION_ALL_OF, DataTypes.DT_BOOLEAN, null, FunctionDefinitionHigherOrderBag.OPERATION.ALL_OF);
+	public static final FunctionDefinition	FD_ANY_OF_ANY	= new FunctionDefinitionHigherOrderBag<Boolean,Object>(XACML3.ID_FUNCTION_ANY_OF_ANY, DataTypes.DT_BOOLEAN, null, FunctionDefinitionHigherOrderBag.OPERATION.ANY_OF_ANY);
+	public static final FunctionDefinition	FD_ANY_OF_ANY_VERSION1	= new FunctionDefinitionHigherOrderBag<Boolean,Object>(XACML1.ID_FUNCTION_ANY_OF_ANY, DataTypes.DT_BOOLEAN, null, FunctionDefinitionHigherOrderBag.OPERATION.ANY_OF_ANY);
+	public static final FunctionDefinition	FD_ALL_OF_ANY	= new FunctionDefinitionHigherOrderBag<Boolean,Object>(XACML3.ID_FUNCTION_ALL_OF_ANY, DataTypes.DT_BOOLEAN, null, FunctionDefinitionHigherOrderBag.OPERATION.ALL_OF_ANY);
+	public static final FunctionDefinition	FD_ANY_OF_ALL	= new FunctionDefinitionHigherOrderBag<Boolean,Object>(XACML3.ID_FUNCTION_ANY_OF_ALL, DataTypes.DT_BOOLEAN, null, FunctionDefinitionHigherOrderBag.OPERATION.ANY_OF_ALL);
+	public static final FunctionDefinition	FD_ALL_OF_ALL	= new FunctionDefinitionHigherOrderBag<Boolean,Object>(XACML3.ID_FUNCTION_ALL_OF_ALL, DataTypes.DT_BOOLEAN, null, FunctionDefinitionHigherOrderBag.OPERATION.ALL_OF_ALL);
+	public static final FunctionDefinition	FD_MAP			= new FunctionDefinitionHigherOrderBag<Object,Object>(XACML3.ID_FUNCTION_MAP, null, null, FunctionDefinitionHigherOrderBag.OPERATION.MAP);
+	public static final FunctionDefinition	FD_MAP_VERSION1	= new FunctionDefinitionHigherOrderBag<Object,Object>(XACML1.ID_FUNCTION_MAP, null, null, FunctionDefinitionHigherOrderBag.OPERATION.MAP);
+
+	
+	/*
+	 * Regular Expression functions (See A.3.13)
+	 */
+	public static final FunctionDefinition	FD_STRING_REGEXP_MATCH		= new FunctionDefinitionRegexpMatch<String>(XACML3.ID_FUNCTION_STRING_REGEXP_MATCH, DataTypes.DT_STRING);
+	public static final FunctionDefinition	FD_ANYURI_REGEXP_MATCH		= new FunctionDefinitionRegexpMatch<URI>(XACML3.ID_FUNCTION_ANYURI_REGEXP_MATCH, DataTypes.DT_ANYURI);
+	public static final FunctionDefinition	FD_IPADDRESS_REGEXP_MATCH	= new FunctionDefinitionRegexpMatch<IPAddress>(XACML3.ID_FUNCTION_IPADDRESS_REGEXP_MATCH, DataTypes.DT_IPADDRESS);
+	public static final FunctionDefinition	FD_DNSNAME_REGEXP_MATCH		= new FunctionDefinitionRegexpMatch<RFC2396DomainName>(XACML3.ID_FUNCTION_DNSNAME_REGEXP_MATCH, DataTypes.DT_DNSNAME);
+	public static final FunctionDefinition	FD_RFC822NAME_REGEXP_MATCH	= new FunctionDefinitionRegexpMatch<RFC822Name>(XACML3.ID_FUNCTION_RFC822NAME_REGEXP_MATCH, DataTypes.DT_RFC822NAME);
+	public static final FunctionDefinition	FD_X500NAME_REGEXP_MATCH	= new FunctionDefinitionRegexpMatch<X500Principal>(XACML3.ID_FUNCTION_X500NAME_REGEXP_MATCH, DataTypes.DT_X500NAME);
+
+
+	/*
+	 * Special Match functions (See A.3.14)
+	 */
+	public static final FunctionDefinition	FD_X500NAME_MATCH	= new FunctionDefinitionX500NameMatch(XACML3.ID_FUNCTION_X500NAME_MATCH);
+	public static final FunctionDefinition	FD_RFC822NAME_MATCH	= new FunctionDefinitionRFC822NameMatch(XACML3.ID_FUNCTION_RFC822NAME_MATCH);
+
+	/*
+	 * XPath based functions (See A.3.15)
+	 * 
+	 * THESE ARE OPTIONAL
+	 * 
+	 */
+	public static final FunctionDefinition	FD_XPATH_NODE_COUNT 			= new FunctionDefinitionXPath<BigInteger>(XACML3.ID_FUNCTION_XPATH_NODE_COUNT, DataTypes.DT_INTEGER, FunctionDefinitionXPath.OPERATION.COUNT);
+//	public static final FunctionDefinition	FD_XPATH_NODE_COUNT_VERSION1 	= new FunctionDefinitionXPath<BigInteger>(XACML1.ID_FUNCTION_XPATH_NODE_COUNT, DataTypes.DT_INTEGER, FunctionDefinitionXPath.OPERATION.COUNT);
+	public static final FunctionDefinition	FD_XPATH_NODE_EQUAL				= new FunctionDefinitionXPath<Boolean>(XACML3.ID_FUNCTION_XPATH_NODE_EQUAL, DataTypes.DT_BOOLEAN, FunctionDefinitionXPath.OPERATION.EQUAL);
+//	public static final FunctionDefinition	FD_XPATH_NODE_EQUAL_VERSION1	= new FunctionDefinitionXPath<Boolean>(XACML1.ID_FUNCTION_XPATH_NODE_EQUAL, DataTypes.DT_BOOLEAN, FunctionDefinitionXPath.OPERATION.EQUAL);
+	public static final FunctionDefinition	FD_XPATH_NODE_MATCH				= new FunctionDefinitionXPath<Boolean>(XACML3.ID_FUNCTION_XPATH_NODE_MATCH, DataTypes.DT_BOOLEAN, FunctionDefinitionXPath.OPERATION.MATCH);
+//	public static final FunctionDefinition	FD_XPATH_NODE_MATCH_VERSION1	= new FunctionDefinitionXPath<Boolean>(XACML1.ID_FUNCTION_XPATH_NODE_MATCH, DataTypes.DT_BOOLEAN, FunctionDefinitionXPath.OPERATION.MATCH);
+
+	
+	/*
+	 * Other functions (See A.3.16)
+	 * 
+	 * THIS ONE IS OPTIONAL
+	 * 
+	 */
+	public static final FunctionDefinition	FD_ACCESS_PERMITTED = new FunctionDefinitionAccessPermitted(XACML3.ID_FUNCTION_ACCESS_PERMITTED);
+
+
+	/*
+	 * Deprecated functions (See A.4)
+	 * 
+	 */
+	public static final FunctionDefinition	FD_URI_STRING_CONCATENATE = new FunctionDefinitionURIStringConcatenate(XACML2.ID_FUNCTION_URI_STRING_CONCATENATE);
+
+	
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdPolicyFinder.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdPolicyFinder.java
new file mode 100755
index 0000000..4463fba
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdPolicyFinder.java
@@ -0,0 +1,373 @@
+/*
+ *                        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.std;
+
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+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.IdReferenceMatch;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.Version;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.eval.MatchResult;
+import com.att.research.xacmlatt.pdp.policy.Policy;
+import com.att.research.xacmlatt.pdp.policy.PolicyDef;
+import com.att.research.xacmlatt.pdp.policy.PolicyFinder;
+import com.att.research.xacmlatt.pdp.policy.PolicyFinderResult;
+import com.att.research.xacmlatt.pdp.policy.PolicySet;
+import com.att.research.xacmlatt.pdp.policy.PolicySetChild;
+import com.att.research.xacmlatt.pdp.policy.dom.DOMPolicyDef;
+
+/**
+ * StdPolicyFinder implements the {@link com.att.research.xacmlatt.pdp.policy.PolicyFinder} interface to look up policies
+ * by their internal ID or an externally visible ID.
+ * 
+ * @author car
+ * @version $Revision: 1.4 $
+ */
+public class StdPolicyFinder implements PolicyFinder {
+	private static final PolicyFinderResult<PolicyDef> PFR_MULTIPLE				= new StdPolicyFinderResult<PolicyDef>(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Multiple applicable root policies"));
+	private static final PolicyFinderResult<PolicyDef> PFR_NOT_FOUND			= new StdPolicyFinderResult<PolicyDef>(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "No matching root policy found"));
+	
+	private static final PolicyFinderResult<Policy>	PFR_POLICY_NOT_FOUND		= new StdPolicyFinderResult<Policy>(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "No matching policy found"));
+	private static final PolicyFinderResult<Policy>	PFR_NOT_A_POLICY			= new StdPolicyFinderResult<Policy>(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Not a policy"));
+	private static final PolicyFinderResult<PolicySet> PFR_POLICYSET_NOT_FOUND	= new StdPolicyFinderResult<PolicySet>(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "No matching policy set found"));
+	private static final PolicyFinderResult<PolicySet> PFR_NOT_A_POLICYSET		= new StdPolicyFinderResult<PolicySet>(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Not a policy set"));	
+
+	private Log logger	= LogFactory.getLog(this.getClass());
+	private List<PolicyDef> listRoots					= new ArrayList<PolicyDef>();
+	private Map<Identifier,List<PolicyDef>> mapPolicies	= new HashMap<Identifier,List<PolicyDef>>();
+	
+	public static class StdPolicyFinderException extends Exception {
+		private static final long serialVersionUID = -8969282995787463288L;
+		public StdPolicyFinderException(String msg) {
+			super(msg);
+		}
+		public StdPolicyFinderException(String msg, Throwable cause) {
+			super(msg, cause);
+		}
+	}
+	
+	private void storeInPolicyMap(PolicyDef policyDef) {
+		List<PolicyDef> listPolicyDefs	= this.mapPolicies.get(policyDef.getIdentifier());
+		if (listPolicyDefs == null) {
+			listPolicyDefs	= new ArrayList<PolicyDef>();
+			this.mapPolicies.put(policyDef.getIdentifier(), listPolicyDefs);
+		}
+		listPolicyDefs.add(policyDef);
+	}
+	
+	private <T extends PolicyDef> List<T> getFromPolicyMap(IdReferenceMatch idReferenceMatch, Class<T> classPolicyDef) {
+		/*
+		 * Get all of the PolicyDefs for the Identifier in the reference match
+		 */
+		List<PolicyDef> listPolicyDefForId	= this.mapPolicies.get(idReferenceMatch.getId());
+		if (listPolicyDefForId == null) {
+			return null;
+		}
+		
+		/*
+		 * Iterate over all of the PolicyDefs that were found and select only the ones that match
+		 * the version request and the isPolicySet
+		 */
+		List<T> listPolicyDefMatches			= null;
+		Iterator<PolicyDef> iterPolicyDefs		= listPolicyDefForId.iterator();
+		while (iterPolicyDefs.hasNext()) {
+			PolicyDef policyDef	= iterPolicyDefs.next();
+			if (classPolicyDef.isInstance(policyDef) && policyDef.matches(idReferenceMatch)) {
+				if (listPolicyDefMatches == null) {
+					listPolicyDefMatches	= new ArrayList<T>();
+				}
+				listPolicyDefMatches.add(classPolicyDef.cast(policyDef));
+			}
+		}
+		
+		return listPolicyDefMatches;
+	}
+	
+	private <T extends PolicyDef> T getBestMatchN(List<T> matches) {
+		T bestMatch				= null;
+		Version bestVersion		= null;
+		Iterator<T> iterMatches	= matches.iterator();
+		
+		while (iterMatches.hasNext()) {
+			T match	= iterMatches.next();
+			if (bestMatch == null) {
+				bestMatch	= match;
+				bestVersion	= match.getVersion();
+			} else {
+				Version matchVersion	= match.getVersion();
+				if (matchVersion != null) {
+					if (matchVersion.compareTo(bestVersion) > 0) {
+						bestMatch	= match;
+						bestVersion	= matchVersion;
+					}
+				}
+			}
+		}
+		return bestMatch;
+	}
+	
+	private <T extends PolicyDef> T getBestMatch(List<T> matches) {
+		switch(matches.size()) {
+		case 0:
+			return null;
+		case 1:
+			return matches.get(0);
+		default:
+			return this.getBestMatchN(matches);
+		}
+	}
+	
+	private PolicyDef loadPolicyDefFromURI(URI uri) throws StdPolicyFinderException {
+		PolicyDef policyDef	= null;
+		InputStream inputStream	= null;
+		try {
+			this.logger.info("Loading policy from URI " + uri.toString());
+			URL url	= uri.toURL();
+			this.logger.debug("Loading policy from URL " + url.toString());
+			
+			inputStream	= url.openStream();
+			policyDef	= DOMPolicyDef.load(inputStream);
+		} catch (MalformedURLException ex) {
+			this.logger.debug("Unknown protocol for URI " + uri.toString());
+			return null;
+		} catch (Exception ex) {
+			this.logger.error("Exception loading policy definition", ex);
+			throw new StdPolicyFinderException("Exception loading policy def from \"" + uri.toString() + "\": " + ex.getMessage(), ex);
+		} finally {
+			if (inputStream != null) {
+				try {
+					inputStream.close();
+				} catch (Exception ex) {
+					
+				}
+			}
+		}
+		return policyDef;
+	}
+	
+	/**
+	 * Looks up the given {@link com.att.research.xacml.api.Identifier} in the map first.  If not found, and the <code>Identifier</code> contains
+	 * a URL, then attempts to retrieve the document from the URL and caches it.
+	 * 
+	 * @param idReferenceMatch the <code>IdReferenceMatch</code> to look up
+	 * @return a <code>PolicyFinderResult</code> with the requested <code>Policy</code> or an error status
+	 */
+	private PolicyFinderResult<Policy> lookupPolicyByIdentifier(IdReferenceMatch idReferenceMatch) {
+		List<Policy> listCachedPolicies	= this.getFromPolicyMap(idReferenceMatch, Policy.class);
+		if (listCachedPolicies == null) {
+			Identifier id	= idReferenceMatch.getId();
+			if (id != null) {
+				URI uri	= id.getUri();
+				if (uri != null && uri.isAbsolute()) {
+					PolicyDef policyDef	= null;
+					try {
+						policyDef	= this.loadPolicyDefFromURI(uri);
+					} catch (StdPolicyFinderException ex) {
+						return new StdPolicyFinderResult<Policy>(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, ex.getMessage()));
+					}
+					if (policyDef != null) {
+						if (policyDef instanceof Policy) {
+							List<PolicyDef> listPolicyDefs	= new ArrayList<PolicyDef>();
+							listPolicyDefs.add(policyDef);
+							this.mapPolicies.put(id, listPolicyDefs);
+							this.mapPolicies.put(policyDef.getIdentifier(), listPolicyDefs);
+							return new StdPolicyFinderResult<Policy>((Policy)policyDef);
+						} else {
+							return PFR_NOT_A_POLICY;
+						}
+					} else {
+						return PFR_POLICY_NOT_FOUND;
+					}
+				}
+			}
+		}
+		if (listCachedPolicies != null) {
+			return new StdPolicyFinderResult<Policy>(this.getBestMatch(listCachedPolicies));
+		} else {
+			return PFR_POLICY_NOT_FOUND;
+		}
+	}
+	
+	/**
+	 * Looks up the given {@link com.att.research.xacml.api.Identifier} in the map first.  If not found, and the <code>Identifier</code> contains
+	 * a URL, then attempts to retrieve the document from the URL and caches it.
+	 * 
+	 * @param idReferenceMatch the <code>IdReferenceMatch</code> to look up
+	 * @return a <code>PolicyFinderResult</code> with the requested <code>PolicySet</code> or an error status
+	 */
+	private PolicyFinderResult<PolicySet> lookupPolicySetByIdentifier(IdReferenceMatch idReferenceMatch) {
+		List<PolicySet> listCachedPolicySets	= this.getFromPolicyMap(idReferenceMatch, PolicySet.class);
+		if (listCachedPolicySets == null) {
+			Identifier id	= idReferenceMatch.getId();
+			if (id != null) {
+				URI uri	= id.getUri();
+				if (uri != null && uri.isAbsolute()) {
+					PolicyDef policyDef	= null;
+					try {
+						policyDef	= this.loadPolicyDefFromURI(uri);
+					} catch (StdPolicyFinderException ex) {
+						return new StdPolicyFinderResult<PolicySet>(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, ex.getMessage()));
+					}
+					if (policyDef != null) {
+						if (policyDef instanceof PolicySet) {
+							List<PolicyDef> listPolicyDefs	= new ArrayList<PolicyDef>();
+							listPolicyDefs.add(policyDef);
+							this.mapPolicies.put(id, listPolicyDefs);
+							this.mapPolicies.put(policyDef.getIdentifier(), listPolicyDefs);
+							return new StdPolicyFinderResult<PolicySet>((PolicySet)policyDef);
+						} else {
+							return PFR_NOT_A_POLICYSET;
+						}
+					} else {
+						return PFR_POLICYSET_NOT_FOUND;
+					}
+				}
+			}
+		}
+		if (listCachedPolicySets != null) {
+			return new StdPolicyFinderResult<PolicySet>(this.getBestMatch(listCachedPolicySets));
+		} else {
+			return PFR_POLICYSET_NOT_FOUND;
+		}
+	}
+	
+	/**
+	 * Adds the given <code>PolicyDef</code> to the map of loaded <code>PolicyDef</code>s and adds
+	 * its child <code>PolicyDef</code>s recursively.
+	 * 
+	 * @param policyDef the <code>PolicyDef</code> to add
+	 */
+	private void updatePolicyMap(PolicyDef policyDef) {
+		this.storeInPolicyMap(policyDef);
+		if (policyDef instanceof PolicySet) {
+			Iterator<PolicySetChild> iterChildren	= ((PolicySet)policyDef).getChildren();
+			if (iterChildren != null) {
+				while (iterChildren.hasNext()) {
+					PolicySetChild policySetChild	= iterChildren.next();
+					if (policySetChild instanceof PolicyDef) {
+						this.updatePolicyMap((PolicyDef)policySetChild);
+					}
+				}
+			}
+		}
+	}
+	
+	public StdPolicyFinder(Collection<PolicyDef> listRootPolicies, Collection<PolicyDef> referencedPolicyDefs) {
+		if (listRootPolicies != null) {
+			for (PolicyDef policyDef: listRootPolicies) {
+				this.listRoots.add(policyDef);
+				this.updatePolicyMap(policyDef);
+			}
+		}
+		if (referencedPolicyDefs != null) {
+			for (PolicyDef policyDef: referencedPolicyDefs) {
+				this.storeInPolicyMap(policyDef);
+			}
+		}
+	}
+	
+	/**
+	 * Creates a new <code>StdPolicyFinder</code> with the given <code>PolicyDef</code> as the root element.
+	 * 
+	 * @param rootPolicyDef the <code>PolicyDef</code> acting as the root element
+	 */
+	public StdPolicyFinder(PolicyDef rootPolicyDef, Collection<PolicyDef> referencedPolicyDefs) {
+		if (rootPolicyDef != null) {
+			this.listRoots.add(rootPolicyDef);
+			this.updatePolicyMap(rootPolicyDef);
+		}
+		
+		if (referencedPolicyDefs != null) {
+			for (PolicyDef policyDef: referencedPolicyDefs) {
+				this.storeInPolicyMap(policyDef);
+			}
+		}
+	}
+	
+	public StdPolicyFinder(List<PolicyDef> rootPolicies, List<PolicyDef> referencedPolicies, Properties properties) {
+		this(rootPolicies, referencedPolicies);
+	}
+
+	@Override
+	public PolicyFinderResult<PolicyDef> getRootPolicyDef(EvaluationContext evaluationContext) {
+		PolicyDef policyDefFirstMatch			= null;
+		Iterator<PolicyDef> iterRootPolicies	= this.listRoots.iterator();
+		PolicyFinderResult<PolicyDef> firstIndeterminate	= null;
+		while (iterRootPolicies.hasNext()) {
+			PolicyDef policyDef	= iterRootPolicies.next();
+			MatchResult matchResult	= null;
+			try {
+				matchResult	= policyDef.match(evaluationContext);
+				switch(matchResult.getMatchCode()) {
+				case INDETERMINATE:
+					if (firstIndeterminate == null) {
+						firstIndeterminate	= new StdPolicyFinderResult<PolicyDef>(matchResult.getStatus());
+					}
+					break;
+				case MATCH:
+					if (policyDefFirstMatch == null) {
+						policyDefFirstMatch	= policyDef;
+					} else {
+						return PFR_MULTIPLE;
+					}
+					break;
+				case NOMATCH:
+					break;
+				}
+			} catch (EvaluationException ex) {
+				if (firstIndeterminate == null) {
+					firstIndeterminate	= new StdPolicyFinderResult<PolicyDef>(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, ex.getMessage()));
+				}
+			}
+		}
+		
+		if (policyDefFirstMatch == null) {
+			if (firstIndeterminate != null) {
+				return firstIndeterminate;
+			} else {
+				return PFR_NOT_FOUND;
+			}
+		} else {
+			return new StdPolicyFinderResult<PolicyDef>(policyDefFirstMatch);
+		}
+	}
+
+	@Override
+	public PolicyFinderResult<Policy> getPolicy(IdReferenceMatch idReferenceMatch) {
+		return this.lookupPolicyByIdentifier(idReferenceMatch);
+	}
+
+	@Override
+	public PolicyFinderResult<PolicySet> getPolicySet(IdReferenceMatch idReferenceMatch) {
+		return this.lookupPolicySetByIdentifier(idReferenceMatch);
+	}
+	
+	public void addReferencedPolicy(PolicyDef policyDef) {
+		this.updatePolicyMap(policyDef);
+	}
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdPolicyFinderFactory.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdPolicyFinderFactory.java
new file mode 100755
index 0000000..365c768
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdPolicyFinderFactory.java
@@ -0,0 +1,224 @@
+/*
+ *                        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.std;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+import java.util.UUID;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.att.research.xacml.std.IdentifierImpl;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.StdVersion;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.util.FactoryException;
+import com.att.research.xacml.util.XACMLProperties;
+import com.att.research.xacmlatt.pdp.policy.CombiningAlgorithm;
+import com.att.research.xacmlatt.pdp.policy.CombiningAlgorithmFactory;
+import com.att.research.xacmlatt.pdp.policy.Policy;
+import com.att.research.xacmlatt.pdp.policy.PolicyDef;
+import com.att.research.xacmlatt.pdp.policy.PolicyFinder;
+import com.att.research.xacmlatt.pdp.policy.PolicyFinderFactory;
+import com.att.research.xacmlatt.pdp.policy.PolicySet;
+import com.att.research.xacmlatt.pdp.policy.PolicySetChild;
+import com.att.research.xacmlatt.pdp.policy.Target;
+import com.att.research.xacmlatt.pdp.policy.dom.DOMPolicyDef;
+import com.att.research.xacmlatt.pdp.util.ATTPDPProperties;
+import com.google.common.base.Splitter;
+
+/**
+ * StdPolicyFinderFactory extends {@link com.att.research.xacmlatt.pdp.policy.PolicyFinderFactory} with the
+ * <code>getPolicyFinder</code> method to get a single instance of the {@link StdPolicyFinder}.  The
+ * root {@link com.att.research.xacmlatt.pdp.policy.PolicyDef} is loaded from a file whose name is specified as a system property or
+ * in the $java.home/lib/xacml.properties property set.
+ * 
+ * @author car
+ * @version $Revision: 1.3 $
+ */
+public class StdPolicyFinderFactory extends PolicyFinderFactory {
+	public static final String	PROP_FILE		= ".file";
+	public static final String	PROP_URL		= ".url";
+	
+	private Log logger							= LogFactory.getLog(this.getClass());
+	private List<PolicyDef> rootPolicies;
+	private List<PolicyDef> referencedPolicies;
+	private boolean needsInit					= true;
+	
+	/**
+	 * Loads the <code>PolicyDef</code> for the given <code>String</code> identifier by looking first
+	 * for a ".file" property associated with the ID and using that to load from a <code>File</code> and
+	 * looking for a ".url" property associated with the ID and using that to load from a <code>URL</code>.
+	 * 
+	 * @param policyId the <code>String</code> identifier for the policy
+	 * @return a <code>PolicyDef</code> loaded from the given identifier
+	 */
+	protected PolicyDef loadPolicyDef(String policyId, Properties properties) {
+		String propLocation	= properties.getProperty(policyId + PROP_FILE);
+		if (propLocation != null) {
+			File fileLocation	= new File(propLocation);
+			if (!fileLocation.exists()) {
+				this.logger.error("Policy file " + fileLocation.getAbsolutePath() + " does not exist.");
+			} else if (!fileLocation.canRead()) {
+				this.logger.error("Policy file " + fileLocation.getAbsolutePath() + " cannot be read.");
+			} else {
+				try {
+					this.logger.info("Loading policy file " + fileLocation);
+					PolicyDef policyDef	= DOMPolicyDef.load(fileLocation);
+					if (policyDef != null) {
+						return policyDef;
+					}
+				} catch (DOMStructureException ex) {
+					this.logger.error("Error loading policy file " + fileLocation.getAbsolutePath() + ": " + ex.getMessage(), ex);
+					return new Policy(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+				}
+			}
+		}
+		
+		if ((propLocation = properties.getProperty(policyId + PROP_URL)) != null) {
+			 InputStream is = null;
+			try {
+				URL url						= new URL(propLocation);
+				URLConnection urlConnection	= url.openConnection();
+				this.logger.info("Loading policy file " + url.toString());
+				is = urlConnection.getInputStream();
+				PolicyDef policyDef			= DOMPolicyDef.load(is);
+				if (policyDef != null) {
+					return policyDef;
+				}
+			} catch (MalformedURLException ex) {
+				this.logger.error("Invalid URL " + propLocation + ": " + ex.getMessage(), ex);
+			} catch (IOException ex) {
+				this.logger.error("IOException opening URL " + propLocation + ": " + ex.getMessage(), ex);
+			} catch (DOMStructureException ex) {
+				this.logger.error("Invalid Policy " + propLocation + ": " + ex.getMessage(), ex);
+				return new Policy(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+			} finally {
+				if (is != null) {
+					try {
+						is.close();
+					} catch (IOException e) {
+						this.logger.error("Exception closing InputStream for GET of url " + propLocation + " : " + e.getMessage() + "  (May be memory leak)", e);
+					}
+				}
+			}
+		}
+		
+		this.logger.error("No known location for Policy " + policyId);
+		return null;
+	}
+	
+	/**
+	 * Finds the identifiers for all of the policies referenced by the given property name in the
+	 * <code>XACMLProperties</code> and loads them using the requested loading method.
+	 * 
+	 * @param propertyName the <code>String</code> name of the property containing the list of policy identifiers
+	 * @return a <code>List</code> of <code>PolicyDef</code>s loaded from the given property name
+	 */
+	protected List<PolicyDef> getPolicyDefs(String propertyName, Properties properties) {
+		String policyIds	= properties.getProperty(propertyName);
+		if (policyIds == null || policyIds.length() == 0) {
+			return null;
+		}
+		
+		Iterable<String> policyIdArray	= Splitter.on(',').trimResults().omitEmptyStrings().split(policyIds);
+		if (policyIdArray == null) {
+			return null;
+		}
+		
+		List<PolicyDef> listPolicyDefs	= new ArrayList<PolicyDef>();
+		for (String policyId : policyIdArray) {
+			PolicyDef policyDef	= this.loadPolicyDef(policyId, properties);	
+			if (policyDef != null) {
+				listPolicyDefs.add(policyDef);
+			}
+		}
+		return listPolicyDefs;
+	}
+	
+	protected synchronized void init(Properties properties) {
+		if (this.needsInit) {
+			//
+			// Check for property that combines root policies into one policyset
+			//
+			String combiningAlgorithm = properties.getProperty(ATTPDPProperties.PROP_POLICYFINDERFACTORY_COMBINEROOTPOLICIES);
+			if (combiningAlgorithm != null) {
+				try {
+					logger.info("Combining root policies with " + combiningAlgorithm);
+					//
+					// Find the combining algorithm
+					//
+					CombiningAlgorithm<PolicySetChild> algorithm = CombiningAlgorithmFactory.newInstance().getPolicyCombiningAlgorithm(new IdentifierImpl(combiningAlgorithm));
+					//
+					// Create our root policy
+					//
+					PolicySet root = new PolicySet();
+					root.setIdentifier(new IdentifierImpl(UUID.randomUUID().toString()));
+					root.setVersion(StdVersion.newInstance("1.0"));
+					root.setTarget(new Target());
+					//
+					// Set the algorithm
+					//
+					root.setPolicyCombiningAlgorithm(algorithm);
+					//
+					// Load all our root policies
+					//
+					for (PolicyDef policy : this.getPolicyDefs(XACMLProperties.PROP_ROOTPOLICIES, properties)) {
+						root.addChild(policy);
+					}
+					//
+					// Set this policy as the root
+					//
+					this.rootPolicies = new ArrayList<>();
+					this.rootPolicies.add(root);
+				} catch (FactoryException | ParseException e) {
+					logger.error("Failed to load Combining Algorithm Factory: " + e.getLocalizedMessage());
+				}
+			} else {
+				this.rootPolicies		= this.getPolicyDefs(XACMLProperties.PROP_ROOTPOLICIES, properties);
+			}
+			
+			this.referencedPolicies	= this.getPolicyDefs(XACMLProperties.PROP_REFERENCEDPOLICIES, properties);
+			this.needsInit	= false;
+		}
+	}
+	
+	public StdPolicyFinderFactory() {
+	}
+
+	public StdPolicyFinderFactory(Properties properties) {
+	}
+
+	@Override
+	public PolicyFinder getPolicyFinder() throws FactoryException {
+		try {
+			this.init(XACMLProperties.getProperties());
+		} catch (IOException e) {
+			throw new FactoryException(e);
+		}
+		return new StdPolicyFinder(this.rootPolicies, this.referencedPolicies);
+	}
+
+	@Override
+	public PolicyFinder getPolicyFinder(Properties properties) throws FactoryException {
+		this.init(properties);
+		return new StdPolicyFinder(this.rootPolicies, this.referencedPolicies, properties);
+	}	
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdPolicyFinderResult.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdPolicyFinderResult.java
new file mode 100755
index 0000000..0749a8e
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdPolicyFinderResult.java
@@ -0,0 +1,52 @@
+/*
+ *                        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.std;
+
+import com.att.research.xacml.api.Status;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacmlatt.pdp.policy.PolicyDef;
+import com.att.research.xacmlatt.pdp.policy.PolicyFinderResult;
+
+/**
+ * StdPolicyFinderResult implements the {@link com.att.research.xacmlatt.pdp.policy.PolicyFinderResult} interface.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ * @param <T> the java class extending {@link com.att.research.xacmlatt.pdp.policy.PolicyDef} held by the <code>StdPolicyFinderResult</code>
+ */
+public class StdPolicyFinderResult<T extends PolicyDef> implements PolicyFinderResult<T> {
+	private Status status;
+	private T policyDef;
+	
+	public StdPolicyFinderResult(Status statusIn, T policyDefIn) {
+		this.status	= (statusIn == null ? StdStatus.STATUS_OK : statusIn);
+		this.policyDef	= policyDefIn;
+	}
+	
+	public StdPolicyFinderResult(Status statusIn) {
+		this(statusIn, null);
+	}
+	
+	public StdPolicyFinderResult(T policyDefIn) {
+		this(null, policyDefIn);
+	}
+
+	@Override
+	public Status getStatus() {
+		return this.status;
+	}
+
+	@Override
+	public T getPolicyDef() {
+		return this.policyDef;
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdProperties.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdProperties.java
new file mode 100755
index 0000000..ff394ee
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdProperties.java
@@ -0,0 +1,19 @@
+/*
+ *                        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.std;
+
+import com.att.research.xacmlatt.pdp.util.ATTPDPProperties;
+
+public class StdProperties extends ATTPDPProperties {
+	protected StdProperties() {
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/CombinedPermitOverrides.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/CombinedPermitOverrides.java
new file mode 100755
index 0000000..c24d2c2
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/CombinedPermitOverrides.java
@@ -0,0 +1,117 @@
+/*
+ *                        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) 2015 AT&T Knowledge Ventures
+ *              Unpublished and Not for Publication
+ *                     All Rights Reserved
+ */
+package com.att.research.xacmlatt.pdp.std.combiners;
+
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.Decision;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationResult;
+import com.att.research.xacmlatt.pdp.policy.CombinerParameter;
+import com.att.research.xacmlatt.pdp.policy.CombiningElement;
+
+/**
+ * @author pameladragosh
+ * 
+ * This algorithm was created to support combining a collection of policies in which the permit's are combined into one decision. PermitOverrides
+ * itself will stop once a Permit is found. However, some policy makers want every policy in a policy set to be visited by the PDP engine. 
+ * The result of all the Permits that were found are then combined and returned. If no Permits were found then the result is the same semantics as
+ * the PermitOverrides combining algorithm.
+ *
+ * @param <T>
+ */
+public class CombinedPermitOverrides<T extends com.att.research.xacmlatt.pdp.eval.Evaluatable> extends CombiningAlgorithmBase<T> {
+
+	public CombinedPermitOverrides(Identifier identifierIn) {
+		super(identifierIn);
+	}
+
+	@Override
+	public EvaluationResult combine(EvaluationContext evaluationContext,
+			List<CombiningElement<T>> elements,
+			List<CombinerParameter> combinerParameters)
+			throws EvaluationException {
+		boolean atLeastOneDeny					= false;
+		boolean atLeastOnePermit				= false;
+
+		EvaluationResult combinedResultDeny			= new EvaluationResult(Decision.DENY);
+		EvaluationResult combinedResultPermit		= new EvaluationResult(Decision.PERMIT);
+		
+		EvaluationResult firstIndeterminateD	= null;
+		EvaluationResult firstIndeterminateP	= null;
+		EvaluationResult firstIndeterminateDP	= null;
+		
+		Iterator<CombiningElement<T>> iterElements	= elements.iterator();
+		while (iterElements.hasNext()) {
+			CombiningElement<T> combiningElement		= iterElements.next();
+			EvaluationResult evaluationResultElement	= combiningElement.evaluate(evaluationContext);
+			
+			assert(evaluationResultElement != null);
+			switch(evaluationResultElement.getDecision()) {
+			case DENY:
+				atLeastOneDeny	= true;
+				combinedResultDeny.merge(evaluationResultElement);
+				break;
+			case INDETERMINATE:
+			case INDETERMINATE_DENYPERMIT:
+				if (firstIndeterminateDP == null) {
+					firstIndeterminateDP	= evaluationResultElement;
+				} else {
+					firstIndeterminateDP.merge(evaluationResultElement);
+				}
+				break;
+			case INDETERMINATE_DENY:
+				if (firstIndeterminateD == null) {
+					firstIndeterminateD		= evaluationResultElement;
+				} else {
+					firstIndeterminateD.merge(evaluationResultElement);
+				}
+				break;
+			case INDETERMINATE_PERMIT:
+				if (firstIndeterminateP == null) {
+					firstIndeterminateP		= evaluationResultElement;
+				} else {
+					firstIndeterminateP.merge(evaluationResultElement);
+				}
+				break;
+			case NOTAPPLICABLE:
+				break;
+			case PERMIT:
+				atLeastOnePermit = true;
+				combinedResultPermit.merge(evaluationResultElement);
+				break;
+			default:
+				throw new EvaluationException("Illegal Decision: \"" + evaluationResultElement.getDecision().toString());
+			}
+		}
+		
+		if (atLeastOnePermit) {
+			return combinedResultPermit;
+		}
+		if (firstIndeterminateDP != null) {
+			return firstIndeterminateDP;
+		} else if (firstIndeterminateP != null && (firstIndeterminateD != null || atLeastOneDeny)) {
+			return new EvaluationResult(Decision.INDETERMINATE_DENYPERMIT, firstIndeterminateD.getStatus());
+		} else if (firstIndeterminateP != null) {
+			return firstIndeterminateP;
+		} else if (atLeastOneDeny) {
+			return combinedResultDeny;
+		} else if (firstIndeterminateD != null) {
+			return firstIndeterminateD;
+		} else {
+			return new EvaluationResult(Decision.NOTAPPLICABLE);
+		}
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/CombiningAlgorithmBase.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/CombiningAlgorithmBase.java
new file mode 100755
index 0000000..4993a98
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/CombiningAlgorithmBase.java
@@ -0,0 +1,40 @@
+/*
+ *                        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.std.combiners;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacmlatt.pdp.policy.CombiningAlgorithm;
+
+public abstract class CombiningAlgorithmBase<T extends com.att.research.xacmlatt.pdp.eval.Evaluatable> implements CombiningAlgorithm<T> {
+	private Identifier id;
+	
+	public CombiningAlgorithmBase(Identifier identifierIn) {
+		this.id	= identifierIn;
+	}
+
+	@Override
+	public Identifier getId() {
+		return this.id;
+	}
+
+	@Override
+	public String toString() {
+		StringBuilder stringBuilder	= new StringBuilder("{");
+		
+		Object objectToDump;
+		if ((objectToDump = this.getId()) != null) {
+			stringBuilder.append("id=");
+			stringBuilder.append(objectToDump.toString());
+		}
+		stringBuilder.append('}');
+		return stringBuilder.toString();
+	}
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/DenyOverrides.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/DenyOverrides.java
new file mode 100755
index 0000000..207ec61
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/DenyOverrides.java
@@ -0,0 +1,105 @@
+/*
+ *                        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.std.combiners;
+
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.Decision;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationResult;
+import com.att.research.xacmlatt.pdp.policy.CombinerParameter;
+import com.att.research.xacmlatt.pdp.policy.CombiningElement;
+
+/**
+ * DenyOverrides implements the XACML 3.0 "deny-overrides" combining algorithm for both policies and rules.
+ * 
+ * @author car
+ *
+ * @param <T> the java class for the {@link com.att.research.xacmlatt.pdp.eval.Evaluatable}
+ * @param <U> the java class for the identifier
+ */
+public class DenyOverrides<T extends com.att.research.xacmlatt.pdp.eval.Evaluatable> extends CombiningAlgorithmBase<T> {
+
+	public DenyOverrides(Identifier identifierIn) {
+		super(identifierIn);
+	}
+
+	@Override
+	public EvaluationResult combine(EvaluationContext evaluationContext, List<CombiningElement<T>> elements, List<CombinerParameter> combinerParameters) throws EvaluationException {
+		boolean atLeastOnePermit				= false;
+
+		EvaluationResult combinedResult			= new EvaluationResult(Decision.PERMIT);
+		
+		EvaluationResult firstIndeterminateD	= null;
+		EvaluationResult firstIndeterminateP	= null;
+		EvaluationResult firstIndeterminateDP	= null;
+		
+		Iterator<CombiningElement<T>> iterElements	= elements.iterator();
+		while (iterElements.hasNext()) {
+			CombiningElement<T> combiningElement		= iterElements.next();
+			EvaluationResult evaluationResultElement	= combiningElement.evaluate(evaluationContext);
+			
+			assert(evaluationResultElement != null);
+			switch(evaluationResultElement.getDecision()) {
+			case DENY:
+				return evaluationResultElement;
+			case INDETERMINATE:
+			case INDETERMINATE_DENYPERMIT:
+				if (firstIndeterminateDP == null) {
+					firstIndeterminateDP	= evaluationResultElement;
+				} else {
+					firstIndeterminateDP.merge(evaluationResultElement);
+				}
+				break;
+			case INDETERMINATE_DENY:
+				if (firstIndeterminateD == null) {
+					firstIndeterminateD		= evaluationResultElement;
+				} else {
+					firstIndeterminateD.merge(evaluationResultElement);
+				}
+				break;
+			case INDETERMINATE_PERMIT:
+				if (firstIndeterminateP == null) {
+					firstIndeterminateP		= evaluationResultElement;
+				} else {
+					firstIndeterminateP.merge(evaluationResultElement);
+				}
+				break;
+			case NOTAPPLICABLE:
+				break;
+			case PERMIT:
+				atLeastOnePermit	= true;
+				combinedResult.merge(evaluationResultElement);
+				break;
+			default:
+				throw new EvaluationException("Illegal Decision: \"" + evaluationResultElement.getDecision().toString());
+			}
+		}
+		
+		if (firstIndeterminateDP != null) {
+			return firstIndeterminateDP;
+		} else if (firstIndeterminateD != null && (firstIndeterminateP != null || atLeastOnePermit)) {
+			return new EvaluationResult(Decision.INDETERMINATE_DENYPERMIT, firstIndeterminateD.getStatus());
+		} else if (firstIndeterminateD != null) {
+			return firstIndeterminateD;
+		} else if (atLeastOnePermit) {
+			return combinedResult;
+		} else if (firstIndeterminateP != null) {
+			return firstIndeterminateP;
+		} else {
+			return new EvaluationResult(Decision.NOTAPPLICABLE);
+		}
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/DenyUnlessPermit.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/DenyUnlessPermit.java
new file mode 100755
index 0000000..4c241e6
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/DenyUnlessPermit.java
@@ -0,0 +1,68 @@
+/*
+ *                        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.std.combiners;
+
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.Decision;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationResult;
+import com.att.research.xacmlatt.pdp.policy.CombinerParameter;
+import com.att.research.xacmlatt.pdp.policy.CombiningElement;
+
+/**
+ * DenyUnlessPermit implements the XACML 3.0 "deny-unless-permit" combining algorithm for both policies and rules.
+ * 
+ * @author car
+ *
+ * @param <T> the java class for the {@link com.att.research.xacmlatt.pdp.eval.Evaluatable}
+ * @param <U> the java class for the identifier
+ */
+public class DenyUnlessPermit<T extends com.att.research.xacmlatt.pdp.eval.Evaluatable> extends CombiningAlgorithmBase<T> {
+
+	public DenyUnlessPermit(Identifier identifierIn) {
+		super(identifierIn);
+	}
+
+	@Override
+	public EvaluationResult combine(EvaluationContext evaluationContext, List<CombiningElement<T>> elements, List<CombinerParameter> combinerParameters) throws EvaluationException {
+		EvaluationResult combinedResult			= new EvaluationResult(Decision.DENY);
+		
+		Iterator<CombiningElement<T>> iterElements	= elements.iterator();
+		while (iterElements.hasNext()) {
+			CombiningElement<T> combiningElement		= iterElements.next();
+			EvaluationResult evaluationResultElement	= combiningElement.evaluate(evaluationContext);
+			
+			assert(evaluationResultElement != null);
+			switch(evaluationResultElement.getDecision()) {
+			case DENY:
+				combinedResult.merge(evaluationResultElement);
+				break;
+			case INDETERMINATE:
+			case INDETERMINATE_DENYPERMIT:
+			case INDETERMINATE_DENY:
+			case INDETERMINATE_PERMIT:
+			case NOTAPPLICABLE:
+				break;
+			case PERMIT:
+				return evaluationResultElement;
+			default:
+				throw new EvaluationException("Illegal Decision: \"" + evaluationResultElement.getDecision().toString());
+			}
+		}
+		
+		return combinedResult;
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/FirstApplicable.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/FirstApplicable.java
new file mode 100755
index 0000000..02402a5
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/FirstApplicable.java
@@ -0,0 +1,58 @@
+/*
+ *                        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.std.combiners;
+
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.Decision;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationResult;
+import com.att.research.xacmlatt.pdp.policy.CombinerParameter;
+import com.att.research.xacmlatt.pdp.policy.CombiningElement;
+
+/**
+ * PermitOverrides extends {@link com.att.research.xacmlatt.pdp.std.combiners.CombiningAlgorithmBase} to implement the
+ * XACML 1.0 "first-applicable" combining algorithm for policies and rules.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ * 
+ * @param <T> the java class of the object to be combined
+ */
+public class FirstApplicable<T extends com.att.research.xacmlatt.pdp.eval.Evaluatable> extends CombiningAlgorithmBase<T> {
+
+	public FirstApplicable(Identifier identifierIn) {
+		super(identifierIn);
+	}
+
+	@Override
+	public EvaluationResult combine(EvaluationContext evaluationContext,
+			List<CombiningElement<T>> elements,
+			List<CombinerParameter> combinerParameters)
+			throws EvaluationException {
+		Iterator<CombiningElement<T>> iterElements	= elements.iterator();
+		while (iterElements.hasNext()) {
+			CombiningElement<T> combiningElement		= iterElements.next();
+			EvaluationResult evaluationResultElement	= combiningElement.evaluate(evaluationContext);
+			
+			assert(evaluationResultElement != null);
+			if (evaluationResultElement.getDecision() != Decision.NOTAPPLICABLE) {
+				return evaluationResultElement;
+			}
+		}
+		
+		return new EvaluationResult(Decision.NOTAPPLICABLE);
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesPolicy.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesPolicy.java
new file mode 100755
index 0000000..e990b6a
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesPolicy.java
@@ -0,0 +1,78 @@
+/*
+ *                        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.std.combiners;
+
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.Decision;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationResult;
+import com.att.research.xacmlatt.pdp.policy.CombinerParameter;
+import com.att.research.xacmlatt.pdp.policy.CombiningElement;
+import com.att.research.xacmlatt.pdp.policy.PolicySetChild;
+
+/**
+ * DenyOverrides implements the XACML 1.0 "deny-overrides" combining algorithm for policies and policy sets.
+ * 
+ * @author car
+ *
+ * @param <T> the java class for the {@link com.att.research.xacmlatt.pdp.eval.Evaluatable}
+ * @param <U> the java class for the identifier
+ */
+public class LegacyDenyOverridesPolicy extends CombiningAlgorithmBase<PolicySetChild> {
+
+	public LegacyDenyOverridesPolicy(Identifier identifierIn) {
+		super(identifierIn);
+	}
+
+	@Override
+	public EvaluationResult combine(EvaluationContext evaluationContext, List<CombiningElement<PolicySetChild>> elements, List<CombinerParameter> combinerParameters) throws EvaluationException {
+		boolean atLeastOnePermit				= false;
+
+		EvaluationResult combinedResult			= new EvaluationResult(Decision.PERMIT);
+		
+		Iterator<CombiningElement<PolicySetChild>> iterElements	= elements.iterator();
+		while (iterElements.hasNext()) {
+			CombiningElement<PolicySetChild> combiningElement		= iterElements.next();
+			EvaluationResult evaluationResultElement	= combiningElement.evaluate(evaluationContext);
+			
+			assert(evaluationResultElement != null);
+			switch(evaluationResultElement.getDecision()) {
+			case DENY:
+				return evaluationResultElement;
+			case INDETERMINATE:
+			case INDETERMINATE_DENYPERMIT:
+			case INDETERMINATE_DENY:
+			case INDETERMINATE_PERMIT:
+				return new EvaluationResult(Decision.DENY, StdStatus.STATUS_OK);
+			case NOTAPPLICABLE:
+				break;
+			case PERMIT:
+				atLeastOnePermit	= true;
+				combinedResult.merge(evaluationResultElement);
+				break;
+			default:
+				throw new EvaluationException("Illegal Decision: \"" + evaluationResultElement.getDecision().toString());
+			}
+		}
+		
+		if (atLeastOnePermit) {
+			return combinedResult;
+		} else {
+			return new EvaluationResult(Decision.NOTAPPLICABLE);
+		}
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesRule.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesRule.java
new file mode 100755
index 0000000..68e156a
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesRule.java
@@ -0,0 +1,91 @@
+/*
+ *                        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.std.combiners;
+
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.Decision;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationResult;
+import com.att.research.xacmlatt.pdp.policy.CombinerParameter;
+import com.att.research.xacmlatt.pdp.policy.CombiningElement;
+import com.att.research.xacmlatt.pdp.policy.Rule;
+import com.att.research.xacmlatt.pdp.policy.RuleEffect;
+
+/**
+ * DenyOverrides implements the XACML 1.0 "deny-overrides" combining algorithm for rules.
+ * 
+ * @author car
+ *
+ * @param <T> the java class for the {@link com.att.research.xacmlatt.pdp.eval.Evaluatable}
+ * @param <U> the java class for the identifier
+ */
+public class LegacyDenyOverridesRule extends CombiningAlgorithmBase<Rule> {
+
+	public LegacyDenyOverridesRule(Identifier identifierIn) {
+		super(identifierIn);
+	}
+
+	@Override
+	public EvaluationResult combine(EvaluationContext evaluationContext, List<CombiningElement<Rule>> elements, List<CombinerParameter> combinerParameters) throws EvaluationException {
+		boolean atLeastOnePermit						= false;
+		boolean potentialDeny							= false;
+
+		EvaluationResult combinedResult					= new EvaluationResult(Decision.PERMIT);
+		EvaluationResult evaluationResultIndeterminate	= null;
+		
+		Iterator<CombiningElement<Rule>> iterElements	= elements.iterator();
+		while (iterElements.hasNext()) {
+			CombiningElement<Rule> combiningElement		= iterElements.next();
+			EvaluationResult evaluationResultElement	= combiningElement.evaluate(evaluationContext);
+			
+			assert(evaluationResultElement != null);
+			switch(evaluationResultElement.getDecision()) {
+			case DENY:
+				return evaluationResultElement;
+			case INDETERMINATE:
+			case INDETERMINATE_DENYPERMIT:
+			case INDETERMINATE_DENY:
+			case INDETERMINATE_PERMIT:
+				if (evaluationResultIndeterminate == null) {
+					evaluationResultIndeterminate	= evaluationResultElement;
+				} else {
+					evaluationResultIndeterminate.merge(evaluationResultElement);
+				}
+				if (combiningElement.getEvaluatable().getRuleEffect() == RuleEffect.DENY) {
+					potentialDeny	= true;
+				}
+			case NOTAPPLICABLE:
+				break;
+			case PERMIT:
+				atLeastOnePermit	= true;
+				combinedResult.merge(evaluationResultElement);
+				break;
+			default:
+				throw new EvaluationException("Illegal Decision: \"" + evaluationResultElement.getDecision().toString());
+			}
+		}
+		
+		if (potentialDeny) {
+			return evaluationResultIndeterminate;
+		} else if (atLeastOnePermit) {
+			return combinedResult;
+		} else if (evaluationResultIndeterminate != null) {
+			return evaluationResultIndeterminate;
+		} else {
+			return new EvaluationResult(Decision.NOTAPPLICABLE);
+		}
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesPolicy.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesPolicy.java
new file mode 100755
index 0000000..43ed569
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesPolicy.java
@@ -0,0 +1,85 @@
+/*
+ *                        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.std.combiners;
+
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.Decision;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationResult;
+import com.att.research.xacmlatt.pdp.policy.CombinerParameter;
+import com.att.research.xacmlatt.pdp.policy.CombiningElement;
+import com.att.research.xacmlatt.pdp.policy.PolicySetChild;
+
+/**
+ * LegacyPermitOverridesPolicy extends {@link com.att.research.xacmlatt.pdp.policy.combiners.CombiningAlgorithmBase} for
+ * {@link com.att.research.xacmlatt.pdp.policy.PolicySetChild} elements implementing the XACML 1.0 permit-overrides policy combining algorithm.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class LegacyPermitOverridesPolicy extends CombiningAlgorithmBase<PolicySetChild> {
+
+	public LegacyPermitOverridesPolicy(Identifier identifierIn) {
+		super(identifierIn);
+	}
+
+	@Override
+	public EvaluationResult combine(EvaluationContext evaluationContext, List<CombiningElement<PolicySetChild>> elements, List<CombinerParameter> combinerParameters) throws EvaluationException {
+		boolean atLeastOneDeny							= false;
+		
+		EvaluationResult evaluationResultCombined		= new EvaluationResult(Decision.DENY);
+		EvaluationResult evaluationResultIndeterminate	= null;
+		
+		Iterator<CombiningElement<PolicySetChild>> iterElements	= elements.iterator();
+		while (iterElements.hasNext()) {
+			CombiningElement<PolicySetChild> combiningElement	= iterElements.next();
+			EvaluationResult evaluationResultElement			= combiningElement.evaluate(evaluationContext);
+			
+			assert(evaluationResultElement != null);
+			switch(evaluationResultElement.getDecision()) {
+			case DENY:
+				atLeastOneDeny	= true;
+				evaluationResultCombined.merge(evaluationResultElement);
+				break;
+			case INDETERMINATE:
+			case INDETERMINATE_DENY:
+			case INDETERMINATE_DENYPERMIT:
+			case INDETERMINATE_PERMIT:
+				if (evaluationResultIndeterminate == null) {
+					evaluationResultIndeterminate	= evaluationResultElement;
+				} else {
+					evaluationResultIndeterminate.merge(evaluationResultElement);
+				}
+				break;
+			case NOTAPPLICABLE:
+				break;
+			case PERMIT:
+				return evaluationResultElement;
+			default:
+				throw new EvaluationException("Illegal Decision: \"" + evaluationResultElement.getDecision().toString());
+			}
+			
+		}
+		
+		if (atLeastOneDeny) {
+			return evaluationResultCombined;
+		} else if (evaluationResultIndeterminate != null) {
+			return evaluationResultIndeterminate;
+		} else {
+			return new EvaluationResult(Decision.NOTAPPLICABLE);
+		}
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesRule.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesRule.java
new file mode 100755
index 0000000..446ff35
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesRule.java
@@ -0,0 +1,91 @@
+/*
+ *                        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.std.combiners;
+
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.Decision;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationResult;
+import com.att.research.xacmlatt.pdp.policy.CombinerParameter;
+import com.att.research.xacmlatt.pdp.policy.CombiningElement;
+import com.att.research.xacmlatt.pdp.policy.Rule;
+import com.att.research.xacmlatt.pdp.policy.RuleEffect;
+
+/**
+ * LegacyPermitOverridesRule extends {@link com.att.research.xacmlatt.pdp.policy.combiners.CombiningAlgorithmBase} for
+ * {@link com.att.research.xacmlatt.pdp.policy.Rule}s to implement the XACML 1.0 permit-overrides rule combining algorithm.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class LegacyPermitOverridesRule extends CombiningAlgorithmBase<Rule> {
+
+	public LegacyPermitOverridesRule(Identifier identifierIn) {
+		super(identifierIn);
+	}
+
+	@Override
+	public EvaluationResult combine(EvaluationContext evaluationContext, List<CombiningElement<Rule>> elements, List<CombinerParameter> combinerParameters) throws EvaluationException {
+		boolean atLeastOneDeny							= false;
+		boolean potentialPermit							= false;
+		
+		EvaluationResult evaluationResultCombined		= new EvaluationResult(Decision.DENY);
+		EvaluationResult evaluationResultIndeterminate	= null;
+		
+		Iterator<CombiningElement<Rule>> iterElements	= elements.iterator();
+		while (iterElements.hasNext()) {
+			CombiningElement<Rule> combiningElement		= iterElements.next();
+			EvaluationResult evaluationResultElement	= combiningElement.evaluate(evaluationContext);
+			
+			assert(evaluationResultElement != null);
+			switch(evaluationResultElement.getDecision()) {
+			case DENY:
+				atLeastOneDeny	= true;
+				evaluationResultCombined.merge(evaluationResultElement);
+				break;
+			case INDETERMINATE:
+			case INDETERMINATE_DENYPERMIT:
+			case INDETERMINATE_DENY:
+			case INDETERMINATE_PERMIT:
+				if (evaluationResultIndeterminate == null) {
+					evaluationResultIndeterminate	= evaluationResultElement;
+				} else {
+					evaluationResultIndeterminate.merge(evaluationResultElement);
+				}
+				if (combiningElement.getEvaluatable().getRuleEffect() == RuleEffect.PERMIT) {
+					potentialPermit	= true;
+				}
+				break;
+			case NOTAPPLICABLE:
+				break;
+			case PERMIT:
+				return evaluationResultElement;
+			default:
+				throw new EvaluationException("Illegal Decision: \"" + evaluationResultElement.getDecision().toString());
+			}
+		}
+		
+		if (potentialPermit) {
+			return evaluationResultIndeterminate;
+		} else if (atLeastOneDeny) {
+			return evaluationResultCombined;
+		} else if (evaluationResultIndeterminate != null) {
+			return evaluationResultIndeterminate;
+		} else {
+			return new EvaluationResult(Decision.NOTAPPLICABLE);
+		}
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/OnlyOneApplicable.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/OnlyOneApplicable.java
new file mode 100755
index 0000000..f5f8f35
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/OnlyOneApplicable.java
@@ -0,0 +1,78 @@
+/*
+ *                        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.std.combiners;
+
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.Decision;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationResult;
+import com.att.research.xacmlatt.pdp.eval.MatchResult;
+import com.att.research.xacmlatt.pdp.policy.CombinerParameter;
+import com.att.research.xacmlatt.pdp.policy.CombiningElement;
+import com.att.research.xacmlatt.pdp.policy.PolicySetChild;
+
+/**
+ * OnlyOneApplicable extends {@link com.att.research.xacmlatt.pdp.std.combiners.CombiningAlgorithmBase} to implement the
+ * XACML 1.0 "only-one-applicable" combining algorithm for policies and rules.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ * 
+ * @param <T> the java class of the object to be combined
+ */
+public class OnlyOneApplicable extends CombiningAlgorithmBase<PolicySetChild> {
+
+	public OnlyOneApplicable(Identifier identifierIn) {
+		super(identifierIn);
+	}
+
+	@Override
+	public EvaluationResult combine(EvaluationContext evaluationContext,
+			List<CombiningElement<PolicySetChild>> elements,
+			List<CombinerParameter> combinerParameters)
+			throws EvaluationException {
+		Iterator<CombiningElement<PolicySetChild>> iterElements	= elements.iterator();
+		PolicySetChild policySetChildApplicable					= null;
+		while (iterElements.hasNext()) {
+			CombiningElement<PolicySetChild> combiningElement		= iterElements.next();
+			MatchResult matchResultElement				= combiningElement.getEvaluatable().match(evaluationContext);
+			
+			switch(matchResultElement.getMatchCode()) {
+			case INDETERMINATE:
+				return new EvaluationResult(Decision.INDETERMINATE, matchResultElement.getStatus());
+			case MATCH:
+				if (policySetChildApplicable == null) {
+					policySetChildApplicable	= combiningElement.getEvaluatable();
+				} else {
+					return new EvaluationResult(Decision.INDETERMINATE, new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "More than one applicable policy"));
+				}
+				break;
+			case NOMATCH:
+				break;
+			default:
+				throw new EvaluationException("Illegal Decision: \"" + matchResultElement.getMatchCode().toString());
+			}			
+		}
+		
+		if (policySetChildApplicable != null) {
+			return policySetChildApplicable.evaluate(evaluationContext);
+		} else {
+			return new EvaluationResult(Decision.NOTAPPLICABLE);
+		}		
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/PermitOverrides.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/PermitOverrides.java
new file mode 100755
index 0000000..ef34403
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/PermitOverrides.java
@@ -0,0 +1,109 @@
+/*
+ *                        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.std.combiners;
+
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.Decision;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationResult;
+import com.att.research.xacmlatt.pdp.policy.CombinerParameter;
+import com.att.research.xacmlatt.pdp.policy.CombiningElement;
+
+/**
+ * PermitOverrides extends {@link com.att.research.xacmlatt.pdp.std.combiners.CombiningAlgorithmBase} to implement the
+ * XACML 3.0 Permit-overrides combining algorithm for policies and rules.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ * 
+ * @param <T> the java class of the object to be combined
+ */
+public class PermitOverrides<T extends com.att.research.xacmlatt.pdp.eval.Evaluatable> extends CombiningAlgorithmBase<T> {
+
+	public PermitOverrides(Identifier identifierIn) {
+		super(identifierIn);
+	}
+
+	@Override
+	public EvaluationResult combine(EvaluationContext evaluationContext,
+			List<CombiningElement<T>> elements,
+			List<CombinerParameter> combinerParameters)
+			throws EvaluationException {
+		boolean atLeastOneDeny					= false;
+
+		EvaluationResult combinedResult			= new EvaluationResult(Decision.DENY);
+		
+		EvaluationResult firstIndeterminateD	= null;
+		EvaluationResult firstIndeterminateP	= null;
+		EvaluationResult firstIndeterminateDP	= null;
+		
+		Iterator<CombiningElement<T>> iterElements	= elements.iterator();
+		while (iterElements.hasNext()) {
+			CombiningElement<T> combiningElement		= iterElements.next();
+			EvaluationResult evaluationResultElement	= combiningElement.evaluate(evaluationContext);
+			
+			assert(evaluationResultElement != null);
+			switch(evaluationResultElement.getDecision()) {
+			case DENY:
+				atLeastOneDeny	= true;
+				combinedResult.merge(evaluationResultElement);
+				break;
+			case INDETERMINATE:
+			case INDETERMINATE_DENYPERMIT:
+				if (firstIndeterminateDP == null) {
+					firstIndeterminateDP	= evaluationResultElement;
+				} else {
+					firstIndeterminateDP.merge(evaluationResultElement);
+				}
+				break;
+			case INDETERMINATE_DENY:
+				if (firstIndeterminateD == null) {
+					firstIndeterminateD		= evaluationResultElement;
+				} else {
+					firstIndeterminateD.merge(evaluationResultElement);
+				}
+				break;
+			case INDETERMINATE_PERMIT:
+				if (firstIndeterminateP == null) {
+					firstIndeterminateP		= evaluationResultElement;
+				} else {
+					firstIndeterminateP.merge(evaluationResultElement);
+				}
+				break;
+			case NOTAPPLICABLE:
+				break;
+			case PERMIT:
+				return evaluationResultElement;
+			default:
+				throw new EvaluationException("Illegal Decision: \"" + evaluationResultElement.getDecision().toString());
+			}
+		}
+		
+		if (firstIndeterminateDP != null) {
+			return firstIndeterminateDP;
+		} else if (firstIndeterminateP != null && (firstIndeterminateD != null || atLeastOneDeny)) {
+			return new EvaluationResult(Decision.INDETERMINATE_DENYPERMIT, firstIndeterminateD.getStatus());
+		} else if (firstIndeterminateP != null) {
+			return firstIndeterminateP;
+		} else if (atLeastOneDeny) {
+			return combinedResult;
+		} else if (firstIndeterminateD != null) {
+			return firstIndeterminateD;
+		} else {
+			return new EvaluationResult(Decision.NOTAPPLICABLE);
+		}
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/PermitUnlessDeny.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/PermitUnlessDeny.java
new file mode 100755
index 0000000..b1b0ee0
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/PermitUnlessDeny.java
@@ -0,0 +1,69 @@
+/*
+ *                        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.std.combiners;
+
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.Decision;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationResult;
+import com.att.research.xacmlatt.pdp.policy.CombinerParameter;
+import com.att.research.xacmlatt.pdp.policy.CombiningElement;
+
+/**
+ * PermitUnlessDeny implements the XACML 3.0 "permit-unless-deny" combining algorithm for both policies and rules.
+ * 
+ * @author car
+ *
+ * @param <T> the java class for the {@link com.att.research.xacmlatt.pdp.eval.Evaluatable}
+ * @param <U> the java class for the identifier
+ */
+public class PermitUnlessDeny<T extends com.att.research.xacmlatt.pdp.eval.Evaluatable> extends CombiningAlgorithmBase<T> {
+
+	public PermitUnlessDeny(Identifier identifierIn) {
+		super(identifierIn);
+	}
+
+	@Override
+	public EvaluationResult combine(EvaluationContext evaluationContext, List<CombiningElement<T>> elements, List<CombinerParameter> combinerParameters) throws EvaluationException {
+		EvaluationResult combinedResult			= new EvaluationResult(Decision.PERMIT);
+		
+		Iterator<CombiningElement<T>> iterElements	= elements.iterator();
+		while (iterElements.hasNext()) {
+			CombiningElement<T> combiningElement		= iterElements.next();
+			EvaluationResult evaluationResultElement	= combiningElement.evaluate(evaluationContext);
+			
+			assert(evaluationResultElement != null);
+			switch(evaluationResultElement.getDecision()) {
+			case DENY:
+				return evaluationResultElement;
+			case INDETERMINATE:
+			case INDETERMINATE_DENYPERMIT:
+			case INDETERMINATE_DENY:
+			case INDETERMINATE_PERMIT:
+				break;
+			case NOTAPPLICABLE:
+				break;
+			case PERMIT:
+				combinedResult.merge(evaluationResultElement);
+				break;
+			default:
+				throw new EvaluationException("Illegal Decision: \"" + evaluationResultElement.getDecision().toString());
+			}
+		}
+		
+		return combinedResult;
+	}
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/package-info.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/package-info.java
new file mode 100755
index 0000000..db6b8f4
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/package-info.java
@@ -0,0 +1,20 @@
+/*
+ *                        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.std.combiners;
+
+/**
+ * com.att.research.xacmlatt.pdp.std.combiners contains implementations of the {@link com.att.research.xacmlatt.pdp.policy.CombiningAlgorithm}
+ * interface.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/ConvertedArgument.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/ConvertedArgument.java
new file mode 100755
index 0000000..9b81539
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/ConvertedArgument.java
@@ -0,0 +1,204 @@
+/*

+ *                        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.std.functions;

+

+import com.att.research.xacml.api.AttributeValue;

+import com.att.research.xacml.api.DataType;

+import com.att.research.xacml.api.Identifier;

+import com.att.research.xacml.api.Status;

+import com.att.research.xacml.std.StdStatus;

+import com.att.research.xacml.std.StdStatusCode;

+import com.att.research.xacmlatt.pdp.policy.Bag;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;

+

+/**

+ * A ConvertedArgument is the result of processing an {@link com.att.research.xacmlatt.pdp.policy.FunctionArgument}

+ * to validate its correctness and to convert it into an object of the required type.

+ * It is returned by the <code>validateArguments</code> method in

+ * {@link com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionHomogeneousSimple}

+ * and should only be used by other Functions in that same package.

+ * This is a data holder with no processing.

+ * It contains two elements:

+ * <UL>

+ * <LI>

+ * A {@link com.att.research.xacml.api.Status} object, and

+ * <LI>

+ * An object containing the value of the FunctionArgument processed by validateArguments.

+ * This object will only exist if status.isOk() (or the isOk() method in this class that calls status.isOk()) is true.

+ * </UL>

+ * 

+ * 

+ * @author glenngriffin

+ *

+ */

+public class ConvertedArgument<I> {

+

+	// When status != Status.OK, the value is null

+	private Status status;

+	

+	// This is non-null when status == Status.OK

+	private I value = null;

+	

+	/**

+	 * Constructor ensures we have a non-null status, though value will be null if status is not ok.

+	 * 

+	 * @param s

+	 * @param v

+	 */

+	public ConvertedArgument(Status s, I v) {

+		status = s;

+		if (s == null) {

+			throw new IllegalArgumentException("Status of argument cannot be null");

+		}

+		if (s.isOk()) {

+			// only set value if status is ok

+			value = v;

+		}

+	}

+	

+	/**

+	 * Get the Status object

+	 * 

+	 * @return

+	 */

+	public Status getStatus() {

+		return status;

+	}

+	

+	

+	/**

+	 * Convenience method that directly returns the isOk() state from the status object.

+	 * 

+	 * @return

+	 */

+	public boolean isOk() {

+		return status.isOk();

+	}

+	

+	

+	/**

+	 * Get the value object.  This may be a Bag.

+	 * 

+	 * @return

+	 */

+	public I getValue() {

+		return value;

+	}

+	

+	

+	/**

+	 * Get the value as a Bag. (convenience method)

+	 * 

+	 * @return

+	 */

+	public Bag getBag() {

+		return (Bag)value;

+	}

+	

+	

+	/**

+	 * Returns a shortened version of the given DataType Id, primarily for use with error messages to prevent them from becoming too long.

+	 * This is a simple convenience method to reduce code bloat.

+	 * 

+	 * @param identifier expected to have '#' in it, and if no '#' should have ":data-type:"

+	 * @return

+	 */

+	public String getShortDataTypeId(Identifier identifier) {

+		String idString = identifier.stringValue();

+		int index = idString.indexOf("#");

+		if (index < 0) {

+			index = idString.indexOf(":data-type:");

+			if (index < 0) {

+				return idString;

+			} else {

+				return idString.substring(index + 11);

+			}

+		} else {

+			return idString.substring(index+1);

+		}

+	}

+	

+	

+	

+	/**

+	 * Evaluates the given <code>FunctionArgument</code> and validates that it has the correct <code>DataType</code>.

+	 * The returned object will be either:

+	 * <UL>

+	 * <LI>

+	 * A Status Object indicating an error condition, or

+	 * <LI>

+	 * An Object of the appropriate type containing the value of the function. 

+	 * In this case the caller should assume that the Status is Status.OK.

+	 * Note that the object may be a bag if that is what the caller expected.

+	 * </UL>

+	 * 

+	 * 

+	 * @param listFunctionArguments the <code>List</code> of <code>FunctionArgument</code>s to validate

+	 * @param convertedValues the <code>List</code> of <code>U</code> that the converted value is added to.

+	 * @return a {@link com.att.research.xacml.api.Status} indication with an error if the arguments are not valid,

+	 * 			or an object of the correct DataType containing the value.

+	 */

+	@SuppressWarnings("unchecked")	// to suppress warning on bag conversion

+	public ConvertedArgument(FunctionArgument functionArgument, DataType<I> expectedDataType, boolean expectBag) {

+

+		if (functionArgument == null ) {

+			status = new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Got null argument");

+			return;

+		}

+		if ( ! functionArgument.isOk()) {

+			status = functionArgument.getStatus();

+			return;

+		}

+		

+		// bags are valid arguments for some functions

+		if (expectBag) {

+			if ( ! functionArgument.isBag()) {

+				status = new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Expected a bag, saw a simple value");

+				return;

+			}

+

+			Bag bag = functionArgument.getBag();

+			value = (I) bag;

+			status = StdStatus.STATUS_OK;

+			return;

+		}

+		

+		// argument should not be a bag

+		if (functionArgument.isBag()) {

+			status = new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Expected a simple value, saw a bag");

+			return;

+		}

+		AttributeValue<?> attributeValue	= functionArgument.getValue();

+		if (attributeValue == null || attributeValue.getValue() == null) {

+			status = new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Got null attribute");

+			return;

+		}

+		if ( ! attributeValue.getDataTypeId().equals(expectedDataType.getId())) {

+			status = new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Expected data type '" + 

+					getShortDataTypeId(expectedDataType.getId()) + "' saw '" + getShortDataTypeId(attributeValue.getDataTypeId()) + "'");

+			return;

+		}

+		

+		try {

+			value = expectedDataType.convert(attributeValue.getValue());

+			status = StdStatus.STATUS_OK;

+		} catch (Exception e) {

+			String message = e.getMessage();

+			if (e.getCause() != null) {

+				message = e.getCause().getMessage();

+			}

+			status = new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, message);

+		}

+	}

+	

+	

+	

+}

diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionAccessPermitted.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionAccessPermitted.java
new file mode 100755
index 0000000..c8109ce
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionAccessPermitted.java
@@ -0,0 +1,198 @@
+/*

+ *                        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.std.functions;

+

+

+import java.io.ByteArrayInputStream;

+import java.io.InputStream;

+import java.net.URI;

+import java.util.List;

+

+import javax.xml.parsers.DocumentBuilderFactory;

+

+import org.w3c.dom.Node;

+

+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.std.StdRequest;

+import com.att.research.xacml.std.StdStatus;

+import com.att.research.xacml.std.StdStatusCode;

+import com.att.research.xacml.std.datatypes.DataTypes;

+import com.att.research.xacml.std.dom.DOMRequestAttributes;

+import com.att.research.xacml.std.dom.DOMStructureException;

+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;

+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;

+

+/**

+ * FunctionDefinitionAccessPermitted implements {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition} to

+ * implement the XACML access-permitted predicate.

+ * 

+ * WARNING: This code is unfinished.  Initially we did not complete the implementation because we did not understand how to handle XML Namespaces 

+ * (from the &lt;Request&gt; or &lt;Policy&gt;).

+ * 	Later we understood that any Namespaces used within this function must be explicitly listed in &lt;Content&gt; XML elemement passed to this function.

+ *  However, it is not clear that anyone needs this function.

+ *  The only use anyone has mentioned is in a recursive operation which requires a loop counter of some kind, which we do not have implemented.

+ *  Therefore we have chosen to leave this unimplemented for now.

+ * 

+ * In the first implementation of XACML we had separate files for each XACML Function.

+ * This release combines multiple Functions in fewer files to minimize code duplication.

+ * This file supports the following XACML codes:

+ * 		access-permitted

+ * 

+ * 

+ * @author glenngriffin

+ * @version $Revision: 1.1 $

+ * 

+ */

+public class FunctionDefinitionAccessPermitted extends FunctionDefinitionBase<Boolean, URI> {

+

+

+	

+	

+	/**

+	 * Constructor - need dataTypeArgs input because of java Generic type-erasure during compilation.

+	 * 

+	 * @param idIn

+	 * @param dataTypeArgsIn

+	 */

+	public FunctionDefinitionAccessPermitted(Identifier idIn) {

+		super(idIn, DataTypes.DT_BOOLEAN, DataTypes.DT_ANYURI, false);

+	}

+

+	@Override

+	public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) {

+		if (arguments == null ||  arguments.size() != 2) {

+			return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + 

+					" Expected 2 arguments, got " + 

+					((arguments == null) ? "null" : arguments.size()) ));

+		}

+		

+		// first arg is URI

+		FunctionArgument functionArgument = arguments.get(0);

+		ConvertedArgument<URI> convertedArgument0 = new ConvertedArgument<URI>(functionArgument, DataTypes.DT_ANYURI, false);

+		if ( ! convertedArgument0.isOk()) {

+			return ExpressionResult.newError(getFunctionStatus(convertedArgument0.getStatus()));

+		}

+		URI attributesURI = convertedArgument0.getValue();

+		// this must be a urn of an attribute category

+		if ( ! attributesURI.toString().startsWith("urn:") ||  ! attributesURI.toString().contains(":attribute-category:")) {

+			return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, this.getShortFunctionId() + 

+					" First argument must be a urn for an attribute-category, not '" + attributesURI.toString() ));

+		}

+		

+		// second argument is of input type

+		functionArgument = arguments.get(1);

+		ConvertedArgument<String> convertedArgument1 = new ConvertedArgument<String>(functionArgument, DataTypes.DT_STRING, false);

+		if ( ! convertedArgument1.isOk()) {

+			return ExpressionResult.newError(getFunctionStatus(convertedArgument1.getStatus()));

+		}

+		// get the Duration object from the argument which includes all fields, even if the incoming argument does not include them all

+		String xmlContent = convertedArgument1.getValue();

+		

+		// The spec is fuzzy on whether this string includes the "<Content>" tags or not, so handle it either way

+		if ( ! xmlContent.trim().toLowerCase().startsWith("<content>") ) {

+			// incomming is not surrounded by <content> tags, so ad them

+			xmlContent = "<Content>" + xmlContent + "</Content>";

+		}

+		

+//TODO - the next block needs to be uncommented and fixed		

+//Request req = evaluationContext.getRequest();

+//List<String> xmlAttrList = req.getRequestXMLAttributes();

+//String attrString = " ";

+//for (String attr : xmlAttrList) {

+//	attrString += " " + attr;

+//}

+//		

+//		// add the Attributes XML element

+//		xmlContent = "<Attributes Category=\"" + attributesURI + "\" " + attrString + " >" + xmlContent + "</Attributes>";

+		

+//java.util.Iterator<RequestAttributes> rait = req.getRequestAttributes();

+//while (rait.hasNext()) {

+//	RequestAttributes ra = rait.next();

+//	System.out.println(ra);

+//}

+

+

+

+		// convert the xmlContent into XML Nodes

+		Node newContentNode = null;

+//TODO - need to get Namespace info from original Request?  How can I recover the original Namespace from the EvaluationContext?

+		try (InputStream is = new ByteArrayInputStream(xmlContent.getBytes())) {

+			DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();

+			docBuilderFactory.setNamespaceAware(true);

+

+			newContentNode =  docBuilderFactory

+				    .newDocumentBuilder()

+				    .parse(is)

+				    .getDocumentElement();

+		} catch (Exception e) {

+			String message = e.getMessage();

+			if (e.getCause() != null) {

+				message = e.getCause().getMessage();

+			}

+			return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, this.getShortFunctionId() + 

+					" Parsing of XML string failed.  Cause='" + message + "'" ));

+		}

+		// convert the XML Node into a RequestAttributes object

+//TODO - If this code is ever completed, the following variable will be used.  The annotation is to avoid warnings.

+@SuppressWarnings("unused")

+		RequestAttributes newRequestAttributes = null;

+		try {

+			newRequestAttributes = DOMRequestAttributes.newInstance(newContentNode);

+		} catch (DOMStructureException e) {

+			String message = e.getMessage();

+			if (e.getCause() != null) {

+				message = e.getCause().getMessage();

+			}

+			return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, this.getShortFunctionId() + 

+					" Conversion of XML to RequestAttributes failed.  Cause='" + message + "'" ));

+		}

+

+		

+		// check the evaluationContext and Request for null

+		if (evaluationContext == null) {

+			return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +

+					" Got null EvaluationContext"));

+		}

+		if (evaluationContext.getRequest() == null) {

+			return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +

+					" Got null Request in EvaluationContext"));

+		}

+		

+		// Create a new Request by:

+		//		- copying the current request, 

+		//		- Dropping the Attributes section identified by the attributesURI argument

+		//		- adding a new Attributes section identified by the attributesURI arg and with a Content section containing the xmlContent argument

+		Request originalRequest = evaluationContext.getRequest();

+		

+//TODO - If this code is ever completed, the following variable will be used.  The annotation is to avoid warnings.

+@SuppressWarnings("unused")

+		Request newRequest = new StdRequest(originalRequest);

+		

+

+		

+//	???? nameingContext????

+		

+		// Now create a new EvaluationContext matching the one passed to this method except for the Request

+//TODO

+		

+		// Run the PDP on the new EvaluationContext

+//TODO

+		

+		

+return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +

+		" Not Implemented"));

+

+	}

+	

+}

diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic.java
new file mode 100755
index 0000000..03bd34f
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic.java
@@ -0,0 +1,196 @@
+/*

+ *                        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.std.functions;

+

+import java.math.BigInteger;

+import java.util.ArrayList;

+import java.util.List;

+

+import com.att.research.xacml.api.AttributeValue;

+import com.att.research.xacml.api.DataType;

+import com.att.research.xacml.api.Identifier;

+import com.att.research.xacml.api.Status;

+import com.att.research.xacml.api.XACML;

+import com.att.research.xacml.std.StdAttributeValue;

+import com.att.research.xacml.std.StdStatus;

+import com.att.research.xacml.std.StdStatusCode;

+import com.att.research.xacml.std.datatypes.DataTypes;

+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;

+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;

+

+/**

+ * FunctionDefinitionArithmetic extends {@link com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionHomogeneousSimple} to

+ * implement the XACML Arithmetic predicates as functions taking one or two arguments of the same data type and returning a single value of the same type.

+ * 

+ * In Java there is no way to do arithmetic operations generically, so we need to have individual code for each operation on each class within this class.

+ * 

+ * In the first implementation of XACML we had separate files for each XACML Function.

+ * This release combines multiple Functions in fewer files to minimize code duplication.

+ * This file supports the following XACML codes:

+ * 		integer-add

+ * 		double-add

+ * 		integer-subtract

+ * 		double-subtract

+ * 		integer-multiply

+ * 		double-multiply

+ * 		integer-divide

+ * 		double-divide

+ * 		integer-mod

+ * 		integer-abs

+ * 		double-abs

+ * 		round

+ * 		floor

+ * 

+ * @author glenngriffin

+ * @version $Revision: 1.1 $

+ * 

+ * @param <T> the java class for the data type of the function arguments

+ */

+public class FunctionDefinitionArithmetic<T extends Number> extends FunctionDefinitionHomogeneousSimple<T,T> {

+	

+	/**

+	 * List of arithmetic operations.

+	 * 

+	 * @author glenngriffin

+	 *

+	 */

+	public enum OPERATION {ADD, SUBTRACT, MULTIPLY, DIVIDE, MOD, ABS, ROUND, FLOOR };

+	

+	// operation to be used in this instance of the Arightmetic class

+	private final OPERATION operation;

+	

+	// result variables used by all functions, one for each type

+	private AttributeValue<BigInteger>	integerResult;

+	private AttributeValue<Double>	doubleResult;

+

+	/**

+	 * Constructor

+	 * 

+	 * @param idIn

+	 * @param dataTypeArgsIn

+	 * @param op

+	 */

+	public FunctionDefinitionArithmetic(Identifier idIn, DataType<T> dataTypeArgsIn, OPERATION op, int nArgs) {

+		// for Arithmetic functions, the output type is the same as the input type (no mixing of Ints and Doubles!)

+		super(idIn, dataTypeArgsIn, dataTypeArgsIn, nArgs);

+		

+		// save the operation to be used in this instance

+		operation = op;

+	}

+

+

+	@Override

+	public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) {

+		List<T> convertedArguments	= new ArrayList<T>();

+		Status status				= this.validateArguments(arguments, convertedArguments);

+		

+		/*

+		 * If the function arguments are not correct, just return an error status immediately

+		 */

+		if (!status.getStatusCode().equals(StdStatusCode.STATUS_CODE_OK)) {

+			return ExpressionResult.newError(getFunctionStatus(status));

+		}

+		

+		/*

+		 * Now perform the requested operation.

+		 */

+		ExpressionResult expressionResult = null;

+		

+		try {

+			switch (operation) {

+			case ADD:

+				if (this.getDataType() == DataTypes.DT_INTEGER) {

+					integerResult	= new StdAttributeValue<BigInteger>(XACML.ID_DATATYPE_INTEGER, ((BigInteger)convertedArguments.get(0)).add( (BigInteger)convertedArguments.get(1)) );

+					expressionResult = ExpressionResult.newSingle(integerResult);

+				} else {

+					doubleResult	= new StdAttributeValue<Double>(XACML.ID_DATATYPE_DOUBLE, (Double)convertedArguments.get(0) + (Double)convertedArguments.get(1));

+					expressionResult = ExpressionResult.newSingle(doubleResult);

+				}

+				break;

+			case SUBTRACT:

+				if (this.getDataType() == DataTypes.DT_INTEGER) {

+					integerResult	= new StdAttributeValue<BigInteger>(XACML.ID_DATATYPE_INTEGER, ((BigInteger)convertedArguments.get(0)).subtract( (BigInteger)convertedArguments.get(1)) );

+					expressionResult = ExpressionResult.newSingle(integerResult);

+				} else {

+					doubleResult	= new StdAttributeValue<Double>(XACML.ID_DATATYPE_DOUBLE, (Double)convertedArguments.get(0) - (Double)convertedArguments.get(1));

+					expressionResult = ExpressionResult.newSingle(doubleResult);

+				}

+				break;

+			case MULTIPLY:

+				if (this.getDataType() == DataTypes.DT_INTEGER) {

+					integerResult	= new StdAttributeValue<BigInteger>(XACML.ID_DATATYPE_INTEGER, ((BigInteger)convertedArguments.get(0)).multiply((BigInteger)convertedArguments.get(1)) );

+					expressionResult = ExpressionResult.newSingle(integerResult);

+				} else {

+					doubleResult	= new StdAttributeValue<Double>(XACML.ID_DATATYPE_DOUBLE, (Double)convertedArguments.get(0) * (Double)convertedArguments.get(1));

+					expressionResult = ExpressionResult.newSingle(doubleResult);

+				}

+				break;

+			case DIVIDE:

+				if (this.getDataType() == DataTypes.DT_INTEGER) {

+					if ( ((BigInteger)convertedArguments.get(1)).equals(new BigInteger("0")) ) {

+						return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +" Divide by 0 error: "+

+								arguments.get(0).getValue().getValue().toString() + ", " + arguments.get(1).getValue().getValue().toString()));

+					}

+					integerResult	= new StdAttributeValue<BigInteger>(XACML.ID_DATATYPE_INTEGER, ((BigInteger)convertedArguments.get(0)).divide((BigInteger)convertedArguments.get(1)) );

+					expressionResult = ExpressionResult.newSingle(integerResult);

+				} else {

+					if ((Double)convertedArguments.get(1) == 0) {

+						return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +" Divide by 0 error: "+

+								arguments.get(0).getValue().getValue().toString() + ", " + arguments.get(1).getValue().getValue().toString()));

+					}

+					doubleResult	= new StdAttributeValue<Double>(XACML.ID_DATATYPE_DOUBLE, (Double)convertedArguments.get(0) / (Double)convertedArguments.get(1));

+					expressionResult = ExpressionResult.newSingle(doubleResult);

+				}

+				break;

+			case MOD:

+				if ( ((BigInteger)convertedArguments.get(1)).equals(new BigInteger("0")) ) {

+					return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +" Divide by 0 error: "+

+							arguments.get(0).getValue().getValue().toString() + ", " + arguments.get(1).getValue().getValue().toString()));

+				}

+				integerResult	= new StdAttributeValue<BigInteger>(XACML.ID_DATATYPE_INTEGER, ((BigInteger)convertedArguments.get(0)).remainder((BigInteger)convertedArguments.get(1)) );

+				expressionResult = ExpressionResult.newSingle(integerResult);

+				break;

+			case ABS:

+				if (this.getDataType() == DataTypes.DT_INTEGER) {

+					integerResult	= new StdAttributeValue<BigInteger>(XACML.ID_DATATYPE_INTEGER, ((BigInteger)convertedArguments.get(0)).abs() );

+					expressionResult = ExpressionResult.newSingle(integerResult);

+				} else {

+					doubleResult	= new StdAttributeValue<Double>(XACML.ID_DATATYPE_DOUBLE, Math.abs((Double)convertedArguments.get(0)));

+					expressionResult = ExpressionResult.newSingle(doubleResult);

+				}

+				break;

+			case ROUND:

+				doubleResult	= new StdAttributeValue<Double>(XACML.ID_DATATYPE_DOUBLE, (double)(Math.round((Double)convertedArguments.get(0))) );

+				expressionResult = ExpressionResult.newSingle(doubleResult);

+				break;

+			case FLOOR:

+				doubleResult	= new StdAttributeValue<Double>(XACML.ID_DATATYPE_DOUBLE, Math.floor((Double)convertedArguments.get(0)));

+				expressionResult = ExpressionResult.newSingle(doubleResult);

+				break;

+			}

+		} catch (Exception e) {

+			String message = e.getMessage();

+			if (e.getCause() != null) {

+				message = e.getCause().getMessage();

+			}

+			String args = arguments.get(0).getValue().toString();

+			if (arguments.size() > 1) {

+				args += ", " + arguments.get(1).getValue().toString();

+			}

+			expressionResult = ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " " + message +

+					" args: " + args + " " + e.getMessage() ));

+		}

+		

+		return expressionResult;

+	}

+

+}

diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBag.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBag.java
new file mode 100755
index 0000000..cbdb406
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBag.java
@@ -0,0 +1,107 @@
+/*

+ *                        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.std.functions;

+

+import java.util.List;

+

+import com.att.research.xacml.api.DataType;

+import com.att.research.xacml.api.Identifier;

+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;

+import com.att.research.xacmlatt.pdp.policy.Bag;

+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;

+

+/**

+ * FunctionDefinitionBag implements {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition} to

+ * implement the XACML 'type'-bag predicates as functions taking 0, 1 or multiple arguments of the same data type and returning a <code>Bag</code>.

+ * 

+ * In the first implementation of XACML we had separate files for each XACML Function.

+ * This release combines multiple Functions in fewer files to minimize code duplication.

+ * This file supports the following XACML codes:

+ * 		string-bag

+ * 		boolean-bag

+ * 		integer-bag

+ * 		double-bag

+ * 		time-bag

+ * 		date-bag

+ * 		dateTime-bag

+ * 		anyURI-bag

+ * 		hexBinary-bag

+ * 		base64Binary-bag

+ * 		dayTimeDuration-bag (version 1 and3)

+ * 		yearMonthDuration-bag (version 1 and 3)

+ * 		x500Name-bag

+ * 		rfc822Name-bag

+ * 		ipAddress-bag

+ * 		dnsName-bag

+ * 

+ * 

+ * @author glenngriffin

+ * @version $Revision: 1.1 $

+ * 

+ * @param <I> the java class for the data type of the function Input arguments,

+ * 		which is also the "type" of the returned bag

+ */

+public class FunctionDefinitionBag<I> extends FunctionDefinitionBase<I, I> {

+

+	

+	/**

+	 * Constructor - need dataType input because of java Generic type-erasure during compilation.

+	 * 

+	 * @param idIn

+	 * @param dataTypeArgsIn

+	 */

+	public FunctionDefinitionBag(Identifier idIn, DataType<I> dataTypeArgsIn) {

+		super(idIn, dataTypeArgsIn, dataTypeArgsIn, true);

+	}

+

+	/**

+	 * Evaluates this <code>FunctionDefinition</code> on the given <code>List</code> of{@link com.att.research.xacmlatt.pdp.policy.FunctionArgument}s.

+	 * 

+	 * @param evaluationContext the {@link com.att.research.xacmlatt.pdp.eval.EvaluationContext} to use in the evaluation

+	 * @param arguments the <code>List</code> of <code>FunctionArgument</code>s for the evaluation

+	 * @return an {@link com.att.research.xacmlatt.pdp.policy.ExpressionResult} with the results of the call

+	 */

+	@Override

+	public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) {

+

+		// create a list to put the values into

+		Bag elementBag	= new Bag();

+		

+		// see if we have arguments

+		if (arguments != null && arguments.size() > 0) {

+	

+			// for each arg, evaluate it, check type, and put on the list

+			for (FunctionArgument argument : arguments) {

+				// get the argument, evaluate it and check status

+				ConvertedArgument<I> convertedArgument = new ConvertedArgument<I>(argument, this.getDataTypeArgs(), false);

+				

+				// check the status

+				if ( ! convertedArgument.isOk()) {

+					return ExpressionResult.newError(getFunctionStatus(convertedArgument.getStatus()));

+				}

+				

+				// Special case: Most methods want the value contained in the AttributeValue object inside the FunctionArgument.

+				// This one wants the AttributeValue itself.

+				// We use the ConvertedArgument constructor to validate that the argument is ok, then use the AttributeValue

+				// from the FunctionArgument.

+				elementBag.add(argument.getValue());

+			}

+		}

+		

+		// return it

+		return ExpressionResult.newBag(elementBag);

+	}

+

+	

+	

+

+}

diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagIsIn.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagIsIn.java
new file mode 100755
index 0000000..e61e59f
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagIsIn.java
@@ -0,0 +1,132 @@
+/*

+ *                        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.std.functions;

+

+import java.util.Iterator;

+import java.util.List;

+

+import com.att.research.xacml.api.AttributeValue;

+import com.att.research.xacml.api.DataType;

+import com.att.research.xacml.api.Identifier;

+import com.att.research.xacml.std.StdStatus;

+import com.att.research.xacml.std.StdStatusCode;

+import com.att.research.xacml.std.datatypes.DataTypes;

+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;

+import com.att.research.xacmlatt.pdp.policy.Bag;

+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;

+

+/**

+ * FunctionDefinitionBagIsIn implements {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition} to

+ * implement the XACML 'type'-is-in predicates as functions taking two arguments, the first of <code>type</code> and the second of type <code>Bag</code>,

+ * and returning a <code>Boolean</code> for whether the first argument is contained in the second.

+ * 

+ * In the first implementation of XACML we had separate files for each XACML Function.

+ * This release combines multiple Functions in fewer files to minimize code duplication.

+ * This file supports the following XACML codes:

+ * 		string-is-in

+ * 		boolean-is-in

+ * 		integer-is-in

+ * 		double-is-in

+ * 		time-is-in

+ * 		date-is-in

+ * 		dateTime-is-in

+ * 		anyURI-is-in

+ * 		hexBinary-is-in

+ * 		base64Binary-is-in

+ * 		dayTimeDuration-is-in (version 1 and3)

+ * 		yearMonthDuration-is-in (version 1 and 3)

+ * 		x500Name-is-in

+ * 		rfc822Name-is-in

+ * 		ipAddress-is-in

+ * 		dnsName-is-in

+ * 

+ * 

+ * @author glenngriffin

+ * @version $Revision: 1.1 $

+ * 

+ * @param <I> the java class for the data type of the elements in the Input argument Bag

+ * 

+ * The Output for these functions is always a Boolean.

+ */

+public class FunctionDefinitionBagIsIn<I> extends FunctionDefinitionBase<Boolean, I> {

+

+	

+	/**

+	 * Constructor - need dataType input because of java Generic type-erasure during compilation.

+	 * 

+	 * @param idIn

+	 * @param dataTypeArgsIn

+	 */

+	public FunctionDefinitionBagIsIn(Identifier idIn, DataType<I> dataTypeArgsIn) {

+		super(idIn, DataTypes.DT_BOOLEAN, dataTypeArgsIn, false);

+

+	}

+

+	/**

+	 * Evaluates this <code>FunctionDefinition</code> on the given <code>List</code> of{@link com.att.research.xacmlatt.pdp.policy.FunctionArgument}s.

+	 * 

+	 * @param evaluationContext the {@link com.att.research.xacmlatt.pdp.eval.EvaluationContext} to use in the evaluation

+	 * @param arguments the <code>List</code> of <code>FunctionArgument</code>s for the evaluation

+	 * @return an {@link com.att.research.xacmlatt.pdp.policy.ExpressionResult} with the results of the call

+	 */

+	@Override

+	public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) {

+

+		if (arguments == null || arguments.size() != 2) {

+			return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Expected 2 arguments, got " + 

+					((arguments == null) ? "null" : arguments.size()) ));

+		}

+		

+		// get the thing to look for in the bag

+		FunctionArgument elementArgument = arguments.get(0);

+

+		ConvertedArgument<I> convertedTargetArgument = new ConvertedArgument<I>(elementArgument, this.getDataTypeArgs(), false);

+		if ( ! convertedTargetArgument.isOk()) {

+			return ExpressionResult.newError(getFunctionStatus(convertedTargetArgument.getStatus()));

+		}

+		

+		// Special case: Most methods want the value contained in the AttributeValue object inside the FunctionArgument.

+		// This one wants the AttributeValue itself.

+		// We use the ConvertedArgument constructor to validate that the argument is ok, then use the AttributeValue

+		// from the FunctionArgument.

+		AttributeValue<?> attributeValueElement	= elementArgument.getValue();

+

+		// now get the bag

+		FunctionArgument bagArgument = arguments.get(1);

+		ConvertedArgument<Bag> convertedBagArgument = new ConvertedArgument<Bag>(bagArgument, null, true);

+

+		if ( ! convertedBagArgument.isOk()) {

+			return ExpressionResult.newError(getFunctionStatus(convertedBagArgument.getStatus()));

+		}

+	

+		Bag bag = convertedBagArgument.getBag();

+

+		Iterator<AttributeValue<?>> iterBagContents	= bag.getAttributeValues();

+		while (iterBagContents.hasNext()) {

+			AttributeValue<?> attributeValueBagContents	= iterBagContents.next();

+			

+			/*

+			 * Should we be checking the type of the bag contents and returning an error if the bag contents are not of the

+			 * right type?  The spec does not say this, so we just use the AttributeValue.equals() method for now.

+			 */

+			if (attributeValueElement.equals(attributeValueBagContents)) {

+				return ER_TRUE;

+			}

+		}

+		

+		return ER_FALSE;

+	}

+

+	

+	

+

+}

diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagOneAndOnly.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagOneAndOnly.java
new file mode 100755
index 0000000..03e1210
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagOneAndOnly.java
@@ -0,0 +1,117 @@
+/*

+ *                        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.std.functions;

+

+import java.util.List;

+

+import com.att.research.xacml.api.AttributeValue;

+import com.att.research.xacml.api.DataType;

+import com.att.research.xacml.api.Identifier;

+import com.att.research.xacml.std.StdStatus;

+import com.att.research.xacml.std.StdStatusCode;

+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;

+import com.att.research.xacmlatt.pdp.policy.Bag;

+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;

+

+/**

+ * FunctionDefinitionBagOneAndOnly implements {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition} to

+ * implement the XACML 'type'-one-and-only predicates as functions taking one <code>Bag</code> argument and returning the single element in that bag of the 'type'.

+ * 

+ * In the first implementation of XACML we had separate files for each XACML Function.

+ * This release combines multiple Functions in fewer files to minimize code duplication.

+ * This file supports the following XACML codes:

+ * 		string-one-and-only

+ * 		boolean-one-and-only

+ * 		integer-one-and-only

+ * 		double-one-and-only

+ * 		time-one-and-only

+ * 		date-one-and-only

+ * 		dateTime-one-and-only

+ * 		anyURI-one-and-only

+ * 		hexBinary-one-and-only

+ * 		base64Binary-one-and-only

+ * 		dayTimeDuration-one-and-only (version 1 and3)

+ * 		yearMonthDuration-one-and-only (version 1 and 3)

+ * 		x500Name-one-and-only

+ * 		rfc822Name-one-and-only

+ * 		ipAddress-one-and-only

+ * 		dnsName-one-and-only

+ * 

+ * 

+ * @author glenngriffin

+ * @version $Revision: 1.1 $

+ * 

+ * @param <I> the java class for the data type of the elements in the bag handed to this as the Input argument, 

+ * 	which is also the type of the return value

+ * 

+ */

+public class FunctionDefinitionBagOneAndOnly<I> extends FunctionDefinitionBase<I,I> {

+

+	

+	/**

+	 * Constructor - need dataType input because of java Generic type-erasure during compilation.

+	 * 

+	 * @param idIn

+	 * @param dataTypeArgsIn

+	 */

+	public FunctionDefinitionBagOneAndOnly(Identifier idIn, DataType<I> dataTypeArgsIn) {

+		super(idIn, dataTypeArgsIn, dataTypeArgsIn, false);

+	}

+

+	/**

+	 * Evaluates this <code>FunctionDefinition</code> on the given <code>List</code> of{@link com.att.research.xacmlatt.pdp.policy.FunctionArgument}s.

+	 * 

+	 * @param evaluationContext the {@link com.att.research.xacmlatt.pdp.eval.EvaluationContext} to use in the evaluation

+	 * @param arguments the <code>List</code> of <code>FunctionArgument</code>s for the evaluation

+	 * @return an {@link com.att.research.xacmlatt.pdp.policy.ExpressionResult} with the results of the call

+	 */

+	@Override

+	public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) {

+

+		if (arguments == null || arguments.size() != 1) {

+			return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, getShortFunctionId() + " Expected 1 argument, got " + 

+					((arguments == null) ? "null" : arguments.size()) ));

+		}

+		

+		FunctionArgument argument = arguments.get(0);

+		ConvertedArgument<Bag> convertedArgument = new ConvertedArgument<Bag>(argument, null, true);

+

+		if ( ! convertedArgument.isOk()) {

+			return ExpressionResult.newError(getFunctionStatus(convertedArgument.getStatus()));

+		}

+		

+		Bag bag = convertedArgument.getBag();

+		

+		if (bag.size() != 1) {

+			return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, getShortFunctionId() + 

+					" Expected 1 but Bag has " + bag.size() + " elements"));

+		}

+

+		// get the single value from the bag

+		AttributeValue<?> attributeValueOneAndOnly	= bag.getAttributeValues().next();

+		assert(attributeValueOneAndOnly != null);

+		

+		// make sure it has the right type

+		//

+		if (!this.getDataTypeId().equals(attributeValueOneAndOnly.getDataTypeId())) {

+			return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, getShortFunctionId() + 

+					" Element in bag of wrong type. Expected " + 

+					this.getShortDataTypeId(this.getDataTypeId()) + " got " + this.getShortDataTypeId(attributeValueOneAndOnly.getDataTypeId())));			

+		}

+		return ExpressionResult.newSingle(attributeValueOneAndOnly);

+	}

+

+

+	

+	

+

+}

diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagSize.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagSize.java
new file mode 100755
index 0000000..af75491
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagSize.java
@@ -0,0 +1,110 @@
+/*

+ *                        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.std.functions;

+

+import java.math.BigInteger;

+import java.util.List;

+

+import com.att.research.xacml.api.AttributeValue;

+import com.att.research.xacml.api.DataType;

+import com.att.research.xacml.api.Identifier;

+import com.att.research.xacml.api.XACML;

+import com.att.research.xacml.std.StdAttributeValue;

+import com.att.research.xacml.std.StdStatus;

+import com.att.research.xacml.std.StdStatusCode;

+import com.att.research.xacml.std.datatypes.DataTypes;

+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;

+import com.att.research.xacmlatt.pdp.policy.Bag;

+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;

+

+/**

+ * FunctionDefinitionBagSize implements {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition} to

+ * implement the XACML 'type'-bag-size predicates as functions taking one <code>Bag</code> argument and returning an <code>Integer</code> 

+ * representing the number of elements in the bag.

+ * 

+ * In the first implementation of XACML we had separate files for each XACML Function.

+ * This release combines multiple Functions in fewer files to minimize code duplication.

+ * This file supports the following XACML codes:

+ * 		string-bag-size

+ * 		boolean-bag-size

+ * 		integer-bag-size

+ * 		double-bag-size

+ * 		time-bag-size

+ * 		date-bag-size

+ * 		dateTime-bag-size

+ * 		anyURI-bag-size

+ * 		hexBinary-bag-size

+ * 		base64Binary-bag-size

+ * 		dayTimeDuration-bag-size (version 1 and3)

+ * 		yearMonthDuration-bag-size (version 1 and 3)

+ * 		x500Name-bag-size

+ * 		rfc822Name-bag-size

+ * 		ipAddress-bag-size

+ * 		dnsName-bag-size

+ * 

+ * 

+ * @author glenngriffin

+ * @version $Revision: 1.1 $

+ * 

+ * @param <I> the java class for the data type of the function Input arguments

+ */

+public class FunctionDefinitionBagSize<I> extends FunctionDefinitionBase<BigInteger, I> {

+

+

+	/**

+	 * Constructor - need dataType input because of java Generic type-erasure during compilation.

+	 * 

+	 * @param idIn

+	 * @param dataTypeArgsIn

+	 */

+	public FunctionDefinitionBagSize(Identifier idIn, DataType<I> dataTypeArgsIn) {

+		super(idIn, DataTypes.DT_INTEGER, dataTypeArgsIn, false);

+	}

+

+	/**

+	 * Evaluates this <code>FunctionDefinition</code> on the given <code>List</code> of{@link com.att.research.xacmlatt.pdp.policy.FunctionArgument}s.

+	 * 

+	 * @param evaluationContext the {@link com.att.research.xacmlatt.pdp.eval.EvaluationContext} to use in the evaluation

+	 * @param arguments the <code>List</code> of <code>FunctionArgument</code>s for the evaluation

+	 * @return an {@link com.att.research.xacmlatt.pdp.policy.ExpressionResult} with the results of the call

+	 */

+	@Override

+	public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) {

+

+		if (arguments == null || arguments.size() != 1) {

+			return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Expected 1 argument, got " + 

+					((arguments == null) ? "null" : arguments.size()) ));

+		}

+		

+		FunctionArgument argument = arguments.get(0);

+		ConvertedArgument<Bag> convertedArgument = new ConvertedArgument<Bag>(argument, null, true);

+

+		if ( ! convertedArgument.isOk()) {

+			return ExpressionResult.newError(getFunctionStatus(convertedArgument.getStatus()));

+		}

+		

+		Bag bag = convertedArgument.getBag();

+		

+		if (bag == null) {

+			return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Bag is null" ));

+

+		}

+

+

+		// type is correct, so create a wrapper and return it

+		AttributeValue<BigInteger> resultAttributeValue = new StdAttributeValue<BigInteger>(XACML.ID_DATATYPE_INTEGER, BigInteger.valueOf(bag.size()));

+		return ExpressionResult.newSingle(resultAttributeValue);

+	}

+

+	

+

+}

diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBase.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBase.java
new file mode 100755
index 0000000..390e9b2
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBase.java
@@ -0,0 +1,165 @@
+/*

+ *                        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.std.functions;

+

+import com.att.research.xacml.api.DataType;

+import com.att.research.xacml.api.Identifier;

+import com.att.research.xacml.api.Status;

+import com.att.research.xacml.std.StdStatus;

+import com.att.research.xacml.std.datatypes.DataTypeBoolean;

+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;

+import com.att.research.xacmlatt.pdp.policy.FunctionDefinition;

+

+

+/**

+ * /**

+ * FunctionDefinitionBase provides a common base for {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition}s.

+ * The child classes derived from this are of two types:

+ * <UL>

+ * <LI> Functions returning a single simple value of a type defined in {@link com.att.research.xacml.std.datatypes.DataTypes}.

+ * 	These functions will all derive from {@link com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionSimple}.

+ * <LI> Functions returning a single bag with elements of a single type.

+ * <UL>

+ * <P>

+ * This base class contains the following components:

+ * <UL>

+ * <LI> The Identity for this function.

+ * <LI> The DataType of the data returned from this function.  

+ * 	For Bags this means the DataType of the elements in the bag, or null if that is ambiguous.

+ * <LI> Commonly-used values.

+ * </UL>

+ * 

+ * @author glenngriffin

+ * 

+ * @param <O> the java class for the Output data type returned by the <code>FunctionDefinition</code>

+ * @param <I> the java class for the Input data type expected in the arguments to the <code>FunctionDefinition</code>.  

+ * 		Some functions have non-homogeneous arguments but may still have a main 'type'.

+ */

+public abstract class FunctionDefinitionBase<O,I> implements FunctionDefinition {

+	

+	// The XACML identifier string for this particular function

+	private Identifier	id;

+	

+	// each function derived from this returns a single non-bag data value of the following type, or a Bag containing elements of this type

+	private DataType<O>	dataTypeReturn;

+	

+	// All functions have input arguments and expect them to be of a given type.

+	// In some instances the argument gets multiple values of different types, but when the function has a 'type' associated with it's name

+	// specific ones of the input must be of this type.

+	// When an argument Input to the function is a Bag, the elements in that bag will be of this type.

+	// This corresponds most closely to the 'type' in the function name (as in 'type'-bag or 'type'-equals).

+	private DataType<I> dataTypeArgs;

+	

+	// true = the return value from this function is a bag; false = return value is a single-value DataType object

+	private boolean returnsBag;

+	

+	/*

+	 * For functions that return a Boolean result we create a single instance of the True/False return values that they can share

+	 */

+	protected static final ExpressionResult			ER_TRUE		= ExpressionResult.newSingle(DataTypeBoolean.AV_TRUE);

+	protected static final ExpressionResult			ER_FALSE	= ExpressionResult.newSingle(DataTypeBoolean.AV_FALSE);

+	

+	/**

+	 * Creates a new <code>FunctionDefinitionBase</code> with the {@link com.att.research.xacml.api.Identifier} <code>idIn</code> as

+	 * the function id.

+	 * 

+	 * @param idIn the <code>Identifier</code> for this <code>FunctionDefinitionBase</code>

+	 */

+	protected FunctionDefinitionBase(Identifier idIn, DataType<O> returnDataTypeIn, DataType<I> argumentDataTypeIn, boolean returnsBagIn) {

+		this.id			= idIn;

+		this.dataTypeReturn = returnDataTypeIn;

+		this.dataTypeArgs = argumentDataTypeIn;

+		this.returnsBag = returnsBagIn;

+	}

+	

+	/**

+	 * Returns a shortened version of the Id for this function, primarilly for use with error messages to prevent them from becoming too long.

+	 * This is a simple convenience method to reduce code bloat.

+	 * 

+	 * @return

+	 */

+	public String getShortFunctionId() {

+		return this.getId().getUri().toString().substring(this.getId().getUri().toString().indexOf("function:"));

+	}

+	

+	/**

+	 * Returns a shortened version of the given DataType Id, primarily for use with error messages to prevent them from becoming too long.

+	 * This is a simple convenience method to reduce code bloat.

+	 * 

+	 * @param identifier expected to have '#' in it, and if no '#' should have ":data-type:"

+	 * @return

+	 */

+	public String getShortDataTypeId(Identifier identifier) {

+		String idString = identifier.stringValue();

+		int index = idString.indexOf("#");

+		if (index < 0) {

+			index = idString.indexOf(":data-type:");

+			if (index < 0) {

+				return idString;

+			} else {

+				return idString.substring(index + 11);

+			}

+		} else {

+			return idString.substring(index+1);

+		}

+	}

+	

+	/**

+	 * Return a new Status that includes the name of this function in front of the original status' message.

+	 * This is a convenience method to reduce code bloat.

+	 * 

+	 * @param originalStatu

+	 * @return

+	 */

+	public Status getFunctionStatus(Status originalStatus) {

+		return new StdStatus(originalStatus.getStatusCode(), getShortFunctionId() + " " + originalStatus.getStatusMessage());

+	}

+	

+	

+	//

+	// Getters for the internal variables

+	//

+	

+	@Override

+	public Identifier getId() {

+		return this.id;

+	}

+	

+	@Override

+	public Identifier getDataTypeId() {

+		if (this.dataTypeReturn == null) {

+			return null;

+		} else {

+			return this.dataTypeReturn.getId();

+		}

+	}

+	

+	public DataType<O> getDataType() {

+		return this.dataTypeReturn;

+	}

+	

+	/**

+	 * Return the Identifier for the Input Argument(s) DataType.

+	 * 

+	 * @return

+	 */

+	public DataType<I> getDataTypeArgs() {

+		return this.dataTypeArgs;

+	}

+	

+	@Override

+	public boolean returnsBag() {

+		return returnsBag;

+	}

+	

+	

+	

+}

diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison.java
new file mode 100755
index 0000000..a6af460
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison.java
@@ -0,0 +1,136 @@
+/*

+ *                        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.std.functions;

+

+import java.util.ArrayList;

+import java.util.List;

+

+import com.att.research.xacml.api.DataType;

+import com.att.research.xacml.api.Identifier;

+import com.att.research.xacml.api.Status;

+import com.att.research.xacml.std.StdStatus;

+import com.att.research.xacml.std.StdStatusCode;

+import com.att.research.xacml.std.datatypes.DataTypes;

+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;

+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;

+

+/**

+ * FunctionDefinitionComparison implements {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition} to

+ * implement the XACML comparison predicates as functions taking two arguments of the same type

+ * and returning a <code>Boolean</code>.

+ * 

+ * In the first implementation of XACML we had separate files for each XACML Function.

+ * This release combines multiple Functions in fewer files to minimize code duplication.

+ * This file supports the following XACML codes:

+ * 		integer-greater-than

+ * 		integer-greater-than-or-equal

+ * 		integer-less-than

+ * 		integer-less-than-or-equal	

+ * 		double-greater-than

+ * 		double-greater-than-or-equal

+ * 		double-less-than

+ * 		double-less-than-or-equal 

+ * 

+ * 

+ * @author glenngriffin

+ * @version $Revision: 1.1 $

+ * 

+ * @param <I> the java class for the data type of the function Input arguments

+ */

+public class FunctionDefinitionComparison<I extends Comparable<I>> extends FunctionDefinitionHomogeneousSimple<Boolean, I> {

+

+	/**

+	 * List of comparison operations.

+	 * 

+	 * @author glenngriffin

+	 *

+	 */

+	public enum OPERATION {GREATER_THAN, GREATER_THAN_EQUAL, LESS_THAN, LESS_THAN_EQUAL };

+	

+	// the operation for this instance of the class

+	private OPERATION operation;

+	

+	

+	/**

+	 * Constructor - need dataType input because of java Generic type-erasure during compilation.

+	 * 

+	 * @param idIn

+	 * @param dataTypeArgsIn

+	 */

+	public FunctionDefinitionComparison(Identifier idIn, DataType<I> dataTypeArgsIn, OPERATION opIn) {

+		super(idIn, DataTypes.DT_BOOLEAN, dataTypeArgsIn, 2);

+		operation = opIn;

+	}

+

+

+	@Override

+	public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) {

+

+		List<I> convertedArguments	= new ArrayList<I>();

+		Status status				= this.validateArguments(arguments, convertedArguments);

+		

+		/*

+		 * If the function arguments are not correct, just return an error status immediately

+		 */

+		if (!status.getStatusCode().equals(StdStatusCode.STATUS_CODE_OK)) {

+			return ExpressionResult.newError(getFunctionStatus(status));

+		}

+		

+		int compareResult;

+		try {

+			compareResult = ((I)convertedArguments.get(0)).compareTo((I)convertedArguments.get(1));

+		} catch (Exception e) {

+			String message = e.getMessage();

+			if (e.getCause() != null) {

+				message = e.getCause().getMessage();

+			}

+			return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " " + message));

+		}

+

+		switch (operation) {

+		case GREATER_THAN:

+			if (compareResult > 0) {

+				return ER_TRUE;

+			} else {

+				return ER_FALSE;

+			}

+			

+		case GREATER_THAN_EQUAL:

+			if (compareResult > -1) {

+				return ER_TRUE;

+			} else {

+				return ER_FALSE;

+			}

+			

+		case LESS_THAN:

+			if (compareResult < 0) {

+				return ER_TRUE;

+			} else {

+				return ER_FALSE;

+			}

+			

+		case LESS_THAN_EQUAL:

+			if (compareResult < 1) {

+				return ER_TRUE;

+			} else {

+				return ER_FALSE;

+			}

+		}

+	

+		// switch on enum should handle everything - should never get here

+		return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " ENUM did not cover case of " + operation));

+

+	}

+

+

+

+}

diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic.java
new file mode 100755
index 0000000..5530065
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic.java
@@ -0,0 +1,125 @@
+/*

+ *                        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.std.functions;

+

+

+import java.util.List;

+

+import com.att.research.xacml.api.DataType;

+import com.att.research.xacml.api.DataTypeException;

+import com.att.research.xacml.api.Identifier;

+import com.att.research.xacml.std.StdStatus;

+import com.att.research.xacml.std.StdStatusCode;

+import com.att.research.xacml.std.datatypes.IDateTime;

+import com.att.research.xacml.std.datatypes.ISO8601Duration;

+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;

+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;

+

+/**

+ * FunctionDefinitionDateTimeArithmetic implements {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition} to

+ * implement the XACML Date and Time Arithmetic predicates.

+ * 

+ * In the first implementation of XACML we had separate files for each XACML Function.

+ * This release combines multiple Functions in fewer files to minimize code duplication.

+ * This file supports the following XACML codes:

+ * 		dateTime-add-dayTimeDuration

+ * 		dateTime-add-yearMonthDuration

+ * 		dateTime-subtract-dayTimeDuration

+ * 		dateTime-subtract-yearMonthDuration

+ * 		date-add-yearMonthDuration

+ * 		date-subtract-yearMonthDuration

+ * 

+ * 

+ * @author glenngriffin

+ * @version $Revision: 1.1 $

+ * 

+ * @param <I> the java class for the data type of the function Input arguments;

+ * 		SPECIAL CASE: this applies ONLY to the 2nd argument.

+ * @param <O> the java class for the data type of the function Output;

+ * 		SPECIAL CASE: this ALSO applies to the type of the 1st Input argument.

+ */

+public class FunctionDefinitionDateTimeArithmetic<O extends IDateTime<O>, I extends ISO8601Duration> extends FunctionDefinitionBase<O, I> {

+

+	/**

+	 * List of Date and Time Arithmetic operations.

+	 * 

+	 * @author glenngriffin

+	 *

+	 */

+	public enum OPERATION {ADD, SUBTRACT};

+	

+	// operation to be used in this instance of the class

+	private final OPERATION operation;

+

+	

+	

+	/**

+	 * Constructor - need dataTypeArgs input because of java Generic type-erasure during compilation.

+	 * 

+	 * @param idIn

+	 * @param dataTypeArgsIn

+	 */

+	public FunctionDefinitionDateTimeArithmetic(Identifier idIn, DataType<O> dataTypeIn, DataType<I> dataTypeArgsIn, OPERATION op) {

+		super(idIn, dataTypeIn, dataTypeArgsIn, false);

+		this.operation = op;

+	}

+

+	@Override

+	public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) {

+		if (arguments == null ||  arguments.size() != 2) {

+			return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + 

+					" Expected 2 arguments, got " + 

+					((arguments == null) ? "null" : arguments.size()) ));

+		}

+		

+		// first arg has same type as function output

+		FunctionArgument functionArgument = arguments.get(0);

+		ConvertedArgument<O> convertedArgument0 = new ConvertedArgument<O>(functionArgument, this.getDataType(), false);

+		if ( ! convertedArgument0.isOk()) {

+			return ExpressionResult.newError(getFunctionStatus(convertedArgument0.getStatus()));

+		}

+		O idateOrig	= convertedArgument0.getValue();

+		

+		// second argument is of input type

+		functionArgument = arguments.get(1);

+		ConvertedArgument<I> convertedArgument1 = new ConvertedArgument<I>(functionArgument, this.getDataTypeArgs(), false);

+		if ( ! convertedArgument1.isOk()) {

+			return ExpressionResult.newError(getFunctionStatus(convertedArgument1.getStatus()));

+		}

+		// get the Duration object from the argument which includes all fields, even if the incoming argument does not include them all

+		ISO8601Duration duration = convertedArgument1.getValue();

+		

+		// add/subtract the duration to the input argument

+		//

+		O idateResult	= null;

+		switch(this.operation) {

+		case ADD:

+			idateResult	= idateOrig.add(duration);

+			break;

+		case SUBTRACT:

+			idateResult	= idateOrig.sub(duration);

+			break;

+		}

+		ExpressionResult expressionResult	= null;

+		try {

+			expressionResult	= ExpressionResult.newSingle(this.getDataType().createAttributeValue(idateResult)); 

+		} catch (DataTypeException e) {

+			String message = e.getMessage();

+			if (e.getCause() != null) {

+				message = e.getCause().getMessage();

+			}

+			return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " " + message));			

+		}

+		return expressionResult; 

+	}

+	

+}

diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionEquality.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionEquality.java
new file mode 100755
index 0000000..af5c1e6
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionEquality.java
@@ -0,0 +1,88 @@
+/*

+ *                        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.std.functions;

+

+import java.util.ArrayList;

+import java.util.List;

+

+import com.att.research.xacml.api.DataType;

+import com.att.research.xacml.api.Identifier;

+import com.att.research.xacml.api.Status;

+import com.att.research.xacml.std.StdStatusCode;

+import com.att.research.xacml.std.datatypes.DataTypes;

+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;

+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;

+

+/**

+ * FunctionDefinitionEquality extends {@link com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionHomogeneousSimple} to

+ * implement the XACML Equality predicates as functions taking two arguments of the same data type and returning a <code>Boolean</code>.

+ * 

+ * In the first implementation of XACML we had separate files for each XACML Function.

+ * This release combines multiple Functions in fewer files to minimize code duplication.

+ * This file supports the following XACML codes:

+ * 		string-equal

+ * 		boolean-equal

+ * 		integer-equal

+ * 		double-equal

+ * 		date-equal

+ * 		time-equal

+ * 		dateTime-equal

+ * 		dayTimeDuration-equal

+ * 		yearMonthDuration-equal

+ * 		anyURI-equal

+ * 

+ * @author car

+ * @version $Revision: 1.2 $

+ * 

+ * @param <I> the java class for the data type of the function Input arguments

+ */

+public class FunctionDefinitionEquality<I> extends FunctionDefinitionHomogeneousSimple<Boolean, I> {

+	

+	/**

+	 * Determines if the two <code>T</code> values are equal using the java <code>equals</code> method.  Derived classes

+	 * may override this if the <code>equals</code> method is not sufficient.

+	 * 

+	 * @param v1 the first object to compare

+	 * @param v2 the second object to compare

+	 * @return true if the two objects are the same, else false

+	 */

+	protected boolean isEqual(I v1, I v2) {

+		return v1.equals(v2);

+	}

+	

+	public FunctionDefinitionEquality(Identifier idIn, DataType<I> dataTypeArgsIn) {

+		super(idIn, DataTypes.DT_BOOLEAN, dataTypeArgsIn, 2);

+	}

+

+	@Override

+	public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) {

+		List<I> convertedArguments	= new ArrayList<I>();

+		Status status				= this.validateArguments(arguments, convertedArguments);

+		

+		/*

+		 * If the function arguments are not correct, just return an error status immediately

+		 */

+		if (!status.getStatusCode().equals(StdStatusCode.STATUS_CODE_OK)) {

+			return ExpressionResult.newError(getFunctionStatus(status));

+		}

+		

+		/*

+		 * Now just perform the equality operation.

+		 */

+		if (this.isEqual(convertedArguments.get(0), convertedArguments.get(1))) {

+			return ER_TRUE;

+		} else {

+			return ER_FALSE;

+		}

+	}

+

+}

diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag.java
new file mode 100755
index 0000000..515cbd5
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag.java
@@ -0,0 +1,523 @@
+/*

+ *                        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.std.functions;

+

+import java.net.URI;

+import java.util.ArrayList;

+import java.util.Iterator;

+import java.util.List;

+

+import com.att.research.xacml.api.AttributeValue;

+import com.att.research.xacml.api.DataType;

+import com.att.research.xacml.api.Identifier;

+import com.att.research.xacml.std.IdentifierImpl;

+import com.att.research.xacml.std.StdStatus;

+import com.att.research.xacml.std.StdStatusCode;

+import com.att.research.xacml.std.datatypes.DataTypes;

+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;

+import com.att.research.xacmlatt.pdp.policy.Bag;

+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue;

+import com.att.research.xacmlatt.pdp.policy.FunctionDefinition;

+import com.att.research.xacmlatt.pdp.std.StdFunctionDefinitionFactory;

+

+/**

+ * FunctionDefinitionSet implements {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition} to

+ * implement the XACML Set predicates as functions taking two arguments of <code>Bag</code> the same primitive type

+ * and returning either a <code>Boolean</code> or a <code>Bag</code> of the same primitive type.

+ * <P>

+ * The ipAddress, dnsName and xPathExpression do not have set functions defined for them in section 10.2.8 of the Release 3 XACML spec.

+ * 

+ * In the first implementation of XACML we had separate files for each XACML Function.

+ * This release combines multiple Functions in fewer files to minimize code duplication.

+ * This file supports the following XACML codes:

+ * 		string-bag

+ * 		boolean-bag

+ * 		integer-bag

+ * 		double-bag

+ * 		time-bag

+ * 		date-bag

+ * 		dateTime-bag

+ * 		anyURI-bag

+ * 		hexBinary-bag

+ * 		base64Binary-bag

+ * 		dayTimeDuration-bag (version 1 and3)

+ * 		yearMonthDuration-bag (version 1 and 3)

+ * 		x500Name-bag

+ * 		rfc822Name-bag

+ * 

+ * 

+ * @author glenngriffin

+ * @version $Revision: 1.1 $

+ * 

+ * @param <I> the java class for the data type of the function Input arguments

+ * @param <O> the java class for the data type of the function Output

+ */

+public class FunctionDefinitionHigherOrderBag<O,I> extends FunctionDefinitionBase<O, I> {

+

+	/**

+	 * List of comparison operations.

+	 * 

+	 * @author glenngriffin

+	 *

+	 */

+	public enum OPERATION {ANY_OF, ALL_OF, ANY_OF_ANY, ALL_OF_ANY, ANY_OF_ALL, ALL_OF_ALL, MAP  };

+	

+	// the operation for this instance of the class

+	private OPERATION operation;

+	

+	

+	/**

+	 * Constructor - need dataType input because of java Generic type-erasure during compilation.

+	 * 

+	 * @param idIn

+	 * @param dataTypeArgsIn

+	 */

+	public FunctionDefinitionHigherOrderBag(Identifier idIn, DataType<O> dataTypeIn, DataType<I> dataTypeArgsIn, OPERATION opIn) {

+		super(idIn, dataTypeIn, dataTypeArgsIn, ((opIn == OPERATION.MAP) ? true : false) );

+		operation = opIn;

+	}

+

+

+	@Override

+	public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) {

+

+		// simple argument check

+		if (arguments == null || arguments.size() < 2) {

+			return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + 

+					" Expected at least 2 arguments, got " + 

+					((arguments == null) ? "null" : arguments.size()) ));

+		}

+		

+		// three functions have some things known about the arguments

+		if (operation == OPERATION.ALL_OF_ANY || operation == OPERATION.ANY_OF_ALL || operation == OPERATION.ALL_OF_ALL) {

+			if (arguments.size() != 3) {

+				return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + 

+					" Expected 3 arguments, got " + arguments.size()) );

+			}

+			// the 2nd & 3rd arguments must both be bags

+			if ( arguments.get(1) == null || ! arguments.get(1).isBag() ) {

+				return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + 

+						" 2nd argument must be bag, got '" + ((arguments.get(1) == null) ? "null" : this.getShortDataTypeId(arguments.get(1).getValue().getDataTypeId())) + "'" ));

+			}

+			if (arguments.get(2) == null || ! arguments.get(2).isBag() ) {

+				return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + 

+						" 3rd argument must be bag, got '" + ((arguments.get(2) == null) ? "null" : this.getShortDataTypeId(arguments.get(2).getValue().getDataTypeId())) + "'" ));

+			}

+		}

+		

+		// first argument is supposed to be a Function ID passed to us as an AnyURI

+		FunctionArgument functionIdArgument = arguments.get(0);

+		if (functionIdArgument == null || functionIdArgument.getValue() == null) {

+			return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + 

+					" Predicate Function (first argument) was null"));

+		}

+		if ( ! functionIdArgument.getValue().getDataTypeId().equals(DataTypes.DT_ANYURI.getId())) {

+			return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + 

+					" First argument expected URI, got " + functionIdArgument.getValue().getDataTypeId() ) );

+		}

+		Identifier functionId = new IdentifierImpl((URI) functionIdArgument.getValue().getValue());

+		

+		// look up the actual function definition based on that ID

+		StdFunctionDefinitionFactory fdf = new StdFunctionDefinitionFactory();

+		

+		FunctionDefinition predicate = fdf.getFunctionDefinition(functionId);

+		

+		if (predicate == null) {

+			return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + 

+					" First argument was not URI of a function, got '" + functionId + "'") );

+		}

+		// in all cases except MAP, the predicate must return True/False

+		if (operation != OPERATION.MAP) {

+			if ( ! predicate.getDataTypeId().equals(DataTypes.DT_BOOLEAN.getId())) {

+				return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + 

+						" Predicate Function must return boolean, but '" + predicate.getId() + "' returns '" + this.getShortDataTypeId(predicate.getDataTypeId()) ));

+			}

+		}

+		

+		

+		

+		// The remaining arguments may be either bags or primitive types.

+		// We do not know what the primitive types will be, and do not concern ourselves about that here 

+		// (the predicate function we just got and will call later will complain if they do not match its expectations).

+		// The predicate function will want things as FunctionAttributes, so we do not need to unwrap anything.

+		boolean bagSeen = false;

+		for (int i = 1; i < arguments.size(); i++) {

+			FunctionArgument argument = arguments.get(i);

+			if (argument == null) {

+				return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + 

+						" Got null argument at index " + i) );

+			}

+			// force evaluation and check status

+			if ( ! argument.getStatus().isOk()) {

+				return ExpressionResult.newError(getFunctionStatus(argument.getStatus()));

+			}

+

+			// for bags, remember that we saw one; for non-bag primitives, check that the primitive value is not null

+			if (argument.isBag()) {

+				bagSeen = true;

+			} else {

+				if (argument.getValue() == null || argument.getValue().getValue() == null) {

+					return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + 

+							" Got null attribute at index " + i) );

+				}

+			}

+		}

+

+		// all functions require at least one bag

+		if ( ! bagSeen && operation != OPERATION.ANY_OF_ANY) {

+			return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + 

+					" Did not get any Bag argument; must have at least 1") );

+		}

+		

+		

+		// arguments are ready for use

+		

+		// list of arguments for passing to the predicate

+		List<FunctionArgument> predicateArguments = new ArrayList<FunctionArgument>();

+

+		// for functions that take a single bag, which index is that bag at

+		int indexOfBagInOriginalArgs = -1;

+		

+		// bag iterator

+		Iterator<AttributeValue<?>> bagIterator1;

+		Iterator<AttributeValue<?>> bagIterator2;

+

+		

+		

+		

+		switch (operation) {

+		

+		case ANY_OF:

+			// Copy the primitive arguments to the list for passing to the predicate,

+			// putting a place-holder in for the value from the (single) bag

+			for (int i = 1; i < arguments.size(); i++) {

+				predicateArguments.add(arguments.get(i));

+				if (arguments.get(i).isBag()) {

+					if (indexOfBagInOriginalArgs == -1) {

+						indexOfBagInOriginalArgs = i ;

+					} else {

+						// bag already found - we should have only one

+						return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + 

+								" must have only 1 bag; found one at index " + indexOfBagInOriginalArgs + " and another at " + i) );

+					}

+				}

+			}

+			

+			// get each primitive value in turn

+			bagIterator1 = arguments.get(indexOfBagInOriginalArgs).getBag().getAttributeValues();

+			while (bagIterator1.hasNext()) {

+				// all of the predicate arguments have been created except that the one from the bag needs to replace the place-holder in the list

+				predicateArguments.set(indexOfBagInOriginalArgs - 1, new FunctionArgumentAttributeValue(bagIterator1.next()));

+				ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments);

+				if ( ! res.isOk()) {

+					return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + 

+							" Predicate error: " + res.getStatus().getStatusMessage()) );

+				}

+				if ( (Boolean)(res.getValue().getValue()) == true) {

+					return ER_TRUE;

+				}

+			}

+

+			return ER_FALSE;

+			

+			

+			

+		case ALL_OF:

+			// Copy the primitive arguments to the list for passing to the predicate,

+			// putting a place-holder in for the value from the (single) bag

+			for (int i = 1; i < arguments.size(); i++) {

+				predicateArguments.add(arguments.get(i));

+				if (arguments.get(i).isBag()) {

+					if (indexOfBagInOriginalArgs == -1) {

+						indexOfBagInOriginalArgs = i ;

+					} else {

+						// bag already found - we should have only one

+						return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + 

+								" must have only 1 bag; found one at index " + indexOfBagInOriginalArgs + " and another at " + i) );

+					}

+				}

+			}

+			

+			// get each primitive value in turn

+			bagIterator1 = arguments.get(indexOfBagInOriginalArgs).getBag().getAttributeValues();

+			while (bagIterator1.hasNext()) {

+				// all of the predicate arguments have been created except that the one from the bag needs to replace the place-holder in the list

+				predicateArguments.set(indexOfBagInOriginalArgs - 1, new FunctionArgumentAttributeValue(bagIterator1.next()));

+				ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments);

+				if ( ! res.isOk()) {

+					return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + 

+							" Predicate error: " + res.getStatus().getStatusMessage()) );

+				}

+				if ( (Boolean)(res.getValue().getValue()) == false) {

+					return ER_FALSE;

+				}

+			}

+			return ER_TRUE;

+		

+			

+		case ANY_OF_ANY:

+			// empty bags can give odd error messages, so check here and return something that makes more sense

+			for (int i = 1; i < arguments.size(); i++) {

+				if (arguments.get(i).isBag() && arguments.get(i).getBag().size() == 0) {

+					return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + 

+							" Bag is empty at index " + i ));

+				}

+			}

+			// This is different from all the other Higher-order bag functions because it can take an unbounded number of arguments any/all of which may be bags.

+			// (The others take either an unbounded number of args of which exactly 1 is a bag, or they take exactly 2 bags)

+			// To handle the possibility of multiple bags without knowing a priori how many there might be,

+			// we first create all possible lists of arguments to be passed to the predicate.

+			// This is done using a depth-first search of the total argument space.

+			List<List<FunctionArgument>> listOfPredicateLists = new ArrayList<List<FunctionArgument>>();		

+			

+			/*

+			 * Start the recursive append process

+			 */

+			appendCrossProduct(new ArrayList<FunctionArgument>(), arguments.subList(1, arguments.size()), 0, listOfPredicateLists);

+			

+			// we now have all possible argument lists for the predicate to work on, so do the ANY operation now

+			for (List<FunctionArgument> predicateArgumentList : listOfPredicateLists) {

+				// all of the predicate arguments have been created except that the one from the bag needs to replace the place-holder in the list

+				ExpressionResult res = predicate.evaluate(evaluationContext, predicateArgumentList);

+				if ( ! res.isOk()) {

+					return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + 

+							" Predicate error: " + res.getStatus().getStatusMessage()) );

+				}

+				if ( (Boolean)(res.getValue().getValue()) == true) {

+					return ER_TRUE;

+				}

+			}

+			

+			// if we get here then none of the combinations gave a TRUE result

+			return ER_FALSE;

+		

+			

+			

+		case ALL_OF_ANY:

+//TODO - it might be more efficient to extract all the attributes from the first bag and convert them to FunctionArguments just once, then use that list each time

+			

+			// get the element from the 2nd bag that we want to check all elements from the 1st bag against

+			bagIterator2 = arguments.get(2).getBag().getAttributeValues();

+			while (bagIterator2.hasNext()) {

+				FunctionArgument predicateArgument2 = new FunctionArgumentAttributeValue(bagIterator2.next());

+				boolean allMatch = true;

+				

+				// now look at every value of the first bag operating with the selected value from the 2nd

+				bagIterator1 = arguments.get(1).getBag().getAttributeValues();

+				while (bagIterator1.hasNext()) {

+

+					predicateArguments.clear();

+					predicateArguments.add(new FunctionArgumentAttributeValue(bagIterator1.next()));

+					predicateArguments.add(predicateArgument2);

+					

+					ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments);

+					if ( ! res.isOk()) {

+						return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + 

+								" Predicate error: " + res.getStatus().getStatusMessage()) );

+					}

+					if ( (Boolean)(res.getValue().getValue()) == false) {

+						allMatch = false;

+						break;

+					}

+				}

+				if (allMatch) {

+					// wee found one value in bag2 that works (is TRUE) for all values in bag1

+					return ER_TRUE;

+				}

+				// this value from bag2 did not work, so get the next one

+			}

+			

+			// no value in bag2 worked for all values of bag1

+			return ER_FALSE;

+

+			

+			

+		case ANY_OF_ALL:

+//TODO - it might be more efficient to extract all the attributes from the 2nd bag and convert them to FunctionArguments just once, then use that list each time

+			

+			// get the element from the 1st bag that we want to check all elements from the 1st bag against

+			bagIterator1 = arguments.get(1).getBag().getAttributeValues();

+			while (bagIterator1.hasNext()) {

+				FunctionArgument predicateArgument1 = new FunctionArgumentAttributeValue(bagIterator1.next());

+				boolean allMatch = true;

+				

+				// now look at every value of the 2nd bag operating with the selected value from the first

+				bagIterator2 = arguments.get(2).getBag().getAttributeValues();

+				while (bagIterator2.hasNext()) {

+					predicateArguments.clear();

+					predicateArguments.add(predicateArgument1);

+					predicateArguments.add(new FunctionArgumentAttributeValue(bagIterator2.next()));

+					

+					ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments);

+					if ( ! res.isOk()) {

+						return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + 

+								" Predicate error: " + res.getStatus().getStatusMessage()) );

+					}

+					if ( (Boolean)(res.getValue().getValue()) == false) {

+						allMatch = false;

+						break;

+					}

+				}

+				if (allMatch) {

+					// wee found one value in bag1 that works (is TRUE) for all values in bag2

+					return ER_TRUE;

+				}

+				// this value from bag1 did not work, so get the next one

+			}

+			

+			// no value in bag1 worked for all values of bag2

+			return ER_FALSE;

+			

+			

+			

+		case ALL_OF_ALL:

+//TODO - it might be more efficient to extract all the attributes from the 2nd bag and convert them to FunctionArguments just once, then use that list each time

+

+			// get the element from the 1st bag that we want to check all elements from the 1st bag against

+			bagIterator1 = arguments.get(1).getBag().getAttributeValues();

+			while (bagIterator1.hasNext()) {

+				FunctionArgument predicateArgument1 = new FunctionArgumentAttributeValue(bagIterator1.next());

+

+				// now look at every value of the 2nd bag operating with the selected value from the first

+				bagIterator2 = arguments.get(2).getBag().getAttributeValues();

+				while (bagIterator2.hasNext()) {

+					predicateArguments.clear();

+					predicateArguments.add(predicateArgument1);

+					predicateArguments.add(new FunctionArgumentAttributeValue(bagIterator2.next()));

+

+					ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments);

+					if ( ! res.isOk()) {

+						return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + 

+								" Predicate error: " + res.getStatus().getStatusMessage()) );

+					}

+

+					if ( (Boolean)(res.getValue().getValue()) == false) {

+						return ER_FALSE;

+					}

+				}

+				// this value did not fail, so try the next

+			}

+			

+			// everything in bag1 worked (was true) for everything in bag 2

+			return ER_TRUE;

+			

+			

+			

+		case MAP:

+			// Copy the primitive arguments to the list for passing to the predicate,

+			// putting a place-holder in for the value from the (single) bag

+			for (int i = 1; i < arguments.size(); i++) {

+				predicateArguments.add(arguments.get(i));

+				if (arguments.get(i).isBag()) {

+					if (indexOfBagInOriginalArgs == -1) {

+						indexOfBagInOriginalArgs = i ;

+					} else {

+						// bag already found - we should have only one

+						return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + 

+								" must have only 1 bag; found one at index " + indexOfBagInOriginalArgs + " and another at " + i) );

+					}

+				}

+			}

+			

+			Bag outputBag = new Bag();

+			

+			// get each primitive value in turn

+			bagIterator1 = arguments.get(indexOfBagInOriginalArgs).getBag().getAttributeValues();

+			while (bagIterator1.hasNext()) {

+				// all of the predicate arguments have been created except that the one from the bag needs to replace the place-holder in the list

+				predicateArguments.set(indexOfBagInOriginalArgs - 1, new FunctionArgumentAttributeValue(bagIterator1.next()));

+				ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments);

+				if ( ! res.isOk()) {

+					return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + 

+							" Predicate error: " + res.getStatus().getStatusMessage()) );

+				}

+				if (res.isBag()) {

+					return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + 

+							" Cannot put bag inside bag; predicate was '" + predicate.getId() + "'"));

+				}

+				outputBag.add(res.getValue());

+			}

+			

+			

+			return ExpressionResult.newBag(outputBag);

+			

+		}

+	

+		// all cases should have been covered by above - should never get here

+		return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Could not evaluate Higher-Order Bag function " + operation));

+

+	}

+

+

+	

+	

+	

+	

+	

+	

+	

+	

+	

+	

+	/**

+	 * Performs the depth-first walk to generate argument lists.  Needed by any-of-any because of the variable number of bags it might get.

+	 * 

+	 * This code was salvaged from the R2 version of the product and adjusted to fit the new way of doing business.

+	 * 

+	 * @param argListInProgress the current argument list being generated in this pass

+	 * @param valueList the list of expression result values 

+	 * @param nPosition the position within the expression result values to use to append to the base argument list

+	 * @param listArgLists the <code>List</code> where final argument lists are appended

+	 */

+	private static void appendCrossProduct(List<FunctionArgument> argListInProgress, List<FunctionArgument> valueList, int nPosition, List<List<FunctionArgument>> listArgLists) {

+		/*

+		 * Have we hit a leaf?

+		 */

+		if (nPosition >= valueList.size()) {

+			List<FunctionArgument>	copy	= new ArrayList<FunctionArgument>();

+			copy.addAll(argListInProgress);

+			listArgLists.add(copy);

+			return;

+		}

+		

+		/*

+		 * Check to see if the value at the current position is a primitive or a bag

+		 */

+		FunctionArgument	FunctionArgument	= valueList.get(nPosition);

+		if (FunctionArgument.isBag() && FunctionArgument.getBag().getAttributeValues() != null && FunctionArgument.getBag().size() > 0) {

+			Iterator<AttributeValue<?>>	iterBagValues	= FunctionArgument.getBag().getAttributeValues();

+			while (iterBagValues.hasNext()) {

+				AttributeValue<?>	attributeValue	= iterBagValues.next();

+				FunctionArgument	functionArgument	= new FunctionArgumentAttributeValue(attributeValue);

+				argListInProgress.add(functionArgument);

+				appendCrossProduct(argListInProgress, valueList, nPosition+1, listArgLists);

+				argListInProgress.remove(argListInProgress.size()-1);

+			}

+		} else {

+			/*

+			 * This is a simple value, so we can just append to the argListInProgress and continue the recursion

+			 */

+			argListInProgress.add(FunctionArgument);

+			appendCrossProduct(argListInProgress, valueList, nPosition+1, listArgLists);

+			argListInProgress.remove(argListInProgress.size()-1);

+		}

+	}

+	

+	

+	

+	

+	

+	

+	

+

+}

diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHomogeneousSimple.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHomogeneousSimple.java
new file mode 100755
index 0000000..a41ccbe
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHomogeneousSimple.java
@@ -0,0 +1,142 @@
+/*

+ *                        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.std.functions;

+

+import java.util.List;

+

+import com.att.research.xacml.api.DataType;

+import com.att.research.xacml.api.Identifier;

+import com.att.research.xacml.api.Status;

+import com.att.research.xacml.std.StdStatus;

+import com.att.research.xacml.std.StdStatusCode;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;

+

+/**

+ * FunctionDefinitionHomogeneousSimple extends {@link com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionSimple}

+ * with utility methods for ensuring the types of the arguments passed in the <code>evaluate</code> method matches the parameterized

+ * type, and the number of arguments is correct.

+ * When evaluated the resulting arguments must be simple data types, not bags.

+ * 

+ * The various functions have the following needs with respect to their arguments:

+ * <UL>

+ * <LI>

+ * The argument list size is pre-defined and all arguments can be evaluated at once before the function is called.

+ * <LI>

+ * The argument list size is pre-defined but the arguments must be evaluated one at a time by the function.

+ * <LI>

+ * The argument list size is not pre-defined.

+ * </UL>

+ * To support those needs this class includes methods for checking the list size and evaluating a single argument as well as

+ * combining those operations in a single method to make it simpler for the calling function.

+ * 

+ * @author car

+ * @version $Revision: 1.3 $

+ *

+ * @param <O> the java class for the value of the Output return result from the <code>FunctionDefinition</code>

+ * @param <I> the java class for the value of the Input {@link com.att.research.xacmlatt.pdp.policy.FunctionArgument}s in the <code>evaluate</code> method

+ */

+public abstract class FunctionDefinitionHomogeneousSimple<O,I> extends FunctionDefinitionBase<O,I> {

+	

+

+	// null means that number of arguments is variable

+	private Integer			numArgs;

+	

+	/**

+	 * Constructor

+	 * 

+	 * @param idIn

+	 * @param dataTypeReturnIn

+	 * @param dataTypeArgsIn

+	 * @param nArgs

+	 */

+	public FunctionDefinitionHomogeneousSimple(Identifier idIn, DataType<O> dataTypeReturnIn, DataType<I> dataTypeArgsIn, Integer nArgs) {

+		super(idIn, dataTypeReturnIn, dataTypeArgsIn, false);

+		this.numArgs		= nArgs;

+	}

+	

+

+	/**

+	 * Gets the number of arguments expected to this <code>FunctionDefinition</code>.

+	 * For functions without a pre-defined number of arguments this is not used.

+	 * 

+	 * @return the number of arguments expected to this <code>FunctionDefinition</code>.

+	 */

+	public Integer getNumArgs() {

+		return this.numArgs;

+	}

+	

+	

+	/**

+	 * Validates the given <code>List</code> of <code>FunctionArgument</code>s has the correct count and <code>DataType</code> and evaluates expressions.

+	 * This combines both the argument list length check and the evaluation of all arguments on that list.

+	 * 

+	 * @param listFunctionArguments the <code>List</code> of <code>FunctionArgument</code>s to validate

+	 * @return a {@link com.att.research.xacml.api.Status} indication with an error if the arguments are not valid

+	 */

+	public Status validateArguments(List<FunctionArgument> listFunctionArguments, List<I> convertedValues) {

+		/*

+		 * See if we have to validate the number of arguments

+		 */

+		Status listLengthStatus = validateArgumentListLength(listFunctionArguments);

+		if ( ! listLengthStatus.isOk()) {

+			return listLengthStatus;

+		}

+		

+		

+		/*

+		 * Now validate the types of the arguments

+		 */

+		for (int i = 0; i < listFunctionArguments.size(); i++) {

+			FunctionArgument functionArgument = listFunctionArguments.get(i);

+			ConvertedArgument<I> argument = new ConvertedArgument<I>(functionArgument, getDataTypeArgs(), false);

+			if ( ! argument.isOk()) {

+				// when a Status is returned that indicates an error, tell caller which arg had problem

+				Status decoratedStatus = new StdStatus(argument.getStatus().getStatusCode(), argument.getStatus().getStatusMessage() + " at arg index " + i  );

+				return decoratedStatus;

+			}

+			if (convertedValues != null) {

+				convertedValues.add(argument.getValue());

+			}

+		}

+		

+		/*

+		 * Everything passed the data type test, so we are good to go

+		 */

+		return StdStatus.STATUS_OK;

+	}

+	

+	

+	/**

+	 * Validates the given <code>List</code> of <code>FunctionArgument</code>s has the correct count.

+	 * 

+	 * @param listFunctionArguments the <code>List</code> of <code>FunctionArgument</code>s to validate

+	 * @return a {@link com.att.research.xacml.api.Status} indication with an error if the arguments are not valid

+	 */

+	public Status validateArgumentListLength(List<FunctionArgument> listFunctionArguments) {

+		/*

+		 * See if we have to validate the number of arguments

+		 */

+		if ((listFunctionArguments == null && this.numArgs > 0 ) ||

+				(listFunctionArguments != null && this.numArgs != listFunctionArguments.size()) ) {

+			return new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Expected " + this.numArgs + " arguments, got " + 

+				((listFunctionArguments == null) ? 0 : listFunctionArguments.size())  );

+		}

+		

+		/*

+		 * Everything passed the data type test, so we are good to go

+		 */

+		return StdStatus.STATUS_OK;

+	}

+	

+	

+	

+

+}

diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical.java
new file mode 100755
index 0000000..a99456b
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical.java
@@ -0,0 +1,219 @@
+/*

+ *                        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.std.functions;

+

+import java.util.List;

+

+import com.att.research.xacml.api.AttributeValue;

+import com.att.research.xacml.api.Identifier;

+import com.att.research.xacml.std.StdStatus;

+import com.att.research.xacml.std.StdStatusCode;

+import com.att.research.xacml.std.datatypes.DataTypes;

+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;

+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;

+

+/**

+ * FunctionDefinitionLogical extends {@link com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionHomogeneousSimple} to

+ * implement the XACML Logic predicates as functions taking zero, one, or multiple arguments of type <code>Boolean</code> and returning a <code>Boolean</code>.

+ * 

+ * In the first implementation of XACML we had separate files for each XACML Function.

+ * This release combines multiple Functions in fewer files to minimize code duplication.

+ * This file supports the following XACML codes:

+ * 		or

+ * 		and

+ * 		n-of

+ * 		not

+ * 

+ * @author glenngriffin

+ * @version $Revision: 1.1 $

+ * 

+ */

+public class FunctionDefinitionLogical extends FunctionDefinitionHomogeneousSimple<Boolean,Boolean> {

+	

+	/**

+	 * List of Logical Operations types

+	 * 

+	 * @author glenngriffin

+	 *

+	 */

+	public enum OPERATION {OR, AND, N_OF, NOT}

+	

+	// the operation that this instance is being asked to do

+	private final OPERATION operation;

+	

+	

+	public FunctionDefinitionLogical(Identifier idIn, OPERATION op) {

+		super(idIn, DataTypes.DT_BOOLEAN, DataTypes.DT_BOOLEAN, null);

+		operation = op;

+	}

+

+	

+	@Override

+	public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) {

+		

+		switch (operation) {

+		case OR:

+			if (arguments == null || arguments.size() == 0) {

+				return ER_FALSE;

+			}

+			try {

+				// evaluate the arguments one at a time and abort on the first true

+				for (int i = 0; i < arguments.size(); i++) {

+					ConvertedArgument<Boolean> argument = new ConvertedArgument<Boolean>(arguments.get(i), this.getDataTypeArgs(), false);

+					if ( ! argument.isOk()) {

+						// return a decorated message

+						return ExpressionResult.newError(getFunctionStatus(argument.getStatus()));

+					}

+					if (argument.getValue() == true) {

+						return ER_TRUE;

+					}

+				}

+			} catch (Exception e) {

+				String message = e.getMessage();

+				if (e.getCause() != null) {

+					message = e.getCause().getMessage();

+				}

+				return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " " + message));

+			}

+			return ER_FALSE;

+

+			

+		case AND:

+			if (arguments == null || arguments.size() == 0) {

+				return ER_TRUE;

+			}

+			try {

+				// evaluate the arguments one at a time and abort on the first false

+				for (int i = 0; i < arguments.size(); i++) {

+					ConvertedArgument<Boolean> argument = new ConvertedArgument<Boolean>(arguments.get(i), this.getDataTypeArgs(), false);

+					if ( ! argument.isOk()) {

+						return ExpressionResult.newError(getFunctionStatus(argument.getStatus()));

+					}

+					if (argument.getValue() == false) {

+						return ER_FALSE;

+					}

+				}

+

+			} catch (Exception e) {

+				String message = e.getMessage();

+				if (e.getCause() != null) {

+					message = e.getCause().getMessage();

+				}

+				return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " " + message));

+			}

+			return ER_TRUE;

+			

+			

+		case N_OF:

+			Integer argumentCountNeeded;

+			int trueArgumentsSeen = 0;

+			if (arguments == null || arguments.size() == 0) {

+				return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Expected 1 argument, got 0"));

+			}

+			try {

+				//

+				// Special case:

+				//	The first argument in the list (an Integer) is not homogeneous with the rest of the arguments (Booleans).

+				//	While this is technically not a FunctionDefinitionHomogeneousSimple type of object, we derive from that class anyway

+				//	so that we can take advantage of the validateArgument() method in that class.

+				//	Unfortunately we cannot re-use that same code (because of generics - it gets messy) for the Integer argument.

+				//	The following code essentially does the same job as validateArgument() on the first argument in the list.

+				//

+				

+				// first arg is the number of remaining arguments that must be TRUE

+				if (arguments.get(0) == null) {

+					return ER_TRUE;

+				}

+				if ( ! arguments.get(0).getStatus().isOk()) {

+					return ExpressionResult.newError(getFunctionStatus(arguments.get(0).getStatus()));

+				}

+				if (arguments.get(0).isBag()) {

+					return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Expected a simple value, saw a bag"));

+				}

+				AttributeValue<?> attributeValue = arguments.get(0).getValue();

+				if (attributeValue == null) {

+					// assume this is the same as "first argument is 0"

+					return ER_TRUE;

+				}

+

+				argumentCountNeeded = DataTypes.DT_INTEGER.convert(attributeValue.getValue()).intValue();

+				if (argumentCountNeeded == 0) {

+					return ER_TRUE;

+				}

+				if (arguments.size() - 1 < argumentCountNeeded) {

+					// return a non-OK status to signal indeterminate

+					return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +

+							" Expected " + argumentCountNeeded + " arguments but only " +

+							(arguments.size() - 1) + " arguments in list after the count"));

+				}

+				for (int i = 1; i < arguments.size(); i++) {

+					ConvertedArgument<Boolean> argument = new ConvertedArgument<Boolean>(arguments.get(i), this.getDataTypeArgs(), false);

+					if ( ! argument.isOk()) {

+						return ExpressionResult.newError(getFunctionStatus(argument.getStatus()));

+					}

+					if ((argument.getValue()) == true) {

+						trueArgumentsSeen++;

+						if (trueArgumentsSeen >= argumentCountNeeded) {

+							return ER_TRUE;

+						}

+					}

+					// if we cannot reach the goal, stop now.

+					// remaining entries to be looked at = list size - i - 1, which is the most additional TRUEs that we could get.

+					if ( (arguments.size() - i - 1) + trueArgumentsSeen < argumentCountNeeded) {

+						// do not evaluate remaining entries

+						return ER_FALSE;

+					}

+				}

+				// did not reach our goal

+				return ER_FALSE;

+				

+			} catch (Exception e) {

+				String message = e.getMessage();

+				if (e.getCause() != null) {

+					message = e.getCause().getMessage();

+				}

+				return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " " + message));

+			}

+			

+			

+		case NOT:

+			if (arguments == null || arguments.size() != 1) {

+				return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Expected 1 argument, got " +

+						((arguments == null) ? "null" : arguments.size()) ) );

+			}

+			try {

+				ConvertedArgument<Boolean> argument = new ConvertedArgument<Boolean>(arguments.get(0), this.getDataTypeArgs(), false);

+				if ( ! argument.isOk()) {

+					return ExpressionResult.newError(getFunctionStatus(argument.getStatus()));

+				}

+				if (argument.getValue() == true) {

+					return ER_FALSE;

+				} else {

+					return ER_TRUE;

+				}

+			} catch (Exception e) {

+				String message = e.getMessage();

+				if (e.getCause() != null) {

+					message = e.getCause().getMessage();

+				}

+				return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " " + message));

+			}

+		}

+		

+		// all cases should have been covered by above - should never get here

+		return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Could not evaluate Logical function " + operation));

+

+	}

+

+	

+

+}

diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionNumberTypeConversion.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionNumberTypeConversion.java
new file mode 100755
index 0000000..ce5ec07
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionNumberTypeConversion.java
@@ -0,0 +1,90 @@
+/*

+ *                        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.std.functions;

+

+import java.math.BigInteger;

+import java.util.ArrayList;

+import java.util.List;

+

+import com.att.research.xacml.api.AttributeValue;

+import com.att.research.xacml.api.DataType;

+import com.att.research.xacml.api.Identifier;

+import com.att.research.xacml.api.Status;

+import com.att.research.xacml.api.XACML;

+import com.att.research.xacml.std.StdAttributeValue;

+import com.att.research.xacml.std.StdStatus;

+import com.att.research.xacml.std.StdStatusCode;

+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;

+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;

+

+/**

+ * FunctionDefinitionNumberTypeConversion extends {@link FunctionDefinitionHomogeneousSimple} to

+ * implement the XACML predicates foc converting <code>Double</code> to <code>Integer</code> and vice versa.

+ * 

+ * In the first implementation of XACML we had separate files for each XACML Function.

+ * This release combines multiple Functions in fewer files to minimize code duplication.

+ * This file supports the following XACML codes:

+ * 		double-to-integer

+ * 		integer-to-double

+ * 

+ * @author glenngriffin

+ * @version $Revision: 1.1 $

+ * 

+ * @param <O> the java class for the data type of the function Output

+ * @param <I> the java class for the data type of the function Input argument

+ */

+public class FunctionDefinitionNumberTypeConversion<O extends Number, I extends Number> extends FunctionDefinitionHomogeneousSimple<O, I> {

+

+

+	public FunctionDefinitionNumberTypeConversion(Identifier idIn, DataType<O> outputType, DataType<I> argType) {

+		super(idIn, outputType, argType, 1);

+		

+	}

+

+	@Override

+	public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) {

+		List<I> convertedArguments	= new ArrayList<I>();

+		Status status				= this.validateArguments(arguments, convertedArguments);

+

+		/*

+		 * If the function arguments are not correct, just return an error status immediately

+		 */

+		if (!status.getStatusCode().equals(StdStatusCode.STATUS_CODE_OK)) {

+			return ExpressionResult.newError(getFunctionStatus(status));

+		}

+		

+		/*

+		 * Numeric operations cannot be operated on generically in java, so we have to check the types and handle separately.

+		 * Whichever type the argument is, convert it to the other

+		 */

+		ExpressionResult expressionResult;

+		try {

+			if (convertedArguments.get(0).getClass() == BigInteger.class) {

+				AttributeValue<Double>	doubleResult	= new StdAttributeValue<Double>(XACML.ID_DATATYPE_DOUBLE,

+						new Double(  ((BigInteger)convertedArguments.get(0)).toString()  ) );

+				expressionResult = ExpressionResult.newSingle(doubleResult);

+			} else {

+				AttributeValue<BigInteger>	integerResult	= new StdAttributeValue<BigInteger>(XACML.ID_DATATYPE_INTEGER, BigInteger.valueOf(((Double)convertedArguments.get(0)).intValue()) );

+				expressionResult = ExpressionResult.newSingle(integerResult);

+			}

+		} catch (Exception e) {

+			String message = e.getMessage();

+			if (e.getCause() != null) {

+				message = e.getCause().getMessage();

+			}

+			return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " " + message));

+		}

+		

+		return expressionResult;

+	}

+

+}

diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRFC822NameMatch.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRFC822NameMatch.java
new file mode 100755
index 0000000..5015204
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRFC822NameMatch.java
@@ -0,0 +1,141 @@
+/*

+ *                        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.std.functions;

+

+import java.util.List;

+

+import com.att.research.xacml.api.Identifier;

+import com.att.research.xacml.api.Status;

+import com.att.research.xacml.std.StdStatus;

+import com.att.research.xacml.std.StdStatusCode;

+import com.att.research.xacml.std.datatypes.DataTypes;

+import com.att.research.xacml.std.datatypes.RFC822Name;

+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;

+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;

+

+/**

+ * FunctionDefinitionRFC822NameMatch extends {@link com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionHomogeneousSimple} to

+ * implement the XACML RFC822Name match predicate as functions taking one <code>String</code> and one <code>RFC822Name</code> arguments

+ * and returning a single <code>Boolean</code> value.

+ * 

+ * In the first implementation of XACML we had separate files for each XACML Function.

+ * This release combines multiple Functions in fewer files to minimize code duplication.

+ * This file supports the following XACML codes:

+ * 		rfc822Name-match

+ * 

+ * @author glenngriffin

+ * @version $Revision: 1.1 $

+ * 

+ */

+public class FunctionDefinitionRFC822NameMatch extends FunctionDefinitionBase<Boolean, RFC822Name> {

+	

+

+	/**

+	 * Constructor

+	 * 

+	 * @param idIn

+	 * @param dataTypeArgsIn

+	 * @param op

+	 */

+	public FunctionDefinitionRFC822NameMatch(Identifier idIn) {

+		super(idIn, DataTypes.DT_BOOLEAN, DataTypes.DT_RFC822NAME, false);

+	}

+

+

+	@Override

+	public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) {

+		

+		if (arguments == null || arguments.size() != 2) {

+			return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, getShortFunctionId() + " Expected 2 arguments, got " + 

+					((arguments == null) ? "null" : arguments.size()) ));

+		}

+

+		// get the string to search for

+		ConvertedArgument<String> stringArgument = new ConvertedArgument<String>(arguments.get(0), DataTypes.DT_STRING, false);

+		if ( ! stringArgument.isOk()) {

+			Status decoratedStatus = new StdStatus(stringArgument.getStatus().getStatusCode(), stringArgument.getStatus().getStatusMessage() + " at arg index 0"  );

+			return ExpressionResult.newError(getFunctionStatus(decoratedStatus));

+		}

+		String searchTermString = stringArgument.getValue();

+		

+		// get the RFC822Name to match with

+		ConvertedArgument<RFC822Name> rfc822Argument = new ConvertedArgument<RFC822Name>(arguments.get(1), DataTypes.DT_RFC822NAME, false);

+		if ( ! rfc822Argument.isOk()) {

+			Status decoratedStatus = new StdStatus(rfc822Argument.getStatus().getStatusCode(), rfc822Argument.getStatus().getStatusMessage() + " at arg index 1"  );

+			return ExpressionResult.newError(getFunctionStatus(decoratedStatus));

+		}

+		

+		RFC822Name rfc822Name = rfc822Argument.getValue();

+		

+		

+		/*

+		 * Now perform the match.

+		 */

+		

+		/*

+		 * According to the spec the string must be one of the following 3 things:

+		 * 	- a name with an '@' in it = a full name that must exactly match the whole RFC name (domain part is ignore case)

+		 * 	- a domain name (without an '@' and not starting with a '.') = must match whole RFC domain name (ignore case)

+		 * 	- a partial domain name (without an '@') starting with a '.' = the last part of the RFC domain name (ignore case)

+		 */

+

+		String[] searchTerms = searchTermString.split("@");

+		

+		if (searchTerms.length > 2) {

+			return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, getShortFunctionId() + 

+					" String contained more than 1 '@' in '" + searchTermString + "'" ));

+		}

+

+		if (searchTerms.length == 2 || searchTermString.endsWith("@")) {

+			// this is an exact match

+			if (searchTerms[0] == null || searchTerms[0].length() == 0) {

+				return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, getShortFunctionId() + 

+						" String missing local part in '" + searchTermString + "'" ));

+			}

+			if (searchTerms.length < 2 || searchTerms[1] == null || searchTerms[1].length() == 0) {

+				return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, getShortFunctionId() + 

+						" String missing domain part in '" + searchTermString + "'" ));

+			}

+			

+			// args are ok, so check both against RFC name

+			if (searchTerms[0].equals(rfc822Name.getLocalName()) && 

+					searchTerms[1].toLowerCase().equals(rfc822Name.getCanonicalDomainName())) {

+				return ER_TRUE;

+			} else {

+				return ER_FALSE;

+			}			

+		}

+		

+		// we have only a domain name, which may be whole or partial

+		

+		// make it match the canonical version

+		searchTerms[0] = searchTerms[0].toLowerCase();

+		

+		if (searchTerms[0].charAt(0) == '.') {

+			// name is partial - must match the end

+			if (rfc822Name.getCanonicalDomainName().endsWith(searchTerms[0])) {

+				return ER_TRUE;

+			} else {

+				return ER_FALSE;

+			}

+		} else {

+			// name is whole domain - must match exactly

+			if (rfc822Name.getCanonicalDomainName().equals(searchTerms[0])) {

+				return ER_TRUE;

+			} else {

+				return ER_FALSE;

+			}

+		}

+

+	}

+

+}

diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRegexpMatch.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRegexpMatch.java
new file mode 100755
index 0000000..ad442ae
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRegexpMatch.java
@@ -0,0 +1,117 @@
+/*

+ *                        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.std.functions;

+

+

+import java.util.List;

+

+import com.att.research.xacml.api.DataType;

+import com.att.research.xacml.api.DataTypeException;

+import com.att.research.xacml.api.Identifier;

+import com.att.research.xacml.std.StdStatus;

+import com.att.research.xacml.std.StdStatusCode;

+import com.att.research.xacml.std.datatypes.DataTypes;

+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;

+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;

+

+/**

+ * FunctionDefinitionRegexMatch implements {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition} to

+ * implement the XACML 'type'-regex-match predicates as functions taking two arguments, the first of <code>String</code>,

+ * representing a regular expression, and the second of the type for that specific predicate,

+ * and returning a <code>Boolean</code> for whether the regular expression matches the string representation of the second argument.

+ * 

+ * In the first implementation of XACML we had separate files for each XACML Function.

+ * This release combines multiple Functions in fewer files to minimize code duplication.

+ * This file supports the following XACML codes:

+ * 		string-regexp-match

+ * 		anyURI-regexp-match

+ * 		x500Name-regexp-match

+ * 		rfc822Name-regexp-match (in sub-class {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition.FunctionDefinitionRegexpMatchRFC822} )

+ * 		ipAddress-regexp-match

+ * 		dnsName-regexp-match

+ * 

+ * 

+ * @author glenngriffin

+ * @version $Revision: 1.1 $

+ * 

+ * @param <I> the java class for the data type of the function Input arguments

+ */

+public class FunctionDefinitionRegexpMatch<I> extends FunctionDefinitionBase<Boolean, I> {

+

+	

+	/**

+	 * Constructor - need dataTypeArgs input because of java Generic type-erasure during compilation.

+	 * 

+	 * @param idIn

+	 * @param dataTypeArgsIn

+	 */

+	public FunctionDefinitionRegexpMatch(Identifier idIn, DataType<I> dataTypeArgsIn) {

+		super(idIn, DataTypes.DT_BOOLEAN, dataTypeArgsIn, false);

+	}

+

+

+	@Override

+	public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) {

+

+		if (arguments == null || arguments.size() != 2) {

+			return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Expected 2 arguments, got " + 

+					((arguments == null) ? "null" : arguments.size()) ));

+		}

+		

+		// get the regular expression

+		FunctionArgument regexpArgument = arguments.get(0);

+

+		ConvertedArgument<String> convertedArgument = new ConvertedArgument<String>(regexpArgument, DataTypes.DT_STRING, false);

+		if ( ! convertedArgument.isOk()) {

+			return ExpressionResult.newError(getFunctionStatus(convertedArgument.getStatus()));

+		}

+		

+		// String regexpValue = (String)regexpArgument.getValue().getValue();

+		String regexpValue	= convertedArgument.getValue();

+

+		

+		// now get the element to match

+		FunctionArgument elementArgument = arguments.get(1);

+		

+		ConvertedArgument<I> convertedElement = new ConvertedArgument<I>(elementArgument, this.getDataTypeArgs(), false);

+		if ( ! convertedElement.isOk()) {

+			return ExpressionResult.newError(getFunctionStatus(convertedElement.getStatus()));

+		}

+		

+		I elementValueObject = convertedElement.getValue();

+

+		String elementValueString;

+		try {

+			elementValueString = this.getDataTypeArgs().toStringValue(elementValueObject);

+		} catch (DataTypeException e) {

+			String message = e.getMessage();

+			if (e.getCause() != null) {

+				message = e.getCause().getMessage();

+			}

+			return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " " + message));

+		}

+		

+		// ConvertedArgument checks for null value, so do not need to do again here

+

+		if (elementValueString.matches(regexpValue)) {

+			return ER_TRUE;

+		} else {

+			return ER_FALSE;

+		}

+

+	}

+

+

+	

+	

+

+}

diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet.java
new file mode 100755
index 0000000..1595a47
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet.java
@@ -0,0 +1,230 @@
+/*

+ *                        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.std.functions;

+

+import java.util.ArrayList;

+import java.util.List;

+

+import com.att.research.xacml.api.AttributeValue;

+import com.att.research.xacml.api.DataType;

+import com.att.research.xacml.api.Identifier;

+import com.att.research.xacml.std.StdStatus;

+import com.att.research.xacml.std.StdStatusCode;

+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;

+import com.att.research.xacmlatt.pdp.policy.Bag;

+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;

+

+/**

+ * FunctionDefinitionSet implements {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition} to

+ * implement the XACML Set predicates as functions taking two arguments of <code>Bag</code> the same primitive type

+ * and returning either a <code>Boolean</code> or a <code>Bag</code> of the same primitive type.

+ * <P>

+ * The ipAddress, dnsName and xPathExpression do not have set functions defined for them in section 10.2.8 of the Release 3 XACML spec.

+ * 

+ * In the first implementation of XACML we had separate files for each XACML Function.

+ * This release combines multiple Functions in fewer files to minimize code duplication.

+ * This file supports the following XACML codes:

+ * 		string-bag

+ * 		boolean-bag

+ * 		integer-bag

+ * 		double-bag

+ * 		time-bag

+ * 		date-bag

+ * 		dateTime-bag

+ * 		anyURI-bag

+ * 		hexBinary-bag

+ * 		base64Binary-bag

+ * 		dayTimeDuration-bag (version 1 and3)

+ * 		yearMonthDuration-bag (version 1 and 3)

+ * 		x500Name-bag

+ * 		rfc822Name-bag

+ * 

+ * 

+ * @author glenngriffin

+ * @version $Revision: 1.1 $

+ * 

+ * @param <I> the java class for the data type of the function Input arguments

+ * @param <O> the java class for the data type of the function Output

+ */

+public class FunctionDefinitionSet<O,I> extends FunctionDefinitionBase<O, I> {

+

+	/**

+	 * List of comparison operations.

+	 * 

+	 * @author glenngriffin

+	 *

+	 */

+	public enum OPERATION {INTERSECTION, AT_LEAST_ONE_MEMBER_OF, UNION, SUBSET, SET_EQUALS };

+	

+	// the operation for this instance of the class

+	private OPERATION operation;

+	

+	

+	/**

+	 * Constructor - need dataType input because of java Generic type-erasure during compilation.

+	 * 

+	 * @param idIn

+	 * @param dataTypeArgsIn

+	 */

+	public FunctionDefinitionSet(Identifier idIn, DataType<O> dataTypeIn, DataType<I> dataTypeArgsIn, OPERATION opIn) {

+		super(idIn, dataTypeIn, dataTypeArgsIn, ((opIn == OPERATION.INTERSECTION || opIn == OPERATION.UNION) ? true : false) );

+		operation = opIn;

+	}

+

+

+	@Override

+	public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) {

+

+		if (arguments == null || arguments.size() != 2) {

+			return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Expected 2 arguments, got " + 

+					((arguments == null) ? "null" : arguments.size()) ));

+		}

+		

+		// get first bag

+		FunctionArgument bagArgument = arguments.get(0);

+		ConvertedArgument<Bag> convertedBagArgument = new ConvertedArgument<Bag>(bagArgument, null, true);

+

+		if ( ! convertedBagArgument.isOk()) {

+			return ExpressionResult.newError(getFunctionStatus(convertedBagArgument.getStatus()));

+		}

+	

+		Bag bag1 = convertedBagArgument.getBag();

+		List<AttributeValue<?>> list1 = (List<AttributeValue<?>>) bag1.getAttributeValueList();

+		

+		// get second bag

+		bagArgument = arguments.get(1);

+		convertedBagArgument = new ConvertedArgument<Bag>(bagArgument, null, true);

+

+		if ( ! convertedBagArgument.isOk()) {

+			return ExpressionResult.newError(getFunctionStatus(convertedBagArgument.getStatus()));

+		}

+	

+		Bag bag2 = convertedBagArgument.getBag();

+		List<AttributeValue<?>> list2 = (List<AttributeValue<?>>) bag2.getAttributeValueList();

+

+		// arguments are ready BUT they have NOT had duplicates removed

+		

+		ExpressionResult expressionResult = null;

+		

+		// some functions return a bag rather than boolean

+		Bag outBag;

+		List<AttributeValue<?>> outList;

+		

+		

+		switch (operation) {

+		case INTERSECTION:

+			outList = new ArrayList<AttributeValue<?>>();

+			

+			for (AttributeValue<?> element : list1) {

+				if (outList.contains(element)) {

+					continue;

+				}

+				if (list2.contains(element)) {

+					outList.add(element);

+				}

+			}

+			

+			// now have the intersection; put it in a bag

+			

+			outBag = new Bag();

+			

+			for (AttributeValue<?> element : outList) {

+					outBag.add(element);

+			}

+

+			expressionResult = ExpressionResult.newBag(outBag);

+			return expressionResult;

+			

+			

+		case AT_LEAST_ONE_MEMBER_OF:

+			// look for elements from the first list in the second.

+			// duplicates do not matter because if the element is not there it does not matter that we look for it again,

+			// and if it is there we stop the first time we see it.

+			// If the first bag is empty, this should fail because no element from the first set can be found in the second set 

+			// (because there IS no element in first set).

+			for (AttributeValue<?> element : list1) {

+				if (list2.contains(element)) {

+					return ER_TRUE;

+				}

+			}

+			// did not find any element from list 1 in list 2

+			return ER_FALSE;

+			

+		case UNION:

+			outList = new ArrayList<AttributeValue<?>>();

+			

+			for (AttributeValue<?> element : list1) {

+				if (outList.contains(element)) {

+					continue;

+				}

+				outList.add((AttributeValue<?>) element);

+			}

+			for (AttributeValue<?> element : list2) {

+				if (outList.contains(element)) {

+					continue;

+				}

+				outList.add((AttributeValue<?>) element);

+			}

+			

+			// now have the intersection; put it in a bag

+			

+			outBag = new Bag();

+			

+			for (AttributeValue<?> element : outList) {

+				outBag.add(element);

+			}

+

+			expressionResult = ExpressionResult.newBag(outBag);

+			return expressionResult;

+			

+			

+		case SUBSET:

+			// all elements from list 1 must exist in list 2.

+			// duplicates do not matter because if an element is not found the first time we stop immediately,

+			// and if it is found the first time it will also be found for the duplicate.

+			// If the first set is empty we return TRUE because all elements (i.e. none) in the first set are in the second.

+			for (AttributeValue<?> element : list1) {

+				if ( ! list2.contains(element)) {

+					return ER_FALSE;

+				}

+			}

+			// all elements in list1 were found

+			return ER_TRUE;

+			

+			

+		case SET_EQUALS:

+			// we cannot do a direct one-to-one compare because the lists may contain duplicates.  Also they may not be ordered the same.

+			// So we ask:

+			//		are all elements in list 1 in list 2 (ignoring duplicates)

+			//		are all elements in list 2 in list 1 (ignoring duplicates)

+			for (AttributeValue<?> element : list1) {

+				if ( ! list2.contains(element)) {

+					return ER_FALSE;

+				}

+			}

+			for (AttributeValue<?> element : list2) {

+				if ( ! list1.contains(element)) {

+					return ER_FALSE;

+				}

+			}

+			// all elements in each are part of the other

+			return ER_TRUE;

+		}

+	

+		// all cases should have been covered by above - should never get here

+		return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Could not evaluate Set function " + operation));

+

+	}

+

+

+

+}

diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringConversion.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringConversion.java
new file mode 100755
index 0000000..bde0bbe
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringConversion.java
@@ -0,0 +1,117 @@
+/*

+ *                        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.std.functions;

+

+import java.util.ArrayList;

+import java.util.List;

+

+import com.att.research.xacml.api.DataType;

+import com.att.research.xacml.api.Identifier;

+import com.att.research.xacml.api.Status;

+import com.att.research.xacml.std.StdAttributeValue;

+import com.att.research.xacml.std.StdStatus;

+import com.att.research.xacml.std.StdStatusCode;

+import com.att.research.xacml.std.datatypes.DataTypes;

+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;

+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;

+

+/**

+ * FunctionDefinitionNumberTypeConversion extends {@link com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionHomogeneousSimple} to

+ * implement the XACML predicates for converting <code>String</code> to <code>DataType<?></code> and vice versa.

+ * 

+ * In the first implementation of XACML we had separate files for each XACML Function.

+ * This release combines multiple Functions in fewer files to minimize code duplication.

+ * This file supports the following XACML codes:

+ * 		boolean-from-string

+ * 		string-from-boolean

+ * 		integer-from-string

+ * 		string-from-integer

+ * 		double-from-string

+ * 		string-from-double

+ * 		time-from-string

+ * 		string-from-time

+ * 		date-from-string

+ * 		string-from-date

+ * 		dateTime-from-string

+ * 		string-from-dateTime

+ * 		anyURI-from-string

+ * 		string-from-anyURI

+ * 		dayTimeDuration-from-string

+ * 		string-from-dayTimeDuration

+ * 		yearMonthDuration-from-string

+ * 		string-from-yearMonthDuration

+ * 		x500Name-from-string

+ * 		string-from-x500Name

+ * 		rfc822Name-from-string

+ * 		string-from-rfc822Name

+ * 		ipAddress-from-string

+ * 		string-from-ipAddress

+ * 		dnsName-from-string

+ * 		string-from-dnsName

+ * 

+ * @author glenngriffin

+ * @version $Revision: 1.1 $

+ * 

+ * @param <O> the java class for the data type of the function Output

+ * @param <I> the java class for the data type of the function Input argument

+ */

+public class FunctionDefinitionStringConversion<O,I> extends FunctionDefinitionHomogeneousSimple<O, I> {

+

+	public FunctionDefinitionStringConversion(Identifier idIn, DataType<O> outputType, DataType<I> argType) {

+		super(idIn, outputType, argType, 1);

+	}

+

+	@Override

+	public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) {

+		List<I> convertedArguments	= new ArrayList<I>();

+		Status status				= this.validateArguments(arguments, convertedArguments);

+

+		/*

+		 * If the function arguments are not correct, just return an error status immediately

+		 */

+		if (!status.getStatusCode().equals(StdStatusCode.STATUS_CODE_OK)) {

+			return ExpressionResult.newError(getFunctionStatus(status));

+		}

+		

+		/*

+		 * Do different conversion depending on which way we are going (to/from String)

+		 */

+		if (this.getDataTypeId().equals(DataTypes.DT_STRING.getId())) {

+			// converting TO String

+			try {

+				String output = this.getDataTypeArgs().toStringValue(convertedArguments.get(0));

+				return ExpressionResult.newSingle(new StdAttributeValue<String>(this.getDataTypeId(), output));

+			} catch (Exception e) {

+				String message = e.getMessage();

+				if (e.getCause() != null) {

+					message = e.getCause().getMessage();

+				}

+				// untested - not clear how this could happen

+				return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +  " " + message));

+			}

+		} else {

+			// converting FROM String to object of DataType

+			try {

+				O output = this.getDataType().convert(convertedArguments.get(0));

+				return ExpressionResult.newSingle(new StdAttributeValue<O>(this.getDataTypeId(), output));

+			} catch (Exception e) {

+				String message = e.getMessage();

+				if (e.getCause() != null) {

+					message = e.getCause().getMessage();

+				}

+				return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, this.getShortFunctionId() + " " + message ));

+			}

+		}

+		

+	}

+

+}

diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringEqualIgnoreCase.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringEqualIgnoreCase.java
new file mode 100755
index 0000000..b8aae7d
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringEqualIgnoreCase.java
@@ -0,0 +1,55 @@
+/*

+ *                        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.std.functions;

+

+import com.att.research.xacml.api.Identifier;

+import com.att.research.xacml.std.datatypes.DataTypes;

+

+/**

+ * FunctionDefinitionStringEqualIgnoreCase extends {@link FunctionDefinitionEquality} for

+ * <code>String</code> arguments by testing for equality without regard to case.

+ * 

+ * The specification actually says that the strings are first converted to lower case using the string-normalize-to-lower-case function.

+ * This code ASSUMES that

+ * <UL>

+ * <LI>	the normalize function just calls the Java toLowerCase() function, and

+ * <LI>	the Java VM is consistent in that equalsIgnoreCase provides the same result as calling toLowerCase on each string and doing a compare.

+ * </UL>

+ * 

+ * In the first implementation of XACML we had separate files for each XACML Function.

+ * This release combines multiple Functions in fewer files to minimize code duplication.

+ * This file supports the following XACML codes:

+ * 		string-equal-ignore-case

+ * 

+ * 

+ * @author car

+ * @version $Revision: 1.2 $

+ */

+public class FunctionDefinitionStringEqualIgnoreCase extends FunctionDefinitionEquality<String> {

+

+	/**

+	 * ASSUMES that equalsIgnoreCase provides the same result as calling string-normalize-to-lower-case on both strings and then comparing.

+	 */

+	@Override

+	protected boolean isEqual(String s1, String s2) {

+		return s1.equalsIgnoreCase(s2);

+	}

+	

+	/**

+	 * Creates a new <code>FunctionDefinitionStringEqualIgnoreCase</code> with the given <code>Identifier</code>.

+	 * 

+	 * @param idIn the <code>Identifier</code> for the new <code>FunctionDefinitionStringEqualIgnoreCase</code>

+	 */

+	public FunctionDefinitionStringEqualIgnoreCase(Identifier idIn) {

+		super(idIn, DataTypes.DT_STRING);

+	}

+

+}

diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions.java
new file mode 100755
index 0000000..bc5515d
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions.java
@@ -0,0 +1,256 @@
+/*

+ *                        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.std.functions;

+

+

+import java.math.BigInteger;

+import java.util.List;

+

+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.Identifier;

+import com.att.research.xacml.api.XACML;

+import com.att.research.xacml.std.StdAttributeValue;

+import com.att.research.xacml.std.StdStatus;

+import com.att.research.xacml.std.StdStatusCode;

+import com.att.research.xacml.std.datatypes.DataTypes;

+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;

+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;

+

+/**

+ * FunctionDefinitionStringFunctions implements {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition} to

+ * implement the XACML String Functions predicates except for the conversions between <code>String</code> and <code>DataType</code>

+ * which are contained in <code>FunctionDefinitionStringConversion</code>.

+ * The functions in this file do not have a lot in common except that the return data type is known and the input argument types are

+ * either known or of the generic type.

+ * 

+ * In the first implementation of XACML we had separate files for each XACML Function.

+ * This release combines multiple Functions in fewer files to minimize code duplication.

+ * This file supports the following XACML codes:

+ * 		string-concatenate

+ * 		string-starts-with

+ * 		anyURI-starts-with

+ * 		string-ends-with

+ * 		anyURI-ends-with

+ * 		string-contains

+ * 		anyURI-contains

+ * 		string-substring

+ * 		anyURI-substring

+ * 

+ * 

+ * @author glenngriffin

+ * @version $Revision: 1.1 $

+ * 

+ * @param <I> the java class for the data type of the function Input arguments

+ * @param <O> the java class for the data type of the function Output -

+ * 		needed because different functions within this class have different output types

+ */

+public class FunctionDefinitionStringFunctions<O, I> extends FunctionDefinitionBase<O, I> {

+

+	/**

+	 * List of String operations.

+	 * 

+	 * @author glenngriffin

+	 *

+	 */

+	public enum OPERATION {CONCATENATE, STARTS_WITH, ENDS_WITH, CONTAINS, SUBSTRING };

+	

+	// operation to be used in this instance of the StringFunctions class

+	private final OPERATION operation;

+	

+	

+	/**

+	 * Constructor - need dataTypeArgs input because of java Generic type-erasure during compilation.

+	 * 

+	 * @param idIn

+	 * @param dataTypeArgsIn

+	 */

+	public FunctionDefinitionStringFunctions(Identifier idIn, DataType<O> dataTypeIn, DataType<I> dataTypeArgsIn, OPERATION op) {

+		super(idIn, dataTypeIn, dataTypeArgsIn, false);

+		this.operation = op;

+	}

+

+

+	@SuppressWarnings("incomplete-switch")

+	@Override

+	public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) {

+

+		if (arguments == null || 

+				(operation == OPERATION.CONCATENATE && arguments.size() < 2) ||

+				(operation == OPERATION.SUBSTRING && arguments.size() != 3) ||

+				(operation != OPERATION.SUBSTRING && operation != OPERATION.CONCATENATE && arguments.size() != 2) ) {

+			return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Expected " +

+				((operation == OPERATION.SUBSTRING) ? 3 : (operation == OPERATION.CONCATENATE ? "2 or more " : 2)) + " arguments, got " + 

+					((arguments == null) ? "null" : arguments.size()) ));

+		}

+		

+

+		

+		ExpressionResult expressionResult = null;

+		

+		String firstArgumentAsString = null;

+		String secondArgumentAsString = null;

+		

+		Integer secondArgumentAsInteger = null;

+		Integer thirdArgumentAsInteger = null;

+		

+		// most of the functions take 2  args, but SUBSTRING takes 3 AND concatenate takes 2 or more

+		if (operation == OPERATION.CONCATENATE) {

+			StringBuilder builder = new StringBuilder();

+			for (int i = 0; i < arguments.size(); i++) {

+				FunctionArgument functionArgument = arguments.get(i);

+				ConvertedArgument<I> convertedArgument = new ConvertedArgument<I>(functionArgument, this.getDataTypeArgs(), false);

+				if ( ! convertedArgument.isOk()) {

+					return ExpressionResult.newError(getFunctionStatus(convertedArgument.getStatus()));

+				}

+				try {

+					String argumentAsString = this.getDataTypeArgs().toStringValue( convertedArgument.getValue());

+					builder.append(argumentAsString);

+				} catch (DataTypeException e) {

+					String message = e.getMessage();

+					if (e.getCause() != null) {

+						message = e.getCause().getMessage();

+					}

+					return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " " + message ));

+				}

+			}

+			AttributeValue<String> stringResult =  new StdAttributeValue<String>(XACML.ID_DATATYPE_STRING, 

+					builder.toString() );

+			expressionResult = ExpressionResult.newSingle(stringResult);

+			return expressionResult;

+			

+		} else if (operation == OPERATION.SUBSTRING) {

+			// first arg is of generic type

+			FunctionArgument functionArgument = arguments.get(0);

+			ConvertedArgument<I> convertedArgument0 = new ConvertedArgument<I>(functionArgument, this.getDataTypeArgs(), false);

+			if ( ! convertedArgument0.isOk()) {

+				return ExpressionResult.newError(getFunctionStatus(convertedArgument0.getStatus()));

+			}

+			try {

+				firstArgumentAsString = this.getDataTypeArgs().toStringValue( convertedArgument0.getValue());

+			} catch (DataTypeException e) {

+				String message = e.getMessage();

+				if (e.getCause() != null) {

+					message = e.getCause().getMessage();

+				}

+				return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " " + message ));

+			}

+			

+			functionArgument = arguments.get(1);

+			ConvertedArgument<BigInteger> convertedArgumentInt = new ConvertedArgument<BigInteger>(functionArgument, DataTypes.DT_INTEGER, false);

+			if ( ! convertedArgumentInt.isOk()) {

+				return ExpressionResult.newError(getFunctionStatus(convertedArgumentInt.getStatus()));

+			}

+			secondArgumentAsInteger = convertedArgumentInt.getValue().intValue();

+			if (secondArgumentAsInteger < 0 || secondArgumentAsInteger > firstArgumentAsString.length()) {

+				return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " " +

+						"Start point '" + secondArgumentAsInteger + "' out of range 0-" + firstArgumentAsString.length() +

+						" for string='" + firstArgumentAsString + "'"));

+			}

+			

+			

+			functionArgument = arguments.get(2);

+			convertedArgumentInt = new ConvertedArgument<BigInteger>(functionArgument, DataTypes.DT_INTEGER, false);

+			if ( ! convertedArgumentInt.isOk()) {

+				return ExpressionResult.newError(getFunctionStatus(convertedArgumentInt.getStatus()));

+			}

+			thirdArgumentAsInteger = convertedArgumentInt.getValue().intValue();

+			// special case: -1 means "to end of string"

+			if (thirdArgumentAsInteger < -1 || thirdArgumentAsInteger > firstArgumentAsString.length()) {

+				return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " " +

+						"End point '" + thirdArgumentAsInteger + "' out of range 0-" + firstArgumentAsString.length() +

+						" for string='" + firstArgumentAsString + "'"));

+			}

+			if (thirdArgumentAsInteger != -1 && thirdArgumentAsInteger < secondArgumentAsInteger) {

+				return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " " +

+						"End point '" + thirdArgumentAsInteger + "' less than start point '" + secondArgumentAsString + "'" +

+						" for string='" + firstArgumentAsString + "'"));

+			}

+			

+		} else {

+			// expect 2 args, one String and one of Generic type

+			FunctionArgument functionArgument = arguments.get(0);

+			ConvertedArgument<String> convertedArgument0 = new ConvertedArgument<String>(functionArgument, DataTypes.DT_STRING, false);

+			if ( ! convertedArgument0.isOk()) {

+				return ExpressionResult.newError(getFunctionStatus(convertedArgument0.getStatus()));

+			}

+			firstArgumentAsString = convertedArgument0.getValue();

+			

+			

+			functionArgument = arguments.get(1);

+			ConvertedArgument<I> convertedArgument1 = new ConvertedArgument<I>(functionArgument, this.getDataTypeArgs(), false);

+			if ( ! convertedArgument1.isOk()) {

+				return ExpressionResult.newError(getFunctionStatus(convertedArgument1.getStatus()));

+			}

+			try {

+				secondArgumentAsString = this.getDataTypeArgs().toStringValue( convertedArgument1.getValue());

+			} catch (DataTypeException e) {

+				String message = e.getMessage();

+				if (e.getCause() != null) {

+					message = e.getCause().getMessage();

+				}

+				return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " " + message +

+						" " + message ));

+			}

+		

+			

+		}

+		

+		// arguments are ready - do the operation

+		

+		switch (operation) {

+		case STARTS_WITH:

+			if (secondArgumentAsString.startsWith(firstArgumentAsString)) {

+				return ER_TRUE;

+			} else {

+				return ER_FALSE;

+			}

+			

+			

+		case ENDS_WITH:

+			if (secondArgumentAsString.endsWith(firstArgumentAsString)) {

+				return ER_TRUE;

+			} else {

+				return ER_FALSE;

+			}

+			

+		case CONTAINS:

+			if (secondArgumentAsString.contains(firstArgumentAsString)) {

+				return ER_TRUE;

+			} else {

+				return ER_FALSE;

+			}

+			

+		case SUBSTRING:

+			String substring = null;

+			if (thirdArgumentAsInteger == -1) {

+				// from start point to end of string

+				substring = firstArgumentAsString.substring(secondArgumentAsInteger);

+			} else {

+				substring = firstArgumentAsString.substring(secondArgumentAsInteger, thirdArgumentAsInteger);

+			}

+			AttributeValue<String> stringResult =  new StdAttributeValue<String>(XACML.ID_DATATYPE_STRING, substring);

+			expressionResult = ExpressionResult.newSingle(stringResult);

+			break;

+		}

+		

+		

+		return expressionResult;

+

+	}

+

+

+	

+	

+

+}

diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize.java
new file mode 100755
index 0000000..11d6359
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize.java
@@ -0,0 +1,108 @@
+/*

+ *                        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.std.functions;

+

+import java.util.ArrayList;

+import java.util.List;

+

+import com.att.research.xacml.api.AttributeValue;

+import com.att.research.xacml.api.Identifier;

+import com.att.research.xacml.api.Status;

+import com.att.research.xacml.api.XACML;

+import com.att.research.xacml.std.StdAttributeValue;

+import com.att.research.xacml.std.StdStatusCode;

+import com.att.research.xacml.std.datatypes.DataTypeString;

+import com.att.research.xacml.std.datatypes.DataTypes;

+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;

+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;

+

+/**

+ * FunctionDefinitionStringNormalize extends {@link com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionHomogeneousSimple} to

+ * implement the XACML String normalization predicates as functions taking one <code>String</code> arg and returning a single value of the same type.

+ * 

+ * In the first implementation of XACML we had separate files for each XACML Function.

+ * This release combines multiple Functions in fewer files to minimize code duplication.

+ * This file supports the following XACML codes:

+ * 		string-normalize-space

+ * 		string-normalize-to-lower-case

+ * 

+ * @author glenngriffin

+ * @version $Revision: 1.1 $

+ * 

+ */

+public class FunctionDefinitionStringNormalize extends FunctionDefinitionHomogeneousSimple<String, String> {

+	

+	/**

+	 * List of string normalization operations.

+	 * 

+	 * @author glenngriffin

+	 *

+	 */

+	public enum OPERATION {SPACE, LOWER_CASE };

+	

+	// operation to be used in this instance of the Arightmetic class

+	private final OPERATION operation;

+	

+	

+	// result variables used by all functions

+	AttributeValue<String>	result;

+

+

+	/**

+	 * Constructor

+	 * 

+	 * @param idIn

+	 * @param dataTypeArgsIn

+	 * @param op

+	 */

+	public FunctionDefinitionStringNormalize(Identifier idIn,  OPERATION op) {

+		// for Arithmetic functions, the output type is the same as the input type (no mixing of Ints and Doubles!)

+		super(idIn, DataTypes.DT_STRING, DataTypeString.newInstance(), 1);

+		

+		// save the operation and data type to be used in this instance

+		operation = op;

+

+	}

+

+

+	@Override

+	public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) {

+		List<String> convertedArguments	= new ArrayList<String>();

+		Status status				= this.validateArguments(arguments, convertedArguments);

+		

+		/*

+		 * If the function arguments are not correct, just return an error status immediately

+		 */

+		if (!status.getStatusCode().equals(StdStatusCode.STATUS_CODE_OK)) {

+			return ExpressionResult.newError(getFunctionStatus(status));

+		}

+		

+		/*

+		 * Now perform the requested operation.

+		 */

+		ExpressionResult expressionResult = null;

+		

+		switch (operation) {

+		case SPACE:

+			result	= new StdAttributeValue<String>(XACML.ID_DATATYPE_STRING, convertedArguments.get(0).trim() );

+			break;

+		case LOWER_CASE:

+			result	= new StdAttributeValue<String>(XACML.ID_DATATYPE_STRING, convertedArguments.get(0).toLowerCase() );

+			break;

+		}

+		

+		expressionResult = ExpressionResult.newSingle(result);

+

+		return expressionResult;

+	}

+

+}

diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionTimeInRange.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionTimeInRange.java
new file mode 100755
index 0000000..bf7ba8b
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionTimeInRange.java
@@ -0,0 +1,96 @@
+/*

+ *                        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.std.functions;

+

+import java.util.ArrayList;

+import java.util.List;

+

+import com.att.research.xacml.api.DataType;

+import com.att.research.xacml.api.Identifier;

+import com.att.research.xacml.api.Status;

+import com.att.research.xacml.std.StdStatus;

+import com.att.research.xacml.std.StdStatusCode;

+import com.att.research.xacml.std.datatypes.DataTypes;

+import com.att.research.xacml.std.datatypes.ISO8601Time;

+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;

+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;

+

+/**

+ * FunctionDefinitionTimeInRange implements {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition} to

+ * implement the XACML time-in-range predicates as a function taking three arguments of type <code>Time</code>

+ * and returning a <code>Boolean</code>.

+ * 

+ * In the first implementation of XACML we had separate files for each XACML Function.

+ * This release combines multiple Functions in fewer files to minimize code duplication.

+ * This file supports the following XACML codes:

+ * 		time-in-range

+ * 

+ * 

+ * @author glenngriffin

+ * @version $Revision: 1.1 $

+ * 

+ * @param <I> the java class for the data type of the function Input arguments.  

+ */

+public class FunctionDefinitionTimeInRange<I> extends FunctionDefinitionHomogeneousSimple<Boolean, I> {

+

+

+	

+	

+	/**

+	 * Constructor - need dataType input because of java Generic type-erasure during compilation.

+	 * 

+	 * @param idIn

+	 * @param dataTypeArgsIn

+	 */

+	public FunctionDefinitionTimeInRange(Identifier idIn, DataType<I> dataTypeArgsIn) {

+		super(idIn, DataTypes.DT_BOOLEAN, dataTypeArgsIn, 3);

+	}

+

+

+	@Override

+	public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) {

+

+		List<I> convertedArguments	= new ArrayList<I>();

+		Status status				= this.validateArguments(arguments, convertedArguments);

+		

+		/*

+		 * If the function arguments are not correct, just return an error status immediately

+		 */

+		if (!status.getStatusCode().equals(StdStatusCode.STATUS_CODE_OK)) {

+			return ExpressionResult.newError(getFunctionStatus(status));

+		}

+		

+		int compareResultLow;

+		int compareResultHigh;

+		try {

+

+			compareResultLow = ((ISO8601Time) convertedArguments.get(1)).compareTo((ISO8601Time)convertedArguments.get(0));

+			compareResultHigh = ((ISO8601Time)convertedArguments.get(2)).compareTo((ISO8601Time)convertedArguments.get(0));

+		} catch (Exception e) {

+			String message = e.getMessage();

+			if (e.getCause() != null) {

+				message = e.getCause().getMessage();

+			}

+			return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " " + message));

+		}

+

+		// is arg 0 within the inclusive range of the other two?

+		if (compareResultLow <=0 && compareResultHigh >= 0) {

+			return ER_TRUE;

+		} else {

+			return ER_FALSE;

+		}

+	}

+

+

+

+}

diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionURIStringConcatenate.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionURIStringConcatenate.java
new file mode 100755
index 0000000..cf9a375
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionURIStringConcatenate.java
@@ -0,0 +1,114 @@
+/*

+ *                        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.std.functions;

+

+import java.net.URI;

+import java.util.List;

+

+import com.att.research.xacml.api.DataTypeException;

+import com.att.research.xacml.api.Identifier;

+import com.att.research.xacml.api.Status;

+import com.att.research.xacml.api.XACML;

+import com.att.research.xacml.std.StdAttributeValue;

+import com.att.research.xacml.std.StdStatus;

+import com.att.research.xacml.std.StdStatusCode;

+import com.att.research.xacml.std.datatypes.DataTypes;

+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;

+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;

+

+/**

+ * FunctionDefinitionURIStringConcatenate extends {@link FunctionDefinitionHomogeneousSimple} to

+ * implement the XACML uri-string-concatenate predicate as a function taking one <code>URI</code> and one or more <code>String</code> arguments

+ * and returning a single <code>URI</code> value.

+ * 

+ * THIS FUNCTION IS DEPRECATED IN 3.0 BUT NOT REMOVED.

+ * To provide backward compatibility for previously built XACML policies we include it in our R3 version.

+ * 

+ * In the first implementation of XACML we had separate files for each XACML Function.

+ * This release combines multiple Functions in fewer files to minimize code duplication.

+ * This file supports the following XACML codes:

+ * 		uri-string-concatenate

+ * 

+ * @author glenngriffin

+ * @version $Revision: 1.1 $

+ * 

+ */

+@Deprecated

+public class FunctionDefinitionURIStringConcatenate extends FunctionDefinitionBase<URI, URI> {

+	

+

+	/**

+	 * Constructor

+	 * 

+	 * @param idIn

+	 * @param dataTypeArgsIn

+	 * @param op

+	 */

+	public FunctionDefinitionURIStringConcatenate(Identifier idIn) {

+		super(idIn, DataTypes.DT_ANYURI, DataTypes.DT_ANYURI, false);

+	}

+

+

+	@Override

+	public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) {

+		

+		if (arguments == null || arguments.size() < 2) {

+			return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, getShortFunctionId() + " Expected 2 or more arguments, got " + 

+					((arguments == null) ? "null" : arguments.size()) ));

+		}

+

+		// get the string to search for

+		ConvertedArgument<URI> uriArgument = new ConvertedArgument<URI>(arguments.get(0), DataTypes.DT_ANYURI, false);

+		if ( ! uriArgument.isOk()) {

+			Status decoratedStatus = new StdStatus(uriArgument.getStatus().getStatusCode(), uriArgument.getStatus().getStatusMessage() + " at arg index 0"  );

+			return ExpressionResult.newError(getFunctionStatus(decoratedStatus));

+		}

+		String uriString = uriArgument.getValue().toString();

+		

+		// remaining arguments are strings

+		String[] stringValues = new String[arguments.size() - 1];

+		

+		for (int i = 1; i < arguments.size(); i++) {

+

+			ConvertedArgument<String> stringArgument = new ConvertedArgument<String>(arguments.get(i), DataTypes.DT_STRING, false);

+			if ( ! stringArgument.isOk()) {

+				Status decoratedStatus = new StdStatus(stringArgument.getStatus().getStatusCode(), stringArgument.getStatus().getStatusMessage() + " at arg index " + i );

+				return ExpressionResult.newError(getFunctionStatus(decoratedStatus));

+			}

+			

+			stringValues[i-1] = stringArgument.getValue();

+		

+		}

+		

+		

+		// add each of the strings onto the URI

+		for (int i = 0; i < stringValues.length; i++) {

+			uriString += stringValues[i];

+		}

+		

+		URI resultURI = null;

+		try {

+			resultURI = DataTypes.DT_ANYURI.convert(uriString);

+		} catch (DataTypeException e) {

+			String message = e.getMessage();

+			if (e.getCause() != null) {

+				message = e.getCause().getMessage();

+			}

+			return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, getShortFunctionId() + 

+					" Final string '" + uriString + "' not URI, " + message));

+		}

+		

+		return ExpressionResult.newSingle(new StdAttributeValue<URI>(XACML.ID_DATATYPE_ANYURI, resultURI));

+

+	}

+

+}

diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionX500NameMatch.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionX500NameMatch.java
new file mode 100755
index 0000000..7f5069c
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionX500NameMatch.java
@@ -0,0 +1,98 @@
+/*

+ *                        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.std.functions;

+

+import java.util.ArrayList;

+import java.util.List;

+

+import javax.security.auth.x500.X500Principal;

+

+import com.att.research.xacml.api.Identifier;

+import com.att.research.xacml.api.Status;

+import com.att.research.xacml.std.StdStatusCode;

+import com.att.research.xacml.std.datatypes.DataTypes;

+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;

+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;

+

+/**

+ * FunctionDefinitionX500NameMatch extends {@link com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionHomogeneousSimple} to

+ * implement the XACML X500Name match predicate as functions taking two <code>X500Name</code> arguments and returning a single <code>Boolean</code> value.

+ * 

+ * In the first implementation of XACML we had separate files for each XACML Function.

+ * This release combines multiple Functions in fewer files to minimize code duplication.

+ * This file supports the following XACML codes:

+ * 		x500Name-match

+ * 

+ * @author glenngriffin

+ * @version $Revision: 1.1 $

+ * 

+ */

+public class FunctionDefinitionX500NameMatch extends FunctionDefinitionHomogeneousSimple<Boolean, X500Principal> {

+	

+

+	/**

+	 * Constructor

+	 * 

+	 * @param idIn

+	 * @param dataTypeArgsIn

+	 * @param op

+	 */

+	public FunctionDefinitionX500NameMatch(Identifier idIn) {

+		super(idIn, DataTypes.DT_BOOLEAN, DataTypes.DT_X500NAME, 2);

+	}

+

+

+	@Override

+	public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) {

+		List<X500Principal> convertedArguments	= new ArrayList<X500Principal>();

+		Status status				= this.validateArguments(arguments, convertedArguments);

+		

+		/*

+		 * If the function arguments are not correct, just return an error status immediately

+		 */

+		if (!status.getStatusCode().equals(StdStatusCode.STATUS_CODE_OK)) {

+			return ExpressionResult.newError(getFunctionStatus(status));

+		}

+		

+		/*

+		 * Now perform the match.

+		 */

+		

+		/*

+		 * The spec writer's comments at:

+		 * https://lists.oasis-open.org/archives/xacml/200906/msg00019.html

+		 * say that the first sequence must exactly match the END of the second sequence.

+		 */

+		

+		String[] searchFor = convertedArguments.get(0).getName().split(",");

+		String[] searchIn = convertedArguments.get(1).getName().split(",");

+

+		// if first is bigger than 2nd there is no way we can match

+		if (searchFor.length > searchIn.length) {

+			return ER_FALSE;

+		}

+		

+		// start from back-end of both lists - everything should match up to the length of the input

+		for (int i = 0; i < searchFor.length; i++) {

+			String searchForTerm = searchFor[searchFor.length - i - 1];

+			String searchInTerm = searchIn[searchIn.length - i - 1];

+			if (searchForTerm == null || searchInTerm == null || 

+					! searchForTerm.trim().equals(searchInTerm.trim())) {

+				return ER_FALSE;

+			}

+		}

+

+

+		return ER_TRUE;

+	}

+

+}

diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath.java
new file mode 100755
index 0000000..22ed22c
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath.java
@@ -0,0 +1,249 @@
+/*

+ *                        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.std.functions;

+

+import java.math.BigInteger;

+import java.util.ArrayList;

+import java.util.Iterator;

+import java.util.List;

+

+import javax.xml.xpath.XPathExpression;

+

+import org.w3c.dom.NodeList;

+

+import com.att.research.xacml.api.AttributeValue;

+import com.att.research.xacml.api.DataType;

+import com.att.research.xacml.api.Identifier;

+import com.att.research.xacml.api.RequestAttributes;

+import com.att.research.xacml.api.Status;

+import com.att.research.xacml.api.XACML;

+import com.att.research.xacml.std.StdAttributeValue;

+import com.att.research.xacml.std.StdStatus;

+import com.att.research.xacml.std.StdStatusCode;

+import com.att.research.xacml.std.datatypes.DataTypes;

+import com.att.research.xacml.std.datatypes.XPathExpressionWrapper;

+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;

+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;

+

+

+/**

+ * FunctionDefinitionXPath extends {@link com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionHomogeneousSimple} to

+ * implement the XACML XPath predicates as functions taking one or two <code>XPathExpression</code> arguments and returning 

+ * either an <code>Integer</code> or a <code>Boolean</code>.

+ * 

+ * XACML version 1.0 and 2.0 used <code>String</code> data type as input.

+ * We do NOT support those functions because of ambiguity in the meaning of those Strings.

+ * The root of the XPath changed from the Request level in 2.0 to the Content level in 3.0.

+ * Also the 2.0 Requests contain only one Content, located in the resources category, while 3.0 allows Requests to contain Content in multiple categories.

+ * 

+ * In the first implementation of XACML we had separate files for each XACML Function.

+ * This release combines multiple Functions in fewer files to minimize code duplication.

+ * This file supports the following XACML codes:

+ * 		xpath-node-count

+ * 		xpath-node-equals

+ * 		xpath-node-match

+ * 

+ * @author glenngriffin

+ * @version $Revision: 1.1 $

+ * 

+ * @param <O> the java class for the data type of the function Output

+

+ * 

+ */

+public class FunctionDefinitionXPath<O> extends FunctionDefinitionHomogeneousSimple<O, XPathExpressionWrapper> {

+	

+	/**

+	 * List of string normalization operations.

+	 * 

+	 * @author glenngriffin

+	 *

+	 */

+	public enum OPERATION {COUNT, EQUAL, MATCH };

+	

+	// operation to be used in this instance of the Arightmetic class

+	private final OPERATION operation;

+	

+	

+	// result variables used by all functions

+	AttributeValue<String>	result;

+

+

+	/**

+	 * Constructor

+	 * 

+	 * @param idIn

+	 * @param dataTypeArgsIn

+	 * @param op

+	 */

+	public FunctionDefinitionXPath(Identifier idIn, DataType<O> dataTypeIn, OPERATION op) {

+		super(idIn, dataTypeIn, DataTypes.DT_XPATHEXPRESSION, ( (op == OPERATION.COUNT) ? 1 : 2 ) );

+		// save the operation and data type to be used in this instance

+		operation = op;

+

+	}

+

+	@Override

+	public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) {

+

+		List<NodeList> nodeListList = new ArrayList<NodeList>();

+

+		List<XPathExpressionWrapper> convertedArguments	= new ArrayList<XPathExpressionWrapper>();

+		Status status				= this.validateArguments(arguments, convertedArguments);

+

+		/*

+		 * If the function arguments are not correct, just return an error status immediately

+		 */

+		if (!status.getStatusCode().equals(StdStatusCode.STATUS_CODE_OK)) {

+			return ExpressionResult.newError(getFunctionStatus(status));

+		}

+		

+		// check the evaluationContext and Request for null

+		if (evaluationContext == null) {

+			return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +

+					" Got null EvaluationContext"));

+		}

+		if (evaluationContext.getRequest() == null) {

+			return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +

+					" Got null Request in EvaluationContext"));

+		}

+		

+		

+		// each argument is an XPath that needs to be evaluated against the Content part of some Category (specified in the argument)

+		for (int i = 0; i < arguments.size(); i++) {

+			FunctionArgument functionArgument = arguments.get(i);

+			if (functionArgument.isBag()) {

+				return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Got bag at index " + i));

+			}

+			AttributeValue<?> attributeValueFunctionArgument	= functionArgument.getValue();

+			if (attributeValueFunctionArgument == null) {

+				return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Got null value at index " + i));

+			}

+			Identifier xpathCategory = attributeValueFunctionArgument.getXPathCategory();

+			if (xpathCategory == null) {

+				return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, this.getShortFunctionId() +

+						" Got null Category at index " + i));

+			}

+			

+			Iterator<RequestAttributes> it = evaluationContext.getRequest().getRequestAttributes(xpathCategory);

+			if (it == null) {

+				return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, this.getShortFunctionId() +

+						" Got null Iterator at index " + i));

+			}

+			

+			NodeList nodeList = null;

+

+			while (it.hasNext()) {

+				if (nodeList != null) {

+					// the request has more than one Content entry for the same Category - error

+					return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, this.getShortFunctionId() +

+							" More than one Content section for id '" + xpathCategory + "'" ));

+				}

+				RequestAttributes requestAttributes = it.next();

+				

+				// if there is no Content section then we return either 0 or FALSE

+				if (requestAttributes.getContentRoot() == null) {

+					if (operation == OPERATION.COUNT){

+						return ExpressionResult.newSingle(new StdAttributeValue<BigInteger>(XACML.ID_DATATYPE_INTEGER, new BigInteger("0") ));

+					} else {

+						return ER_FALSE;

+					}

+				}

+

+				try {

+					XPathExpression xPathExpression = convertedArguments.get(i).getXpathExpressionWrapped();

+					nodeList    = requestAttributes.getContentNodeListByXpathExpression(xPathExpression);

+				} catch (Exception e) {

+					return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, this.getShortFunctionId() +

+							" XPath produces null result at '" + convertedArguments.get(i).getPath() + "' at index " + i ));

+				}

+

+

+			}

+			

+			if (nodeList == null) {

+				return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +

+						" XPathExpression returned null at index " + i));

+			}

+			

+			// add this nodeList to the list of lists

+			nodeListList.add(nodeList);

+		}

+		

+		

+		/*

+		 * Now perform the requested operation.

+		 */

+		ExpressionResult expressionResult = null;

+		

+		switch (operation) {

+		case COUNT:

+			Integer listLength = new Integer(nodeListList.get(0).getLength());

+			expressionResult = ExpressionResult.newSingle(new StdAttributeValue<BigInteger>(XACML.ID_DATATYPE_INTEGER,

+					new BigInteger(listLength.toString()) ));

+			return expressionResult;

+			

+			

+		case EQUAL:

+			// true if any node in first list equals any node in second set.

+			// The spec says: "Two nodes are considered equal if they have the same identity."

+			// we use the isSameNode method in Node to determine that.

+			for (int index0 = 0; index0 < nodeListList.get(0).getLength(); index0++) {

+				for (int index1 = 0; index1 < nodeListList.get(1).getLength(); index1++)  {

+					if (nodeListList.get(0).item(index0).isSameNode(nodeListList.get(1).item(index1))) {

+						return ER_TRUE;

+					}

+				}

+			}

+			// none from the first list found in the second

+			return ER_FALSE;

+			

+			

+		case MATCH:

+			// this is looking to see if any of the nodes in the second set are children of (or equal to) the nodes in the first set

+			// Call recursive check for that.

+			expressionResult = nodeListMatch(nodeListList.get(0), nodeListList.get(1));

+			return expressionResult;

+		}

+		

+		expressionResult = ExpressionResult.newSingle(result);

+

+		return expressionResult;

+	}

+	

+	/**

+	 * Recursive method checking to see if anything in list 2 equals anything in list 1 OR list 1's child nodes

+	 * @param list1

+	 * @param list2

+	 * @return

+	 */

+	private ExpressionResult nodeListMatch(NodeList list1, NodeList list2) {

+		// look for match with current contents of list 1

+		for (int index1 = 0; index1 < list1.getLength(); index1++) {

+			for (int index2 = 0; index2 < list2.getLength(); index2++)  {

+				if (list1.item(index1).isSameNode(list2.item(index2))) {

+					return ER_TRUE;

+				}

+			}

+		}

+		// look for match with children of list 1

+		for (int index1 = 0; index1 < list1.getLength(); index1++) {

+			if (nodeListMatch(list1.item(index1).getChildNodes(), list2) == ER_TRUE) {

+				return ER_TRUE;

+			}

+			// this one had no children that matched, so check the next element in list1

+		}

+		

+		// no match anywhere

+		return ER_FALSE;

+	}

+

+}

diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/package-info.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/package-info.java
new file mode 100755
index 0000000..2122dd9
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/package-info.java
@@ -0,0 +1,20 @@
+/*
+ *                        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.std.functions;
+
+/**
+ * com.att.research.xacmlatt.pdp.policy.expressions contains class definitions that represent specific XACML function
+ * implementations for target and condition evaluation and variable definitions.
+ *  
+ * @author car
+ * @version $Revision: 1.1 $
+ */
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/package-info.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/package-info.java
new file mode 100755
index 0000000..fe69353
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/package-info.java
@@ -0,0 +1,20 @@
+/*
+ *                        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.std;
+
+/**
+ * com.att.research.xacmlatt.pdp.std contains classes that provide reference implementations of various extensible components
+ * in the PDP implementation.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/util/ATTPDPProperties.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/util/ATTPDPProperties.java
new file mode 100755
index 0000000..2b932ba
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/util/ATTPDPProperties.java
@@ -0,0 +1,29 @@
+/*
+ *                        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.util;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.std.IdentifierImpl;
+import com.att.research.xacml.util.XACMLProperties;
+
+public class ATTPDPProperties extends XACMLProperties {
+	public static final String PROP_EVALUATIONCONTEXTFACTORY	= "xacml.att.evaluationContextFactory";
+	public static final String PROP_COMBININGALGORITHMFACTORY	= "xacml.att.combiningAlgorithmFactory";
+	public static final String PROP_FUNCTIONDEFINITIONFACTORY	= "xacml.att.functionDefinitionFactory";
+	public static final String PROP_POLICYFINDERFACTORY			= "xacml.att.policyFinderFactory";
+	public static final String PROP_POLICYFINDERFACTORY_COMBINEROOTPOLICIES = "xacml.att.policyFinderFactory.combineRootPolicies";
+	
+	public static final Identifier ID_POLICY_COMBINEDPERMITOVERRIDES = new IdentifierImpl("urn:com:att:xacml:3.0:policy-combining-algorithm:combined-permit-overrides");
+	
+	protected ATTPDPProperties() {
+	}
+
+}
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/ATTPDPEngine$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/ATTPDPEngine$1.class
new file mode 100644
index 0000000..61fbdd6
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/ATTPDPEngine$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/ATTPDPEngine.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/ATTPDPEngine.class
new file mode 100644
index 0000000..56e339d
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/ATTPDPEngine.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/ATTPDPEngineFactory.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/ATTPDPEngineFactory.class
new file mode 100644
index 0000000..647988e
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/ATTPDPEngineFactory.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/Evaluatable.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/Evaluatable.class
new file mode 100644
index 0000000..435ab9c
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/Evaluatable.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/EvaluationContext.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/EvaluationContext.class
new file mode 100644
index 0000000..25802a3
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/EvaluationContext.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/EvaluationContextException.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/EvaluationContextException.class
new file mode 100644
index 0000000..ab03f3e
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/EvaluationContextException.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/EvaluationContextFactory.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/EvaluationContextFactory.class
new file mode 100644
index 0000000..8e508d2
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/EvaluationContextFactory.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/EvaluationException.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/EvaluationException.class
new file mode 100644
index 0000000..2f424aa
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/EvaluationException.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/EvaluationResult.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/EvaluationResult.class
new file mode 100644
index 0000000..c73f36d
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/EvaluationResult.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/MatchResult$MatchCode.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/MatchResult$MatchCode.class
new file mode 100644
index 0000000..8306ba6
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/MatchResult$MatchCode.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/MatchResult.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/MatchResult.class
new file mode 100644
index 0000000..9ec087c
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/MatchResult.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/Matchable.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/Matchable.class
new file mode 100644
index 0000000..d24eb17
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/Matchable.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AdviceExpression.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AdviceExpression.class
new file mode 100644
index 0000000..ccb1e74
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AdviceExpression.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AllOf$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AllOf$1.class
new file mode 100644
index 0000000..cdf3dc3
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AllOf$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AllOf.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AllOf.class
new file mode 100644
index 0000000..58d2ced
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AllOf.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AnyOf$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AnyOf$1.class
new file mode 100644
index 0000000..101274e
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AnyOf$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AnyOf.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AnyOf.class
new file mode 100644
index 0000000..4942daf
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AnyOf.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AttributeAssignmentExpression.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AttributeAssignmentExpression.class
new file mode 100644
index 0000000..ef8fe7e
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AttributeAssignmentExpression.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AttributeAssignmentResult.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AttributeAssignmentResult.class
new file mode 100644
index 0000000..3fb1237
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AttributeAssignmentResult.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Bag.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Bag.class
new file mode 100644
index 0000000..2bc997b
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Bag.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/CombinerParameter.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/CombinerParameter.class
new file mode 100644
index 0000000..ee80fd2
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/CombinerParameter.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/CombiningAlgorithm.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/CombiningAlgorithm.class
new file mode 100644
index 0000000..5157663
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/CombiningAlgorithm.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/CombiningAlgorithmFactory.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/CombiningAlgorithmFactory.class
new file mode 100644
index 0000000..ad60823
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/CombiningAlgorithmFactory.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/CombiningElement.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/CombiningElement.class
new file mode 100644
index 0000000..225cf1d
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/CombiningElement.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Condition.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Condition.class
new file mode 100644
index 0000000..2a74ea6
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Condition.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Expression.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Expression.class
new file mode 100644
index 0000000..0e0aea0
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Expression.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultBag.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultBag.class
new file mode 100644
index 0000000..051dbef
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultBag.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultEmptyBag.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultEmptyBag.class
new file mode 100644
index 0000000..30c0841
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultEmptyBag.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultError.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultError.class
new file mode 100644
index 0000000..9c507c0
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultError.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultSingle.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultSingle.class
new file mode 100644
index 0000000..dddaa10
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultSingle.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResult.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResult.class
new file mode 100644
index 0000000..1c431ba
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResult.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResultBoolean.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResultBoolean.class
new file mode 100644
index 0000000..c337941
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResultBoolean.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionArgument.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionArgument.class
new file mode 100644
index 0000000..d5cb5ed
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionArgument.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionArgumentAttributeValue.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionArgumentAttributeValue.class
new file mode 100644
index 0000000..12ef034
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionArgumentAttributeValue.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionArgumentBag.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionArgumentBag.class
new file mode 100644
index 0000000..1abf718
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionArgumentBag.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionArgumentExpression.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionArgumentExpression.class
new file mode 100644
index 0000000..8ba8dd4
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionArgumentExpression.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionDefinition.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionDefinition.class
new file mode 100644
index 0000000..6367b3f
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionDefinition.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionDefinitionFactory.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionDefinitionFactory.class
new file mode 100644
index 0000000..5c2d6f3
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionDefinitionFactory.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Match$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Match$1.class
new file mode 100644
index 0000000..3bd5b5e
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Match$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Match.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Match.class
new file mode 100644
index 0000000..1a7355c
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Match.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ObligationExpression.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ObligationExpression.class
new file mode 100644
index 0000000..285943b
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ObligationExpression.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Policy$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Policy$1.class
new file mode 100644
index 0000000..d45b7cb
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Policy$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Policy.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Policy.class
new file mode 100644
index 0000000..1ff09f5
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Policy.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyComponent.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyComponent.class
new file mode 100644
index 0000000..2a245a5
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyComponent.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyDef.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyDef.class
new file mode 100644
index 0000000..121d0a8
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyDef.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyDefaults.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyDefaults.class
new file mode 100644
index 0000000..9bc54d9
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyDefaults.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyFinder.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyFinder.class
new file mode 100644
index 0000000..5fdb442
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyFinder.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyFinderFactory.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyFinderFactory.class
new file mode 100644
index 0000000..90a1f82
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyFinderFactory.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyFinderResult.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyFinderResult.class
new file mode 100644
index 0000000..2e17129
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyFinderResult.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyIdReference.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyIdReference.class
new file mode 100644
index 0000000..98f42a1
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyIdReference.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyIdReferenceBase.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyIdReferenceBase.class
new file mode 100644
index 0000000..3883a6e
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyIdReferenceBase.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyIssuer.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyIssuer.class
new file mode 100644
index 0000000..f631054
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyIssuer.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicySet$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicySet$1.class
new file mode 100644
index 0000000..7cda7d4
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicySet$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicySet.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicySet.class
new file mode 100644
index 0000000..af76185
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicySet.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicySetChild.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicySetChild.class
new file mode 100644
index 0000000..643f5eb
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicySetChild.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicySetIdReference.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicySetIdReference.class
new file mode 100644
index 0000000..d834fa5
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicySetIdReference.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Rule$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Rule$1.class
new file mode 100644
index 0000000..171ecbe
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Rule$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Rule.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Rule.class
new file mode 100644
index 0000000..1dc60b6
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Rule.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/RuleEffect.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/RuleEffect.class
new file mode 100644
index 0000000..911cbcb
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/RuleEffect.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Target.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Target.class
new file mode 100644
index 0000000..9ab657b
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Target.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameter.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameter.class
new file mode 100644
index 0000000..5b2ca51
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameter.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameterMap.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameterMap.class
new file mode 100644
index 0000000..96c3cab
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameterMap.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/VariableDefinition.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/VariableDefinition.class
new file mode 100644
index 0000000..b955b0e
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/VariableDefinition.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/VariableMap.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/VariableMap.class
new file mode 100644
index 0000000..2516589
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/VariableMap.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAdviceExpression.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAdviceExpression.class
new file mode 100644
index 0000000..503201c
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAdviceExpression.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAllOf.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAllOf.class
new file mode 100644
index 0000000..8be4cfc
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAllOf.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAnyOf.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAnyOf.class
new file mode 100644
index 0000000..3ac5422
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAnyOf.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMApply.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMApply.class
new file mode 100644
index 0000000..14583a3
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMApply.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeAssignmentExpression.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeAssignmentExpression.class
new file mode 100644
index 0000000..a0b2a05
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeAssignmentExpression.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeDesignator.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeDesignator.class
new file mode 100644
index 0000000..7062e1f
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeDesignator.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeSelector.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeSelector.class
new file mode 100644
index 0000000..c2709e6
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeSelector.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMCombinerParameter.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMCombinerParameter.class
new file mode 100644
index 0000000..e823a43
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMCombinerParameter.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMDocumentRepair.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMDocumentRepair.class
new file mode 100644
index 0000000..c3ce1c7
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMDocumentRepair.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMExpression.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMExpression.class
new file mode 100644
index 0000000..b006026
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMExpression.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMMatch.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMMatch.class
new file mode 100644
index 0000000..c4ef9c6
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMMatch.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMObligationExpression.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMObligationExpression.class
new file mode 100644
index 0000000..d02bb03
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMObligationExpression.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicy.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicy.class
new file mode 100644
index 0000000..585ad00
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicy.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyCombinerParameter.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyCombinerParameter.class
new file mode 100644
index 0000000..9abb139
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyCombinerParameter.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDef.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDef.class
new file mode 100644
index 0000000..8213a5b
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDef.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDefaults.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDefaults.class
new file mode 100644
index 0000000..5f2a5b2
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDefaults.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIdReference.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIdReference.class
new file mode 100644
index 0000000..251b708
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIdReference.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIssuer.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIssuer.class
new file mode 100644
index 0000000..5052858
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIssuer.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyRepair.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyRepair.class
new file mode 100644
index 0000000..c6d8849
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyRepair.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySet.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySet.class
new file mode 100644
index 0000000..170541f
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySet.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetCombinerParameter.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetCombinerParameter.class
new file mode 100644
index 0000000..5975519
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetCombinerParameter.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetIdReference.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetIdReference.class
new file mode 100644
index 0000000..4307789
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetIdReference.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMRule.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMRule.class
new file mode 100644
index 0000000..f2faac6
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMRule.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMRuleCombinerParameters.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMRuleCombinerParameters.class
new file mode 100644
index 0000000..c05e205
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMRuleCombinerParameters.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMTarget.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMTarget.class
new file mode 100644
index 0000000..c60901c
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMTarget.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMVariableDefinition.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMVariableDefinition.class
new file mode 100644
index 0000000..94411a2
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMVariableDefinition.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/Apply.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/Apply.class
new file mode 100644
index 0000000..99f5f44
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/Apply.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/AttributeDesignator.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/AttributeDesignator.class
new file mode 100644
index 0000000..9fcf24a
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/AttributeDesignator.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/AttributeRetrievalBase.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/AttributeRetrievalBase.class
new file mode 100644
index 0000000..36bddc1
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/AttributeRetrievalBase.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/AttributeSelector.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/AttributeSelector.class
new file mode 100644
index 0000000..e4ea696
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/AttributeSelector.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/AttributeValueExpression.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/AttributeValueExpression.class
new file mode 100644
index 0000000..c0864ba
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/AttributeValueExpression.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/Function.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/Function.class
new file mode 100644
index 0000000..dd76634
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/Function.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/VariableReference.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/VariableReference.class
new file mode 100644
index 0000000..d62b7c1
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/VariableReference.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithmFactory.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithmFactory.class
new file mode 100644
index 0000000..cc23407
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithmFactory.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithms.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithms.class
new file mode 100644
index 0000000..2ef4d9a
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithms.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdEvaluationContext.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdEvaluationContext.class
new file mode 100644
index 0000000..a6a4b4b
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdEvaluationContext.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdEvaluationContextFactory.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdEvaluationContextFactory.class
new file mode 100644
index 0000000..0a065dd
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdEvaluationContextFactory.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdFunctionDefinitionFactory.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdFunctionDefinitionFactory.class
new file mode 100644
index 0000000..b704f03
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdFunctionDefinitionFactory.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdFunctions.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdFunctions.class
new file mode 100644
index 0000000..2dcba35
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdFunctions.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdPolicyFinder$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdPolicyFinder$1.class
new file mode 100644
index 0000000..1671f08
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdPolicyFinder$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdPolicyFinder$StdPolicyFinderException.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdPolicyFinder$StdPolicyFinderException.class
new file mode 100644
index 0000000..ffed3c4
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdPolicyFinder$StdPolicyFinderException.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdPolicyFinder.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdPolicyFinder.class
new file mode 100644
index 0000000..d409eba
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdPolicyFinder.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdPolicyFinderFactory.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdPolicyFinderFactory.class
new file mode 100644
index 0000000..ea56f8e
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdPolicyFinderFactory.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdPolicyFinderResult.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdPolicyFinderResult.class
new file mode 100644
index 0000000..6f57c16
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdPolicyFinderResult.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdProperties.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdProperties.class
new file mode 100644
index 0000000..8bef17e
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdProperties.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/CombinedPermitOverrides$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/CombinedPermitOverrides$1.class
new file mode 100644
index 0000000..019485f
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/CombinedPermitOverrides$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/CombinedPermitOverrides.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/CombinedPermitOverrides.class
new file mode 100644
index 0000000..20bd937
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/CombinedPermitOverrides.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/CombiningAlgorithmBase.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/CombiningAlgorithmBase.class
new file mode 100644
index 0000000..42057bf
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/CombiningAlgorithmBase.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/DenyOverrides$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/DenyOverrides$1.class
new file mode 100644
index 0000000..f5a6ae2
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/DenyOverrides$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/DenyOverrides.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/DenyOverrides.class
new file mode 100644
index 0000000..71f33e6
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/DenyOverrides.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/DenyUnlessPermit$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/DenyUnlessPermit$1.class
new file mode 100644
index 0000000..b5a3d4c
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/DenyUnlessPermit$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/DenyUnlessPermit.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/DenyUnlessPermit.class
new file mode 100644
index 0000000..d75367a
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/DenyUnlessPermit.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/FirstApplicable.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/FirstApplicable.class
new file mode 100644
index 0000000..72554f8
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/FirstApplicable.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesPolicy$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesPolicy$1.class
new file mode 100644
index 0000000..95e620a
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesPolicy$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesPolicy.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesPolicy.class
new file mode 100644
index 0000000..44ad7fd
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesPolicy.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesRule$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesRule$1.class
new file mode 100644
index 0000000..d29d9a7
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesRule$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesRule.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesRule.class
new file mode 100644
index 0000000..d965889
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesRule.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesPolicy$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesPolicy$1.class
new file mode 100644
index 0000000..f7bf40e
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesPolicy$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesPolicy.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesPolicy.class
new file mode 100644
index 0000000..7c13802
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesPolicy.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesRule$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesRule$1.class
new file mode 100644
index 0000000..62eeef6
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesRule$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesRule.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesRule.class
new file mode 100644
index 0000000..5135125
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesRule.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/OnlyOneApplicable$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/OnlyOneApplicable$1.class
new file mode 100644
index 0000000..9081b65
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/OnlyOneApplicable$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/OnlyOneApplicable.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/OnlyOneApplicable.class
new file mode 100644
index 0000000..a1656af
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/OnlyOneApplicable.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/PermitOverrides$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/PermitOverrides$1.class
new file mode 100644
index 0000000..61d0da8
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/PermitOverrides$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/PermitOverrides.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/PermitOverrides.class
new file mode 100644
index 0000000..d1c518a
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/PermitOverrides.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/PermitUnlessDeny$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/PermitUnlessDeny$1.class
new file mode 100644
index 0000000..b8f83e6
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/PermitUnlessDeny$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/PermitUnlessDeny.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/PermitUnlessDeny.class
new file mode 100644
index 0000000..ae8115c
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/PermitUnlessDeny.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/ConvertedArgument.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/ConvertedArgument.class
new file mode 100644
index 0000000..d28ce78
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/ConvertedArgument.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionAccessPermitted.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionAccessPermitted.class
new file mode 100644
index 0000000..0a104a2
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionAccessPermitted.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic$1.class
new file mode 100644
index 0000000..a0ac560
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic$OPERATION.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic$OPERATION.class
new file mode 100644
index 0000000..7fe2a1b
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic$OPERATION.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic.class
new file mode 100644
index 0000000..6cc59f0
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBag.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBag.class
new file mode 100644
index 0000000..7e69de0
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBag.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagIsIn.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagIsIn.class
new file mode 100644
index 0000000..da9dead
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagIsIn.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagOneAndOnly.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagOneAndOnly.class
new file mode 100644
index 0000000..34f3a5e
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagOneAndOnly.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagSize.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagSize.class
new file mode 100644
index 0000000..844df5e
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagSize.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBase.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBase.class
new file mode 100644
index 0000000..ff60811
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBase.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison$1.class
new file mode 100644
index 0000000..652a98f
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison$OPERATION.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison$OPERATION.class
new file mode 100644
index 0000000..5e9bf60
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison$OPERATION.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison.class
new file mode 100644
index 0000000..1045783
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic$1.class
new file mode 100644
index 0000000..1056721
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic$OPERATION.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic$OPERATION.class
new file mode 100644
index 0000000..85d79ca
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic$OPERATION.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic.class
new file mode 100644
index 0000000..ccd974a
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionEquality.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionEquality.class
new file mode 100644
index 0000000..4e3726f
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionEquality.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag$1.class
new file mode 100644
index 0000000..315fb99
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag$OPERATION.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag$OPERATION.class
new file mode 100644
index 0000000..ae2716d
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag$OPERATION.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag.class
new file mode 100644
index 0000000..a2a0169
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHomogeneousSimple.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHomogeneousSimple.class
new file mode 100644
index 0000000..1bcaa07
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHomogeneousSimple.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical$1.class
new file mode 100644
index 0000000..ef8f697
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical$OPERATION.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical$OPERATION.class
new file mode 100644
index 0000000..7d04b7b
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical$OPERATION.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical.class
new file mode 100644
index 0000000..92e5e67
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionNumberTypeConversion.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionNumberTypeConversion.class
new file mode 100644
index 0000000..c204a33
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionNumberTypeConversion.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRFC822NameMatch.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRFC822NameMatch.class
new file mode 100644
index 0000000..612f3c3
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRFC822NameMatch.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRegexpMatch.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRegexpMatch.class
new file mode 100644
index 0000000..7ddfc87
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRegexpMatch.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet$1.class
new file mode 100644
index 0000000..2e56349
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet$OPERATION.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet$OPERATION.class
new file mode 100644
index 0000000..ddc1cb0
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet$OPERATION.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet.class
new file mode 100644
index 0000000..2b522e8
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringConversion.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringConversion.class
new file mode 100644
index 0000000..93eae8f
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringConversion.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringEqualIgnoreCase.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringEqualIgnoreCase.class
new file mode 100644
index 0000000..9cf81f1
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringEqualIgnoreCase.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions$1.class
new file mode 100644
index 0000000..b3d96fa
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions$OPERATION.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions$OPERATION.class
new file mode 100644
index 0000000..305cd59
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions$OPERATION.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions.class
new file mode 100644
index 0000000..714bf36
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize$1.class
new file mode 100644
index 0000000..23e2571
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize$OPERATION.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize$OPERATION.class
new file mode 100644
index 0000000..592b19e
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize$OPERATION.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize.class
new file mode 100644
index 0000000..4a8b7b1
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionTimeInRange.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionTimeInRange.class
new file mode 100644
index 0000000..5f6a4e9
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionTimeInRange.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionURIStringConcatenate.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionURIStringConcatenate.class
new file mode 100644
index 0000000..b80bd20
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionURIStringConcatenate.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionX500NameMatch.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionX500NameMatch.class
new file mode 100644
index 0000000..e0eb6cb
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionX500NameMatch.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath$1.class
new file mode 100644
index 0000000..b539667
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath$OPERATION.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath$OPERATION.class
new file mode 100644
index 0000000..b8b971f
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath$OPERATION.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath.class
new file mode 100644
index 0000000..0f93467
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/util/ATTPDPProperties.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/util/ATTPDPProperties.class
new file mode 100644
index 0000000..3ef30e5
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/util/ATTPDPProperties.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/maven-archiver/pom.properties b/openaz-xacml-pdp/target/maven-archiver/pom.properties
new file mode 100644
index 0000000..7e994fb
--- /dev/null
+++ b/openaz-xacml-pdp/target/maven-archiver/pom.properties
@@ -0,0 +1,5 @@
+#Generated by Maven
+#Tue Apr 07 07:42:36 EDT 2015
+version=0.0.1-SNAPSHOT
+groupId=org.openliberty.openaz
+artifactId=openaz-xacml-pdp
diff --git a/openaz-xacml-pdp/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/openaz-xacml-pdp/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
new file mode 100644
index 0000000..d6cacb9
--- /dev/null
+++ b/openaz-xacml-pdp/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
@@ -0,0 +1,176 @@
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionX500NameMatch.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize$OPERATION.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMRule.class
+com/att/research/xacmlatt/pdp/policy/FunctionDefinition.class
+com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesRule.class
+com/att/research/xacmlatt/pdp/std/combiners/PermitUnlessDeny$1.class
+com/att/research/xacmlatt/pdp/policy/AdviceExpression.class
+com/att/research/xacmlatt/pdp/std/StdPolicyFinderResult.class
+com/att/research/xacmlatt/pdp/std/combiners/DenyUnlessPermit.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMMatch.class
+com/att/research/xacmlatt/pdp/policy/CombiningAlgorithmFactory.class
+com/att/research/xacmlatt/pdp/policy/CombiningElement.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBase.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic$1.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions$1.class
+com/att/research/xacmlatt/pdp/policy/PolicyFinderResult.class
+com/att/research/xacmlatt/pdp/std/StdPolicyFinderFactory.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMDocumentRepair.class
+com/att/research/xacmlatt/pdp/policy/Match.class
+com/att/research/xacmlatt/pdp/policy/RuleEffect.class
+com/att/research/xacmlatt/pdp/std/combiners/CombiningAlgorithmBase.class
+com/att/research/xacmlatt/pdp/policy/CombiningAlgorithm.class
+com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesRule$1.class
+com/att/research/xacmlatt/pdp/policy/AttributeAssignmentExpression.class
+com/att/research/xacmlatt/pdp/std/StdEvaluationContextFactory.class
+com/att/research/xacmlatt/pdp/policy/expressions/Apply.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath$OPERATION.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyRepair.class
+com/att/research/xacmlatt/pdp/ATTPDPEngine.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize$1.class
+com/att/research/xacmlatt/pdp/std/combiners/DenyOverrides$1.class
+com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesRule$1.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison$1.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath$1.class
+com/att/research/xacmlatt/pdp/policy/AllOf.class
+com/att/research/xacmlatt/pdp/std/functions/ConvertedArgument.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet$OPERATION.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeSelector.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeAssignmentExpression.class
+com/att/research/xacmlatt/pdp/std/combiners/OnlyOneApplicable.class
+com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesPolicy.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHomogeneousSimple.class
+com/att/research/xacmlatt/pdp/policy/FunctionDefinitionFactory.class
+com/att/research/xacmlatt/pdp/policy/FunctionArgument.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionAccessPermitted.class
+com/att/research/xacmlatt/pdp/eval/EvaluationResult.class
+com/att/research/xacmlatt/pdp/std/StdProperties.class
+com/att/research/xacmlatt/pdp/policy/Target.class
+com/att/research/xacmlatt/pdp/policy/Bag.class
+com/att/research/xacmlatt/pdp/policy/AnyOf.class
+com/att/research/xacmlatt/pdp/policy/PolicyIdReference.class
+com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultBag.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMPolicy.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMCombinerParameter.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison.class
+com/att/research/xacmlatt/pdp/eval/Evaluatable.class
+com/att/research/xacmlatt/pdp/policy/FunctionArgumentExpression.class
+com/att/research/xacmlatt/pdp/policy/Expression.class
+com/att/research/xacmlatt/pdp/policy/ExpressionResult.class
+com/att/research/xacmlatt/pdp/eval/EvaluationException.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetIdReference.class
+com/att/research/xacmlatt/pdp/policy/expressions/AttributeSelector.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRFC822NameMatch.class
+com/att/research/xacmlatt/pdp/policy/ExpressionResultBoolean.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDefaults.class
+com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesPolicy$1.class
+com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameter.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDef.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagOneAndOnly.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag.class
+com/att/research/xacmlatt/pdp/std/combiners/PermitUnlessDeny.class
+com/att/research/xacmlatt/pdp/ATTPDPEngineFactory.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetCombinerParameter.class
+com/att/research/xacmlatt/pdp/policy/PolicySetChild.class
+com/att/research/xacmlatt/pdp/std/StdPolicyFinder.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMExpression.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIdReference.class
+com/att/research/xacmlatt/pdp/eval/MatchResult.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag$1.class
+com/att/research/xacmlatt/pdp/policy/Match$1.class
+com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultError.class
+com/att/research/xacmlatt/pdp/std/combiners/PermitOverrides.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionNumberTypeConversion.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic.class
+com/att/research/xacmlatt/pdp/policy/PolicySet$1.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIssuer.class
+com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesPolicy$1.class
+com/att/research/xacmlatt/pdp/eval/MatchResult$MatchCode.class
+com/att/research/xacmlatt/pdp/policy/PolicySet.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionURIStringConcatenate.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical$1.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBag.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison$OPERATION.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionEquality.class
+com/att/research/xacmlatt/pdp/std/combiners/FirstApplicable.class
+com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultSingle.class
+com/att/research/xacmlatt/pdp/std/StdFunctionDefinitionFactory.class
+com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithms.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyCombinerParameter.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMVariableDefinition.class
+com/att/research/xacmlatt/pdp/eval/EvaluationContextFactory.class
+com/att/research/xacmlatt/pdp/policy/PolicyDef.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMRuleCombinerParameters.class
+com/att/research/xacmlatt/pdp/policy/VariableDefinition.class
+com/att/research/xacmlatt/pdp/policy/PolicyFinderFactory.class
+com/att/research/xacmlatt/pdp/policy/Policy$1.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMAnyOf.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet$1.class
+com/att/research/xacmlatt/pdp/std/StdPolicyFinder$1.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeDesignator.class
+com/att/research/xacmlatt/pdp/policy/expressions/AttributeRetrievalBase.class
+com/att/research/xacmlatt/pdp/std/StdPolicyFinder$StdPolicyFinderException.class
+com/att/research/xacmlatt/pdp/eval/Matchable.class
+com/att/research/xacmlatt/pdp/policy/expressions/AttributeDesignator.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMApply.class
+com/att/research/xacmlatt/pdp/eval/EvaluationContext.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagIsIn.class
+com/att/research/xacmlatt/pdp/std/combiners/CombinedPermitOverrides$1.class
+com/att/research/xacmlatt/pdp/policy/PolicyFinder.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMTarget.class
+com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithmFactory.class
+com/att/research/xacmlatt/pdp/std/StdFunctions.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMObligationExpression.class
+com/att/research/xacmlatt/pdp/policy/PolicyComponent.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRegexpMatch.class
+com/att/research/xacmlatt/pdp/policy/Condition.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic$OPERATION.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionTimeInRange.class
+com/att/research/xacmlatt/pdp/std/combiners/DenyOverrides.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet.class
+com/att/research/xacmlatt/pdp/policy/PolicyIssuer.class
+com/att/research/xacmlatt/pdp/std/combiners/CombinedPermitOverrides.class
+com/att/research/xacmlatt/pdp/std/combiners/DenyUnlessPermit$1.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical.class
+com/att/research/xacmlatt/pdp/std/combiners/OnlyOneApplicable$1.class
+com/att/research/xacmlatt/pdp/policy/AnyOf$1.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize.class
+com/att/research/xacmlatt/pdp/policy/PolicySetIdReference.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic$1.class
+com/att/research/xacmlatt/pdp/policy/FunctionArgumentBag.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringConversion.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagSize.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic$OPERATION.class
+com/att/research/xacmlatt/pdp/policy/expressions/Function.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMAllOf.class
+com/att/research/xacmlatt/pdp/policy/CombinerParameter.class
+com/att/research/xacmlatt/pdp/policy/VariableMap.class
+com/att/research/xacmlatt/pdp/policy/Rule$1.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMAdviceExpression.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag$OPERATION.class
+com/att/research/xacmlatt/pdp/policy/Rule.class
+com/att/research/xacmlatt/pdp/policy/Policy.class
+com/att/research/xacmlatt/pdp/std/combiners/PermitOverrides$1.class
+com/att/research/xacmlatt/pdp/policy/expressions/VariableReference.class
+com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesRule.class
+com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameterMap.class
+com/att/research/xacmlatt/pdp/policy/PolicyDefaults.class
+com/att/research/xacmlatt/pdp/policy/FunctionArgumentAttributeValue.class
+com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultEmptyBag.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySet.class
+com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesPolicy.class
+com/att/research/xacmlatt/pdp/std/StdEvaluationContext.class
+com/att/research/xacmlatt/pdp/ATTPDPEngine$1.class
+com/att/research/xacmlatt/pdp/policy/PolicyIdReferenceBase.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringEqualIgnoreCase.class
+com/att/research/xacmlatt/pdp/policy/ObligationExpression.class
+com/att/research/xacmlatt/pdp/policy/AllOf$1.class
+com/att/research/xacmlatt/pdp/util/ATTPDPProperties.class
+com/att/research/xacmlatt/pdp/policy/AttributeAssignmentResult.class
+com/att/research/xacmlatt/pdp/eval/EvaluationContextException.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions$OPERATION.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical$OPERATION.class
+com/att/research/xacmlatt/pdp/policy/expressions/AttributeValueExpression.class
diff --git a/openaz-xacml-pdp/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/openaz-xacml-pdp/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
new file mode 100644
index 0000000..b9e94a4
--- /dev/null
+++ b/openaz-xacml-pdp/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
@@ -0,0 +1,142 @@
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicySet.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAllOf.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagOneAndOnly.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionAccessPermitted.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMExpression.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesRule.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/package-info.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionEquality.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicy.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyIssuer.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBag.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdEvaluationContextFactory.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/Function.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/RuleEffect.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesPolicy.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Match.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMVariableDefinition.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyIdReferenceBase.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/CombiningAlgorithmBase.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Bag.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgumentBag.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameterMap.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/Matchable.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombinerParameter.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionDefinition.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeDesignator.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetIdReference.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/ObligationExpression.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationContext.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMRuleCombinerParameters.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAnyOf.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/ExpressionResultBoolean.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithms.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeSelector.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Expression.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameter.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/util/ATTPDPProperties.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/package-info.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdProperties.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyDef.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/ATTPDPEngineFactory.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/PermitOverrides.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/package-info.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMMatch.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMTarget.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagIsIn.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMRule.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombiningAlgorithmFactory.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithmFactory.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/Apply.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/CombinedPermitOverrides.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Policy.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgumentAttributeValue.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeDesignator.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySet.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyFinderFactory.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgument.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMApply.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdPolicyFinderFactory.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdFunctions.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyCombinerParameter.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeSelector.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AttributeAssignmentExpression.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/ExpressionResult.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/MatchResult.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombiningAlgorithm.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionNumberTypeConversion.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationContextFactory.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyFinder.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/DenyUnlessPermit.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAdviceExpression.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeAssignmentExpression.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetCombinerParameter.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationContextException.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/package-info.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyRepair.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyFinderResult.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/package-info.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/package-info.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionTimeInRange.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBase.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeRetrievalBase.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMCombinerParameter.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDef.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMDocumentRepair.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdPolicyFinder.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationException.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/FirstApplicable.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AnyOf.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHomogeneousSimple.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AllOf.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/VariableMap.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesPolicy.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringEqualIgnoreCase.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicySetIdReference.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMObligationExpression.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdEvaluationContext.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Condition.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AttributeAssignmentResult.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/PermitUnlessDeny.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/package-info.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/VariableDefinition.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdFunctionDefinitionFactory.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/OnlyOneApplicable.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesRule.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/VariableReference.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyIdReference.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyDefaults.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicySetChild.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeValueExpression.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIssuer.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/ATTPDPEngine.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionX500NameMatch.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringConversion.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Target.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyComponent.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/Evaluatable.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRFC822NameMatch.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/ConvertedArgument.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombiningElement.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIdReference.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgumentExpression.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/DenyOverrides.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagSize.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionURIStringConcatenate.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationResult.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdPolicyFinderResult.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AdviceExpression.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRegexpMatch.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/package-info.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDefaults.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Rule.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionDefinitionFactory.java
diff --git a/openaz-xacml-pdp/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/openaz-xacml-pdp/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/openaz-xacml-pdp/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
diff --git a/openaz-xacml-pdp/target/openaz-xacml-pdp-0.0.1-SNAPSHOT.jar b/openaz-xacml-pdp/target/openaz-xacml-pdp-0.0.1-SNAPSHOT.jar
new file mode 100644
index 0000000..ff65667
--- /dev/null
+++ b/openaz-xacml-pdp/target/openaz-xacml-pdp-0.0.1-SNAPSHOT.jar
Binary files differ
diff --git a/openaz-xacml-pdp/xacml.properties b/openaz-xacml-pdp/xacml.properties
new file mode 100755
index 0000000..8394be9
--- /dev/null
+++ b/openaz-xacml-pdp/xacml.properties
@@ -0,0 +1,26 @@
+# Default XACML Properties File
+# Standard API Factories
+#
+xacml.dataTypeFactory=com.att.research.xacml.std.StdDataTypeFactory
+xacml.pdpEngineFactory=com.att.research.xacmlatt.pdp.ATTPDPEngineFactory
+xacml.pepEngineFactory=com.att.research.xacml.std.pep.StdEngineFactory
+xacml.pipFinderFactory=com.att.research.xacml.std.pip.StdPIPFinderFactory
+
+# If there is a standard set of PIPEngines:
+# xacml.pip.engines=engine1,engine2,...,engineN
+# engine1.classname=com.att.research.xacmlpip.OraclePIP
+# engine1.prop1=foo
+# engine1.prop2=bar
+# ...
+# engine2.classname=com.att.research.xacmlpip.ActiveDirectoryPIP
+# ...
+
+# AT&T PDP Implementation Factories
+#
+xacml.att.evaluationContextFactory=com.att.research.xacmlatt.pdp.std.StdEvaluationContextFactory
+xacml.att.combiningAlgorithmFactory=com.att.research.xacmlatt.pdp.std.StdCombiningAlgorithmFactory
+xacml.att.functionDefinitionFactory=com.att.research.xacmlatt.pdp.std.StdFunctionDefinitionFactory
+xacml.att.policyFinderFactory=com.att.research.xacmlatt.pdp.std.StdPolicyFinderFactory
+
+# If there is a standard policy for the engine:
+# xacml.att.stdPolicyFinderFactory.rootPolicyFile=/etc/stdpolicyset.xml
diff --git a/openaz-xacml-rest/pom.xml b/openaz-xacml-rest/pom.xml
new file mode 100755
index 0000000..cf8b334
--- /dev/null
+++ b/openaz-xacml-rest/pom.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>openaz</artifactId>
+        <groupId>org.openliberty.openaz</groupId>
+        <version>0.0.1-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>openaz-xacml-rest</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.openliberty.openaz</groupId>
+            <artifactId>openaz-xacml</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-logging</groupId>
+            <artifactId>commons-logging</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/openaz-xacml-rest/src/main/java/com/att/research/xacml/rest/XACMLRest.java b/openaz-xacml-rest/src/main/java/com/att/research/xacml/rest/XACMLRest.java
new file mode 100755
index 0000000..83a8c7b
--- /dev/null
+++ b/openaz-xacml-rest/src/main/java/com/att/research/xacml/rest/XACMLRest.java
@@ -0,0 +1,201 @@
+/*
+ *                        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.xacml.rest;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.att.research.xacml.util.XACMLProperties;
+
+/**
+ * This static class is used by both the PDP and PAP servlet's. It contains some common
+ * static functions and objects used by both the servlet's.
+ * 
+ * @author pameladragosh
+ *
+ */
+public class XACMLRest {
+	private static final Log logger	= LogFactory.getLog(XACMLRest.class);
+	private static Properties restProperties = new Properties();
+	
+	/**
+	 * This must be called during servlet initialization. It sets up the xacml.?.properties
+	 * file as a system property. If the System property is already set, then it does not
+	 * do anything. This allows the developer to specify their own xacml.properties file to be
+	 * used. They can 1) modify the default properties that comes with the project, or 2) change
+	 * the WebInitParam annotation, or 3) specify an alternative path in the web.xml, or 4) set
+	 * the Java System property to point to their xacml.properties file.
+	 * 
+	 * The recommended way of overriding the default xacml.properties file is using a Java System
+	 * property:
+	 * 
+	 * -Dxacml.properties=/opt/app/xacml/etc/xacml.admin.properties
+	 * 
+	 * This way one does not change any actual code or files in the project and can leave the 
+	 * defaults alone.
+	 * 
+	 * @param config - The servlet config file passed from the javax servlet init() function
+	 */
+	public static void xacmlInit(ServletConfig config) {
+		//
+		// Get the XACML Properties File parameter first
+		//
+		String propFile = config.getInitParameter("XACML_PROPERTIES_NAME");
+		if (propFile != null) {
+			//
+			// Look for system override
+			//
+			String xacmlPropertiesName = System.getProperty(XACMLProperties.XACML_PROPERTIES_NAME);
+			if (xacmlPropertiesName == null) {
+				//
+				// Set it to our servlet default
+				//
+				if (logger.isDebugEnabled()) {
+					logger.debug("Using Servlet Config Property for XACML_PROPERTIES_NAME:" + propFile);
+				}
+				System.setProperty(XACMLProperties.XACML_PROPERTIES_NAME, propFile);
+			} else {
+				if (logger.isDebugEnabled()) {
+					logger.debug("Using System Property for XACML_PROPERTIES_NAME:" + xacmlPropertiesName);
+				}
+			}
+		}
+		//
+		// Setup the remaining properties
+		//
+		Enumeration<String> params = config.getInitParameterNames();
+		while (params.hasMoreElements()) {
+			String param = params.nextElement();
+			if (! param.equals("XACML_PROPERTIES_NAME")) {
+				String value = config.getInitParameter(param);
+				logger.info(param + "=" + config.getInitParameter(param));
+				restProperties.setProperty(param, value);
+			}
+		}
+	}
+	
+	/**
+	 * Reset's the XACMLProperties internal properties object so we start
+	 * in a fresh environment. Then adds back in our Servlet init properties that were
+	 * passed in the javax Servlet init() call.
+	 * 
+	 * This function is primarily used when a new configuration is passed in and the
+	 * PDP servlet needs to load a new PDP engine instance.
+	 * 
+	 * @param pipProperties - PIP configuration properties
+	 * @param policyProperties  - Policy configuration properties
+	 */
+	public static void loadXacmlProperties(Properties policyProperties, Properties pipProperties) {
+		try {
+			//
+			// Start fresh
+			//
+			XACMLProperties.reloadProperties();
+			//
+			// Now load our init properties
+			//
+			XACMLProperties.getProperties().putAll(XACMLRest.restProperties);
+			//
+			// Load our policy properties
+			//
+			if (policyProperties != null) {
+				XACMLProperties.getProperties().putAll(policyProperties);
+			}
+			//
+			// Load our pip config properties
+			//
+			if (pipProperties != null) {
+				XACMLProperties.getProperties().putAll(pipProperties);
+			}
+		} catch (IOException e) {
+			logger.error("Failed to put init properties into Xacml properties", e);
+		}
+		//
+		// Dump them
+		//
+		if (logger.isDebugEnabled()) {
+			try {
+				logger.debug(XACMLProperties.getProperties().toString());
+			} catch (IOException e) {
+				logger.error("Cannot dump properties", e);
+			}
+		}
+	}
+	
+	/**
+	 * Helper routine to dump the HTTP servlet request being serviced. Primarily for debugging.
+	 * 
+	 * @param request - Servlet request (from a POST/GET/PUT/etc.)
+	 */
+	public static void dumpRequest(HttpServletRequest request) {
+		if (logger.isDebugEnabled()) {
+			// special-case for receiving heartbeat - don't need to repeatedly output all of the information in multiple lines
+			if (request.getMethod().equals("GET") && "hb".equals(request.getParameter("type"))  ) {
+				logger.debug("GET type=hb : heartbeat received");
+				return;
+			}
+			logger.debug(request.getMethod() + ":" + request.getRemoteAddr() + " " + request.getRemoteHost() + " " + request.getRemotePort());
+			logger.debug(request.getLocalAddr() + " " + request.getLocalName() + " " + request.getLocalPort());
+			Enumeration<String> en = request.getHeaderNames();
+			logger.debug("Headers:");
+			while (en.hasMoreElements()) {
+				String element = en.nextElement();
+				Enumeration<String> values = request.getHeaders(element);
+				while (values.hasMoreElements()) {
+					String value = values.nextElement();
+					logger.debug(element + ":" + value);
+				}
+			}
+			logger.debug("Attributes:");
+			en = request.getAttributeNames();
+			while (en.hasMoreElements()) {
+				String element = en.nextElement();
+				logger.debug(element + ":" + request.getAttribute(element));
+			}
+			logger.debug("ContextPath: " + request.getContextPath());
+			if (request.getMethod().equals("PUT") || request.getMethod().equals("POST")) {
+				// POST and PUT are allowed to have parameters in the content, but in our usage the parameters are always in the Query string.
+				// More importantly, there are cases where the POST and PUT content is NOT parameters (e.g. it might contain a Policy file).
+				// Unfortunately the request.getParameterMap method reads the content to see if there are any parameters,
+				// and once the content is read it cannot be read again.
+				// Thus for PUT and POST we must avoid reading the content here so that the main code can read it.
+				logger.debug("Query String:" + request.getQueryString());
+				try {
+					if (request.getInputStream() == null) {
+						logger.debug("Content: No content inputStream");
+					} else {
+						logger.debug("Content available: " + request.getInputStream().available());
+					}
+				} catch (Exception e) {
+					logger.debug("Content: inputStream exception: " + e.getMessage() + ";  (May not be relevant)");
+				}
+			} else {
+				logger.debug("Parameters:");
+				Map<String, String[]> params = request.getParameterMap();
+				Set<String> keys = params.keySet();
+				for (String key : keys) {
+					String[] values = params.get(key);
+					logger.debug(key + "(" + values.length + "): " + (values.length > 0 ? values[0] : ""));
+				}
+			}
+			logger.debug("Request URL:" + request.getRequestURL());
+		}
+	}
+}
diff --git a/openaz-xacml-rest/src/main/java/com/att/research/xacml/rest/XACMLRestProperties.java b/openaz-xacml-rest/src/main/java/com/att/research/xacml/rest/XACMLRestProperties.java
new file mode 100755
index 0000000..d70f33e
--- /dev/null
+++ b/openaz-xacml-rest/src/main/java/com/att/research/xacml/rest/XACMLRestProperties.java
@@ -0,0 +1,137 @@
+/*
+ *                        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.xacml.rest;
+
+import com.att.research.xacml.util.XACMLProperties;
+
+/**
+ * These are XACML Properties that are relevant to the RESTful API interface for
+ * the PDP, PAP and AC interfaces.
+ * 
+ *  
+ * @author pameladragosh
+ *
+ */
+public class XACMLRestProperties extends XACMLProperties {
+	/**
+	 * A unique identifier for the PDP servlet instance. Usually set to the URL
+	 * it is running as in the J2EE container.
+	 * 
+	 * Eg. http://localhost:8080/pdp/
+	 */
+	public static final String	PROP_PDP_ID	= "xacml.rest.pdp.id";
+	/**
+	 * A PDP servlet's configuration directory. Holds the pip and policy configuration
+	 * data as well as the local policy cache.
+	 * 
+	 * Eg: /opt/app/xacml/config
+	 */
+	public static final String	PROP_PDP_CONFIG = "xacml.rest.pdp.config";
+	/**
+	 * Set this property to true or false if the PDP servlet should register itself upon
+	 * startup with the PAP servlet.
+	 */
+	public static final String	PROP_PDP_REGISTER = "xacml.rest.pdp.register";
+	/**
+	 * Number of seconds the PDP will sleep while retrying registration with the PAP. 
+	 * This value must be greater or equal to 5.
+	 */
+	public static final String	PROP_PDP_REGISTER_SLEEP = "xacml.rest.pdp.register.sleep";
+	/**
+	 * Number of retry attempts at registration with the PAP. A value of -1 indicates infinite retries.
+	 */
+	public static final String	PROP_PDP_REGISTER_RETRIES = "xacml.rest.pdp.register.retries";
+	/**
+	 * Max content length accepted for an incoming POST XML/JSON request. Default is 32767 bytes.
+	 */
+	public static final String	PROP_PDP_MAX_CONTENT = "xacml.rest.pdp.maxcontent";
+	/**
+	 * Custom HTTP header used by PDP to send the value of the PROP_PDP_ID
+	 */
+	public static final String	PROP_PDP_HTTP_HEADER_ID = "X-XACML-PDP-ID";
+	/**
+	 * Custom HHTP header used by PDP to send its heartbeat value.
+	 */
+	public static final String	PROP_PDP_HTTP_HEADER_HB = "X-XACML-PDP-HB";
+	/**
+	 * The URL of the PAP servlet. Used by PDP servlet's to communicate. Because administrators
+	 * can set whatever context they want to run the PAP servlet, it isn't easy to determine a return
+	 * URL for the PAP servlet. This is especially true upon initialization.
+	 */
+	public static final String	PROP_PAP_URL = "xacml.rest.pap.url";
+	/**
+	 * Upon startup, have the PAP servlet send latest configuration information to all
+	 * the PDP nodes it knows about.
+	 */
+	public static final String PROP_PAP_INITIATE_PDP_CONFIG = "xacml.rest.pap.initiate.pdp";
+	/**
+	 * The interval the PAP servlet uses to send heartbeat requests to the PDP nodes.
+	 */
+	public static final String	PROP_PAP_HEARTBEAT_INTERVAL = "xacml.rest.pap.heartbeat.interval";
+	/**
+	 * Timeout value used by the PAP servlet when trying to check the heartbeat of a PDP node.
+	 */
+	public static final String	PROP_PAP_HEARTBEAT_TIMEOUT = "xacml.rest.pap.heartbeat.timeout";
+	/*
+	 * Local path to  where the GIT repository exists.
+	 * 
+	 * Eg. /opt/app/xacml/repository
+	 */
+	public static final String PROP_ADMIN_REPOSITORY = "xacml.rest.admin.repository";
+	/*
+	 * Local path to where user workspaces exist. The user workspace contains temporary files, the
+	 * user's clone of the GIT repository, anything specific to the user, etc.
+	 */
+	public static final String PROP_ADMIN_WORKSPACE = "xacml.rest.admin.workspace";
+	/*
+	 * This is the domain you can setup for your organization, it should be a URI.
+	 * 
+	 * Eg. com:sample:foo
+	 */
+	public static final String PROP_ADMIN_DOMAIN = "xacml.rest.admin.domain";
+	/**
+	 * PROP_ADMIN_USER_NAME is simply a name for the logged in user.
+	 * 
+	 * AC authentication is out the scope of the web application itself. It is up to the
+	 * developer to setup authentication as they please in the J2EE container used to run
+	 * the web application. Whatever authentication mechanism they use, they should then set
+	 * the attribute into the HttpSession object. The Admin Console will be able to read that
+	 * value (default to "guest") in. 
+	 * 
+	 * ((HttpServletRequest) request).getSession().setAttribute("xacml.rest.admin.user.name", "Homer");
+	 * 
+	 */
+	public static final String	PROP_ADMIN_USER_NAME = "xacml.rest.admin.user.name";
+	/**
+	 * 
+	 * PROP_ADMIN_USER_ID is an id for the logged in user.
+	 * 
+	 * Eg. hs1234
+	 *
+	 * @see #PROP_ADMIN_USER_NAME for more information.
+	 */
+	public static final String	PROP_ADMIN_USER_ID = "xacml.rest.admin.user.id";
+	/**
+	 * 
+	 * PROP_ADMIN_USER_EMAIL is a user's email address.
+	 * 
+	 * @see #PROP_ADMIN_USER_NAME for more information.
+	 */
+	public static final String	PROP_ADMIN_USER_EMAIL = "xacml.rest.admin.user.email";
+	/**
+	 * Directory path containing sub-directories where the Subscriber servlet puts files sent through data feeds.
+	 */
+	public static final String	PROP_SUBSCRIBER_INCOMING = "xacml.subscriber.incoming";
+	/**
+	 * The specific data feed name for the Subscriber servlet to register for.
+	 */
+	public static final String	PROP_SUBSCRIBER_FEED = "xacml.subscriber.feed";
+}
diff --git a/openaz-xacml-rest/target/classes/com/att/research/xacml/rest/XACMLRest.class b/openaz-xacml-rest/target/classes/com/att/research/xacml/rest/XACMLRest.class
new file mode 100644
index 0000000..ef86656
--- /dev/null
+++ b/openaz-xacml-rest/target/classes/com/att/research/xacml/rest/XACMLRest.class
Binary files differ
diff --git a/openaz-xacml-rest/target/classes/com/att/research/xacml/rest/XACMLRestProperties.class b/openaz-xacml-rest/target/classes/com/att/research/xacml/rest/XACMLRestProperties.class
new file mode 100644
index 0000000..b6570eb
--- /dev/null
+++ b/openaz-xacml-rest/target/classes/com/att/research/xacml/rest/XACMLRestProperties.class
Binary files differ
diff --git a/openaz-xacml-rest/target/maven-archiver/pom.properties b/openaz-xacml-rest/target/maven-archiver/pom.properties
new file mode 100644
index 0000000..75af03d
--- /dev/null
+++ b/openaz-xacml-rest/target/maven-archiver/pom.properties
@@ -0,0 +1,5 @@
+#Generated by Maven
+#Tue Apr 07 07:42:35 EDT 2015
+version=0.0.1-SNAPSHOT
+groupId=org.openliberty.openaz
+artifactId=openaz-xacml-rest
diff --git a/openaz-xacml-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/openaz-xacml-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
new file mode 100644
index 0000000..d842d7d
--- /dev/null
+++ b/openaz-xacml-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
@@ -0,0 +1,2 @@
+com/att/research/xacml/rest/XACMLRestProperties.class
+com/att/research/xacml/rest/XACMLRest.class
diff --git a/openaz-xacml-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/openaz-xacml-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
new file mode 100644
index 0000000..f772e13
--- /dev/null
+++ b/openaz-xacml-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
@@ -0,0 +1,2 @@
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-rest/src/main/java/com/att/research/xacml/rest/XACMLRest.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-rest/src/main/java/com/att/research/xacml/rest/XACMLRestProperties.java
diff --git a/openaz-xacml-rest/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/openaz-xacml-rest/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/openaz-xacml-rest/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
diff --git a/openaz-xacml-rest/target/openaz-xacml-rest-0.0.1-SNAPSHOT.jar b/openaz-xacml-rest/target/openaz-xacml-rest-0.0.1-SNAPSHOT.jar
new file mode 100644
index 0000000..49eba1f
--- /dev/null
+++ b/openaz-xacml-rest/target/openaz-xacml-rest-0.0.1-SNAPSHOT.jar
Binary files differ
diff --git a/openaz-xacml-test/pom.xml b/openaz-xacml-test/pom.xml
new file mode 100755
index 0000000..c88e4c0
--- /dev/null
+++ b/openaz-xacml-test/pom.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>openaz</artifactId>
+        <groupId>org.openliberty.openaz</groupId>
+        <version>0.0.1-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>openaz-xacml-test</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>openaz-xacml</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>openaz-xacml-rest</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>openaz-xacml-pdp</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-codec</groupId>
+            <artifactId>commons-codec</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-logging</groupId>
+            <artifactId>commons-logging</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-cli</groupId>
+            <artifactId>commons-cli</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.h2database</groupId>
+            <artifactId>h2</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>postgresql</groupId>
+            <artifactId>postgresql</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.hsqldb</groupId>
+            <artifactId>hsqldb</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/dom/DOMResponseConformanceTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/dom/DOMResponseConformanceTest.java
new file mode 100755
index 0000000..de3851b
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/dom/DOMResponseConformanceTest.java
@@ -0,0 +1,187 @@
+/*

+ *                        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.std.dom;

+

+import static org.junit.Assert.fail;

+

+import java.io.BufferedReader;

+import java.io.File;

+import java.io.FileReader;

+import java.util.ArrayList;

+import java.util.List;

+

+import org.junit.Test;

+

+import com.att.research.xacml.api.Response;

+import com.att.research.xacml.std.dom.DOMResponse;

+

+/**

+ * Tests for handling the XML version of the XACML Response object.

+ * 

+ * TO RUN - use jUnit

+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test

+ * 

+ * Normally the Response is generated by the PDP and returned through the RESTful interface as JSON.

+ * Testing of the XML interface is minimal and not complete.

+ * 

+ * 

+ * 

+ * @author glenngriffin

+ *

+ */

+public class DOMResponseConformanceTest {

+	

+	// where to find the conformance test XML files

+	private final String CONFORMANCE_DIRECTORY_PATH = "testsets/conformance/xacml3.0-ct-v.0.4";

+	

+	// The request object output from each test conversion from JSON string

+	Response response;

+

+	

+	

+	// Load the Conformance test responses into Response objects, generate the output XML for that Response and compare with the original files.

+	@Test

+	public void testDOMResponse() {

+		List<File> filesInDirectory = null;

+		

+		File conformanceDirectory = null;

+		

+		File currentFile = null;

+		

+		try {

+			conformanceDirectory = new File(CONFORMANCE_DIRECTORY_PATH);

+			filesInDirectory = getRequestsInDirectory(conformanceDirectory);

+		} catch (Exception e) {

+			fail("Unable to set up Conformance tests for dir '" + conformanceDirectory.getAbsolutePath()+"' e="+ e);

+		}

+		

+		// run through each XML file

+		//	- load the file from XML into an internal Response object

+		//	- generate the XML representation from that Response object

+		// 	- reload the file into a String

+		//	- compare the 2 XML strings

+		Response xmlResponse = null;

+		try {

+			for (File f : filesInDirectory) {

+				currentFile = f;

+

+//// This is a simple way to select just one file for debugging - comment out when not being used

+//if ( ! f.getName().equals("IID302Response.xml")) {   continue;  }

+

+// during debugging it is helpful to know what file it is starting to work on

+//				System.out.println("starting file="+currentFile.getName());

+				

+				

+				BufferedReader br = new BufferedReader(new FileReader(f));

+				StringBuffer sb = new StringBuffer();

+				String line;

+				while ((line = br.readLine()) != null) {

+					sb.append(line + "\n");

+				}

+				br.close();

+				

+				String xmlFromFile = sb.toString();

+				

+				try {

+					// load XML into a Response object

+					xmlResponse = DOMResponse.load(xmlFromFile);

+				} catch (Exception e) {

+					// if XML does not load, just note it and continue with next file

+					System.out.println("XML file did not load: '" + f.getName() + "  e=" + e);

+					continue;

+				}

+//System.out.println(xmlFromFile);				

+				

+				// create String version from the Response object

+				String xmlResponseString = DOMResponse.toString(xmlResponse, false);

+				

+				// Comparing the string directly to the String from the file is difficult.

+				// We can minimize the problems with newlines and whitespace, but we have other issues with how various object values are represented.

+				// For instance, and input double of "23.50" is output as "23.5" which is the same value but not identical strings.

+				// Therefore we take the XML output and use it to create a new Response object, then compare the two objects.

+

+//System.out.println(xmlResponseString);			

+				Response reGeneratedResponse = DOMResponse.load(xmlResponseString);

+				

+				if ( ! xmlResponse.equals(reGeneratedResponse)) {

+					String normalizedFromFile = xmlFromFile.replaceAll("\\r|\\n", "");

+					normalizedFromFile = normalizedFromFile.replaceAll("\\s+", " ");

+					normalizedFromFile = normalizedFromFile.replaceAll(">\\s*<", "><");

+					System.out.println("File="+normalizedFromFile);

+					System.out.println("Gend="+ xmlResponseString);

+					

+					System.out.println(DOMResponse.toString(xmlResponse, true));

+				

+					fail("Output string did not re-generate eqivilent object.");

+				}

+

+//				// Normally whitespace is significant in XML.

+//				// However in this case we are generating an XML string for output and comparing it to a hand-made file.

+//				// The file may contain extra newlines or fewer spaces then our prettyPrinted output version.

+//				// Therefore we do the comparison on the un-prettyPrinted generated string.

+//				// To do this we have to remove the extra whitespace from the version read from the file.

+//				String normalizedFromFile = xmlFromFile.replaceAll("\\r|\\n", "");

+//				normalizedFromFile = normalizedFromFile.replaceAll("\\s+", " ");

+//				normalizedFromFile = normalizedFromFile.replaceAll(">\\s*<", "><");

+//			

+//				if ( ! xmlResponseString.equals(normalizedFromFile)) {

+//					System.out.println("file="+normalizedFromFile+"\ngend="+xmlResponseString);

+//					fail("file not same as generated string: " + f.getName()+ "\nFile="+xmlFromFile + "\nString="+xmlResponseString);

+//				}

+

+

+			}			

+

+		} catch (Exception e) {

+			fail ("Failed test with '" + currentFile.getName() + "', e=" + e);

+		}

+

+		

+	}

+	

+	

+	

+	//

+	// HELPER to get list of all Request files in the given directory

+	//

+	

+	private List<File> getRequestsInDirectory(File directory) {

+		List<File> fileList = new ArrayList<File>();

+		

+		File[] fileArray = directory.listFiles();

+		for (File f : fileArray) {

+			if (f.isDirectory()) {

+				List<File> subDirList = getRequestsInDirectory(f);

+				fileList.addAll(subDirList);

+			}

+			if (f.getName().endsWith("Response.xml")) {

+				fileList.add(f);

+			}

+		}

+		return fileList;

+		

+	}

+	

+	

+}

+

+

+/*

+Place to edit long strings output during tests

+

+

+

+

+

+

+

+

+*/

diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/dom/DOMResponseTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/dom/DOMResponseTest.java
new file mode 100755
index 0000000..9596650
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/dom/DOMResponseTest.java
@@ -0,0 +1,2287 @@
+/*

+ *                        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.std.dom;

+

+import com.att.research.xacml.api.*;

+import com.att.research.xacml.std.*;

+import com.att.research.xacml.std.datatypes.DataTypes;

+import com.att.research.xacml.std.datatypes.StringNamespaceContext;

+import com.att.research.xacml.std.datatypes.XPathExpressionWrapper;

+import com.att.research.xacml.std.dom.DOMResponse;

+import com.att.research.xacml.std.dom.DOMStructureException;

+import org.junit.Test;

+

+import java.text.ParseException;

+import java.util.ArrayList;

+import java.util.Arrays;

+import java.util.Collection;

+import java.util.List;

+

+import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.fail;

+

+/**

+ * Test DOM XML Responses

+ * 

+ * TO RUN - use jUnit

+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test

+ * 

+ * This class was copied from the JSON tests.  At this time only the first two methods have been revised to work with XML.

+ * The second method includes multiple instances of all possible fields and has been manually verified.

+ * The remaining methods have not been converted because:

+ * 	- "conversion" consists of replacing the JSON strings with XML

+ * 	- the replacement would consist of copying the XML from the JUnit output and doing a String replace

+ * 	- there would be little examination of the (long) XML strings, so their validity would be questionable

+ * so the benefit for the cost of doing that work is not clear.

+ * 

+ * @author glenngriffin

+ *

+ */

+public class DOMResponseTest {

+

+	String xmlResponse;

+	

+	StdMutableResponse response;

+	

+	StdMutableResult result;

+	

+	StdMutableStatus status;

+	

+	

+	// Note: Initially test responses without Obligations, Associated Advice, Attributes, or PolicyIdentifier

+	

+	

+	@Test

+	public void testEmptyAndDecisions() {

+		// null response

+		try {

+			xmlResponse = DOMResponse.toString(null, false);

+			fail("Operation should throw exception");

+		} catch (DOMStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from object to XML: " + e);

+		}

+		

+		// empty response (no Result object)

+		response = new StdMutableResponse();

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			fail("Operation should throw exception");

+		} catch (DOMStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from object to XML: " + e);

+		}

+		

+		

+		// just decision, no status

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		// just status (empty), no decision

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		status = new StdMutableStatus();		

+		result.setStatus(status);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			fail("Operation should throw exception");

+		} catch (DOMStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from object to XML: " + e);

+		}

+		

+		// just status (non-empty), no decision

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		status = new StdMutableStatus();

+		status.setStatusCode(StdStatusCode.STATUS_CODE_OK);

+		result.setStatus(status);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			fail("Operation should throw exception");

+		} catch (DOMStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from object to XML: " + e);

+		}

+		

+		

+		// test other decisions without Status

+		

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.DENY);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Deny</Decision></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.NOTAPPLICABLE);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>NotApplicable</Decision></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.INDETERMINATE);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.INDETERMINATE_DENY);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{D}</Decision></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.INDETERMINATE_DENYPERMIT);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{DP}</Decision></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.INDETERMINATE_PERMIT);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{P}</Decision></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+

+		

+		// test Multiple Decisions - success

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		response.add(result);

+		StdMutableResult result2 = new StdMutableResult();

+		result2.setDecision(Decision.DENY);

+		response.add(result2);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision></Result><Result><Decision>Deny</Decision></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		

+		// test Multiple Decisions - one success and one error

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		response.add(result);

+		result2 = new StdMutableResult();

+		result2.setDecision(Decision.INDETERMINATE);

+		response.add(result2);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision></Result><Result><Decision>Indeterminate</Decision></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+	}

+		

+

+	

+	

+	// Test with every field filled in with multiple values where appropriate

+	@Test

+	public void testAllFieldsResponse() {	

+		

+		// fully-loaded multiple response

+		

+		StdMutableResponse response = new StdMutableResponse();

+		// create a Status object

+		StdMutableStatus status = new StdMutableStatus(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE);

+		status.setStatusMessage("some status message");

+		StdMutableStatusDetail statusDetailIn = new StdMutableStatusDetail();

+		StdMutableMissingAttributeDetail mad = new StdMutableMissingAttributeDetail();

+		mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "doh"));

+		mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_INTEGER.getId(), "5432"));

+		mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "meh"));

+		mad.setAttributeId(XACML3.ID_ACTION_PURPOSE);

+		mad.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_ACTION);

+		mad.setDataTypeId(XACML3.ID_DATATYPE_STRING);

+		mad.setIssuer("an Issuer");

+		statusDetailIn.addMissingAttributeDetail(mad);

+		status.setStatusDetail(statusDetailIn);

+		// create a single result object

+		StdMutableResult result = new StdMutableResult(status);

+		// set the decision

+		result.setDecision(Decision.INDETERMINATE);

+		// put the Result into the Response

+		response.add(result);

+

+		

+		// create a new Result with a different Decision

+		status = new StdMutableStatus(StdStatusCode.STATUS_CODE_OK);

+		result = new StdMutableResult(status);

+		result.setDecision(Decision.DENY);

+		

+		StdMutableObligation obligation = new StdMutableObligation();

+		obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION);

+		obligation.addAttributeAssignment(new StdMutableAttributeAssignment(

+				XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, 

+				XACML3.ID_SUBJECT, 

+				"obligation-issuer1", 

+				new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart")));

+		obligation.addAttributeAssignment(new StdMutableAttributeAssignment(

+				XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, 

+				XACML3.ID_SUBJECT, 

+				"obligation-issuer2", 

+				new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Ned")));

+		result.addObligation(obligation);

+		obligation = new StdMutableObligation();

+		obligation.setId(XACML3.ID_SUBJECT_CATEGORY_INTERMEDIARY_SUBJECT);

+		obligation.addAttributeAssignment(new StdMutableAttributeAssignment(

+				XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, 

+				XACML3.ID_SUBJECT, 

+				"obligation-issuer3", 

+				new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Maggie")));

+		obligation.addAttributeAssignment(new StdMutableAttributeAssignment(

+				XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, 

+				XACML3.ID_SUBJECT, 

+				"obligation-issuer4", 

+				new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Homer")));

+		result.addObligation(obligation);

+		

+		

+		StdMutableAdvice advice = new StdMutableAdvice();

+		advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION);

+		advice.addAttributeAssignment(new StdMutableAttributeAssignment(

+				XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, 

+				XACML3.ID_SUBJECT, 

+				"advice-issuer1", 

+				new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu")));

+		advice.addAttributeAssignment(new StdMutableAttributeAssignment(

+				null, 

+				XACML3.ID_SUBJECT, 

+				"advice-issuerNoCategory", 

+				new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Crusty")));

+		result.addAdvice(advice);

+		

+		

+		response.add(result);

+		

+		

+		// create a new Result with a different Decision

+		// add Child/minor status codes within the main status

+		StdStatusCode childChildChildStatusCode = new StdStatusCode(new IdentifierImpl("childChildChildStatusCode"));

+		StdStatusCode childChildStatusCode = new StdStatusCode(new IdentifierImpl("childChildStatusCode"), childChildChildStatusCode);

+		StdStatusCode child1StatusCode = new StdStatusCode(new IdentifierImpl("child1StatusCode"), childChildStatusCode);

+		StdStatusCode statusCode = new StdStatusCode(XACML3.ID_STATUS_OK, child1StatusCode);

+		

+		status = new StdMutableStatus(statusCode);

+		

+		

+		result = new StdMutableResult(status);

+		result.setDecision(Decision.PERMIT);

+		

+		

+		

+		

+		// add attribute list in result

+		Identifier categoryIdentifier = new IdentifierImpl("firstCategory");

+		Attribute[] attrList = {

+				new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true),

+				new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent2"), new StdAttributeValue<String>(DataTypes.DT_YEARMONTHDURATION.getId(), "P10Y4M"), "BIssue", false),

+				new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent3"), new StdAttributeValue<Double>(DataTypes.DT_DOUBLE.getId(), 765.432), "CIssue", true),

+				new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent4"), new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), true), "DIssue", true),

+				new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent5"), new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567), "EIssue", true),

+				new StdAttribute(categoryIdentifier, new IdentifierImpl("attrNoIssuer"), new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567), null, true) };

+		result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, Arrays.asList(attrList)));

+		categoryIdentifier = new IdentifierImpl("secondCategory");

+		Attribute[] secondAttrList = {

+				new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent12"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu2"), "AIssue2", true),

+				new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent22"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Abc2"), "BIssue2", false),

+				new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent32"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Der2"), "CIssue2", true) };

+		result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, Arrays.asList(secondAttrList)));

+		

+		

+		// add PolicyIdentifierList to result

+		StdIdReference policyIdentifier1 = null;

+		StdIdReference policyIdentifier2 = null;

+		StdIdReference policySetIdentifier1 = null;

+		StdIdReference policySetIdentifier2 = null;

+		try {

+			policyIdentifier1 = new StdIdReference(new IdentifierImpl("idRef1"), StdVersion.newInstance("1.2.3"));

+			policyIdentifier2 = new StdIdReference(new IdentifierImpl("idRef2_NoVersion"));

+			policySetIdentifier1 = new StdIdReference(new IdentifierImpl("idSetRef1"), StdVersion.newInstance("4.5.6.7.8.9.0"));

+			policySetIdentifier2 = new StdIdReference(new IdentifierImpl("idSetRef2_NoVersion"));

+		} catch (ParseException e1) {

+			fail("creating policyIds, e="+e1);

+		}

+		

+		result.addPolicyIdentifier(policyIdentifier1);

+		result.addPolicyIdentifier(policyIdentifier2);

+	

+		result.addPolicySetIdentifier(policySetIdentifier1);

+		result.addPolicySetIdentifier(policySetIdentifier2);

+		

+		response.add(result);

+	

+		// convert Response to XML

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+//System.out.println(xmlResponse);

+//System.out.println(DOMResponse.toString(response, true));

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/><StatusMessage>some status message</StatusMessage><StatusDetail><MissingAttributeDetail Category=\"urn:oasis:names:tc:xacml:3.0:attribute-category:action\" AttributeId=\"urn:oasis:names:tc:xacml:2.0:action:purpose\" DataTypeId=\"http://www.w3.org/2001/XMLSchema#string\" Issuer=\"an Issuer\"><AttributeValue>doh</AttributeValue><AttributeValue>5432</AttributeValue><AttributeValue>meh</AttributeValue></MissingAttributeDetail></StatusDetail></Status></Result><Result><Decision>Deny</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:ok\"/></Status><Obligations><Obligation ObligationId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Ned</AttributeAssignment></Obligation><Obligation ObligationId=\"urn:oasis:names:tc:xacml:1.0:subject-category:intermediary-subject\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Maggie</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Homer</AttributeAssignment></Obligation></Obligations><AssociatedAdvice><Advice AdviceId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Crusty</AttributeAssignment></Advice></AssociatedAdvice></Result><Result><Decision>Permit</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:ok\"><StatusCode Value=\"child1StatusCode\"><StatusCode Value=\"childChildStatusCode\"><StatusCode Value=\"childChildChildStatusCode\"/></StatusCode></StatusCode></StatusCode></Status><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent3\" Issuer=\"CIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#double\">765.432</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent4\" Issuer=\"DIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#boolean\">true</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent5\" Issuer=\"EIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrNoIssuer\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute></Attributes><Attributes Category=\"secondCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent12\" Issuer=\"AIssue2\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu2</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent32\" Issuer=\"CIssue2\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Der2</AttributeValue></Attribute></Attributes><PolicyIdentifierList><PolicyIdReference Version=\"1.2.3\">idRef1</PolicyIdReference><PolicyIdReference>idRef2_NoVersion</PolicyIdReference><PolicySetIdReference Version=\"4.5.6.7.8.9.0\">idSetRef1</PolicySetIdReference><PolicySetIdReference>idSetRef2_NoVersion</PolicySetIdReference></PolicyIdentifierList></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+	}

+	

+	

+	

+	

+	// combinations of Status values with Decision values

+	@Test

+	public void testDecisionStatusMatch() {

+		// the tests in this method use different values and do not change structures, so we can re-use the objects

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		status = new StdMutableStatus();

+		result.setStatus(status);

+		response.add(result);

+		

+		// StatusCode = OK

+		status.setStatusCode(StdStatusCode.STATUS_CODE_OK);

+		result.setDecision(Decision.PERMIT);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:ok\"/></Status></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		result.setDecision(Decision.DENY);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Deny</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:ok\"/></Status></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		result.setDecision(Decision.NOTAPPLICABLE);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>NotApplicable</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:ok\"/></Status></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		result.setDecision(Decision.INDETERMINATE);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			fail("Operation should throw exception");

+		} catch (DOMStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from object to XML: " + e);

+		}

+		result.setDecision(Decision.INDETERMINATE_DENY);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			fail("Operation should throw exception");

+		} catch (DOMStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from object to XML: " + e);

+		}

+		result.setDecision(Decision.INDETERMINATE_DENYPERMIT);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			fail("Operation should throw exception");

+		} catch (DOMStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from object to XML: " + e);

+		}

+		result.setDecision(Decision.INDETERMINATE_PERMIT);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			fail("Operation should throw exception");

+		} catch (DOMStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from object to XML: " + e);

+		}

+		

+		

+		

+		

+		

+		

+		// StatusCode = SyntaxError

+		status.setStatusCode(StdStatusCode.STATUS_CODE_SYNTAX_ERROR);

+		result.setDecision(Decision.PERMIT);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			fail("Operation should throw exception");

+		} catch (DOMStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from object to XML: " + e);

+		}

+		result.setDecision(Decision.DENY);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			fail("Operation should throw exception");

+		} catch (DOMStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from object to XML: " + e);

+		}

+		result.setDecision(Decision.NOTAPPLICABLE);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			fail("Operation should throw exception");

+		} catch (DOMStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from object to XML: " + e);

+		}

+		result.setDecision(Decision.INDETERMINATE);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:syntax-error\"/></Status></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		result.setDecision(Decision.INDETERMINATE_DENY);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{D}</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:syntax-error\"/></Status></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		result.setDecision(Decision.INDETERMINATE_DENYPERMIT);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{DP}</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:syntax-error\"/></Status></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		result.setDecision(Decision.INDETERMINATE_PERMIT);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{P}</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:syntax-error\"/></Status></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		

+		// StatusCode = ProcessingError

+		status.setStatusCode(StdStatusCode.STATUS_CODE_PROCESSING_ERROR);

+		result.setDecision(Decision.PERMIT);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			fail("Operation should throw exception");

+		} catch (DOMStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from object to XML: " + e);

+		}

+		result.setDecision(Decision.DENY);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			fail("Operation should throw exception");

+		} catch (DOMStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from object to XML: " + e);

+		}

+		result.setDecision(Decision.NOTAPPLICABLE);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			fail("Operation should throw exception");

+		} catch (DOMStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from object to XML: " + e);

+		}

+		result.setDecision(Decision.INDETERMINATE);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:processing-error\"/></Status></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		result.setDecision(Decision.INDETERMINATE_DENY);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{D}</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:processing-error\"/></Status></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		result.setDecision(Decision.INDETERMINATE_DENYPERMIT);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{DP}</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:processing-error\"/></Status></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		result.setDecision(Decision.INDETERMINATE_PERMIT);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{P}</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:processing-error\"/></Status></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		

+		

+		// StatusCode = MissingAttribute

+		status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE);

+		result.setDecision(Decision.PERMIT);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			fail("Operation should throw exception");

+		} catch (DOMStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from object to XML: " + e);

+		}

+		result.setDecision(Decision.DENY);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			fail("Operation should throw exception");

+		} catch (DOMStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from object to XML: " + e);

+		}

+		result.setDecision(Decision.NOTAPPLICABLE);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			fail("Operation should throw exception");

+		} catch (DOMStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from object to XML: " + e);

+		}

+		result.setDecision(Decision.INDETERMINATE);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/></Status></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		result.setDecision(Decision.INDETERMINATE_DENY);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{D}</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/></Status></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		result.setDecision(Decision.INDETERMINATE_DENYPERMIT);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{DP}</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/></Status></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		result.setDecision(Decision.INDETERMINATE_PERMIT);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{P}</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/></Status></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+	}

+

+	

+	

+

+	// tests related to Status and its components

+	@Test

+	public void testStatus() {

+		// Status with no StatusCode - error

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		status = new StdMutableStatus();

+		result.setStatus(status);

+		result.setDecision(Decision.PERMIT);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			fail("Operation should throw exception");

+		} catch (DOMStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from object to XML: " + e);

+		}

+		

+		// Status with StatusMessage when OK

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		status = new StdMutableStatus();

+		status.setStatusCode(StdStatusCode.STATUS_CODE_OK);

+		status.setStatusMessage("I'm ok, you're ok");

+		result.setStatus(status);

+		result.setDecision(Decision.PERMIT);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:ok\"/><StatusMessage>I'm ok, you're ok</StatusMessage></Status></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		// Status with StatusDetail when OK

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		status = new StdMutableStatus();

+		status.setStatusCode(StdStatusCode.STATUS_CODE_OK);

+		StdMutableStatusDetail statusDetail = new StdMutableStatusDetail();

+		status.setStatusDetail(statusDetail);

+		result.setStatus(status);

+		result.setDecision(Decision.PERMIT);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			fail("Operation should throw exception");

+		} catch (DOMStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from object to XML: " + e);

+		}

+		

+		// Status with StatusMessage when SyntaxError

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		status = new StdMutableStatus();

+		status.setStatusCode(StdStatusCode.STATUS_CODE_SYNTAX_ERROR);

+		status.setStatusMessage("I'm ok, you're ok");

+		result.setStatus(status);

+		result.setDecision(Decision.INDETERMINATE);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:syntax-error\"/><StatusMessage>I'm ok, you're ok</StatusMessage></Status></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		// Status with empty StatusDetail when SyntaxError

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		status = new StdMutableStatus();

+		status.setStatusCode(StdStatusCode.STATUS_CODE_SYNTAX_ERROR);

+		statusDetail = new StdMutableStatusDetail();

+		status.setStatusDetail(statusDetail);

+		result.setStatus(status);

+		result.setDecision(Decision.INDETERMINATE);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			fail("Operation should throw exception");

+		} catch (DOMStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from object to XML: " + e);

+		}

+		

+		

+		// Status with StatusMessage when ProcessingError

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		status = new StdMutableStatus();

+		status.setStatusCode(StdStatusCode.STATUS_CODE_PROCESSING_ERROR);

+		status.setStatusMessage("I'm ok, you're ok");

+		result.setStatus(status);

+		result.setDecision(Decision.INDETERMINATE);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:processing-error\"/><StatusMessage>I'm ok, you're ok</StatusMessage></Status></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		// Status with empty StatusDetail when ProcessingError

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		status = new StdMutableStatus();

+		status.setStatusCode(StdStatusCode.STATUS_CODE_PROCESSING_ERROR);

+		statusDetail = new StdMutableStatusDetail();

+		status.setStatusDetail(statusDetail);

+		result.setStatus(status);

+		result.setDecision(Decision.INDETERMINATE);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			fail("Operation should throw exception");

+		} catch (DOMStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from object to XML: " + e);

+		}

+

+		

+		// Status with StatusMessage when MissingAttribute

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		status = new StdMutableStatus();

+		status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE);

+		status.setStatusMessage("I'm ok, you're ok");

+		result.setStatus(status);

+		result.setDecision(Decision.INDETERMINATE);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/><StatusMessage>I'm ok, you're ok</StatusMessage></Status></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		// Status with empty StatusDetail when MissingAttribute

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		status = new StdMutableStatus();

+		status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE);

+		statusDetail = new StdMutableStatusDetail();

+		status.setStatusDetail(statusDetail);

+		result.setStatus(status);

+		result.setDecision(Decision.INDETERMINATE);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/><StatusDetail></StatusDetail></Status></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		

+		

+		// Status with StatusDetail with empty detail when MissingAttribute

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		status = new StdMutableStatus();

+		status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE);

+		statusDetail = new StdMutableStatusDetail();

+		StdMutableMissingAttributeDetail mad = new StdMutableMissingAttributeDetail();

+		statusDetail.addMissingAttributeDetail(mad);

+		status.setStatusDetail(statusDetail);

+		result.setStatus(status);

+		result.setDecision(Decision.INDETERMINATE);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			fail("Operation should throw exception");

+		} catch (DOMStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from object to XML: " + e);

+		}

+		

+		// Status with StatusDetail with valid detail with no value when MissingAttribute

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		status = new StdMutableStatus();

+		status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE);

+		statusDetail = new StdMutableStatusDetail();

+		mad = new StdMutableMissingAttributeDetail();

+		mad.setAttributeId(new IdentifierImpl("mad"));

+		mad.setCategory(XACML3.ID_ACTION);

+		mad.setDataTypeId(DataTypes.DT_STRING.getId());

+		statusDetail.addMissingAttributeDetail(mad);

+		status.setStatusDetail(statusDetail);

+		result.setStatus(status);

+		result.setDecision(Decision.INDETERMINATE);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/><StatusDetail><MissingAttributeDetail Category=\"urn:oasis:names:tc:xacml:1.0:action\" AttributeId=\"mad\" DataTypeId=\"http://www.w3.org/2001/XMLSchema#string\"></MissingAttributeDetail></StatusDetail></Status></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		// Status with StatusDetail with valid detail with value when MissingAttribute

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		status = new StdMutableStatus();

+		status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE);

+		statusDetail = new StdMutableStatusDetail();

+		mad = new StdMutableMissingAttributeDetail();

+		mad.setAttributeId(new IdentifierImpl("mad"));

+		mad.setCategory(XACML3.ID_ACTION);

+		mad.setDataTypeId(DataTypes.DT_STRING.getId());	

+		mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "meh"));

+		statusDetail.addMissingAttributeDetail(mad);

+		status.setStatusDetail(statusDetail);

+		result.setStatus(status);

+		result.setDecision(Decision.INDETERMINATE);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/><StatusDetail><MissingAttributeDetail Category=\"urn:oasis:names:tc:xacml:1.0:action\" AttributeId=\"mad\" DataTypeId=\"http://www.w3.org/2001/XMLSchema#string\"><AttributeValue>meh</AttributeValue></MissingAttributeDetail></StatusDetail></Status></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		// Status with StatusDetail with array valid detail with value when MissingAttribute

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		status = new StdMutableStatus();

+		status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE);

+		statusDetail = new StdMutableStatusDetail();

+		mad = new StdMutableMissingAttributeDetail();

+		mad.setAttributeId(new IdentifierImpl("mad"));

+		mad.setCategory(XACML3.ID_ACTION);

+		mad.setDataTypeId(DataTypes.DT_STRING.getId());	

+		mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "meh"));

+		mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "nu?"));

+		statusDetail.addMissingAttributeDetail(mad);

+		status.setStatusDetail(statusDetail);

+		result.setStatus(status);

+		result.setDecision(Decision.INDETERMINATE);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/><StatusDetail><MissingAttributeDetail Category=\"urn:oasis:names:tc:xacml:1.0:action\" AttributeId=\"mad\" DataTypeId=\"http://www.w3.org/2001/XMLSchema#string\"><AttributeValue>meh</AttributeValue><AttributeValue>nu?</AttributeValue></MissingAttributeDetail></StatusDetail></Status></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		

+		// Status with StatusDetail with valid detail with Integer value when MissingAttribute

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		status = new StdMutableStatus();

+		status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE);

+		statusDetail = new StdMutableStatusDetail();

+		mad = new StdMutableMissingAttributeDetail();

+		mad.setAttributeId(new IdentifierImpl("mad"));

+		mad.setCategory(XACML3.ID_ACTION);

+		mad.setDataTypeId(DataTypes.DT_STRING.getId());	

+		mad.addAttributeValue(new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 1111));

+		statusDetail.addMissingAttributeDetail(mad);

+		status.setStatusDetail(statusDetail);

+		result.setStatus(status);

+		result.setDecision(Decision.INDETERMINATE);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/><StatusDetail><MissingAttributeDetail Category=\"urn:oasis:names:tc:xacml:1.0:action\" AttributeId=\"mad\" DataTypeId=\"http://www.w3.org/2001/XMLSchema#string\"><AttributeValue>1111</AttributeValue></MissingAttributeDetail></StatusDetail></Status></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		// Status with StatusDetail with array valid detail with Integer value when MissingAttribute

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		status = new StdMutableStatus();

+		status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE);

+		statusDetail = new StdMutableStatusDetail();

+		mad = new StdMutableMissingAttributeDetail();

+		mad.setAttributeId(new IdentifierImpl("mad"));

+		mad.setCategory(XACML3.ID_ACTION);

+		mad.setDataTypeId(DataTypes.DT_STRING.getId());	

+		mad.addAttributeValue(new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 1111));

+		mad.addAttributeValue(new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 2222));

+		statusDetail.addMissingAttributeDetail(mad);

+		status.setStatusDetail(statusDetail);

+		result.setStatus(status);

+		result.setDecision(Decision.INDETERMINATE);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/><StatusDetail><MissingAttributeDetail Category=\"urn:oasis:names:tc:xacml:1.0:action\" AttributeId=\"mad\" DataTypeId=\"http://www.w3.org/2001/XMLSchema#string\"><AttributeValue>1111</AttributeValue><AttributeValue>2222</AttributeValue></MissingAttributeDetail></StatusDetail></Status></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+//		StringNamespaceContext snc = new StringNamespaceContext();

+//		try {

+//			snc.add("defaultURI");

+//			snc.add("md", "referenceForMD");

+//		} catch (Exception e) {

+//			fail("unable to create NamespaceContext e="+e);

+//		}

+//		XPathExpressionWrapper xpathExpressionWrapper = new XPathExpressionWrapper(snc, "//md:record");

+//

+//TODO - assume that we will never try to pass back an XPathExpression in a MissingAttributeDetail - it doesn't make sense and is unclear how to put into XML

+//		// Status with StatusDetail with valid detail with XPathExpression value when MissingAttribute

+//		response = new StdMutableResponse();

+//		result = new StdMutableResult();

+//		status = new StdMutableStatus();

+//		status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE);

+//		statusDetail = new StdMutableStatusDetail();

+//		mad = new StdMutableMissingAttributeDetail();

+//		mad.setAttributeId(new IdentifierImpl("mad"));

+//		mad.setCategory(XACML3.ID_ACTION);

+//		mad.setDataTypeId(DataTypes.DT_STRING.getId());	

+//		mad.addAttributeValue(new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper, new IdentifierImpl("xpathCategoryId")));

+//		statusDetail.addMissingAttributeDetail(mad);

+//		status.setStatusDetail(statusDetail);

+//		result.setStatus(status);

+//		result.setDecision(Decision.INDETERMINATE);

+//		response.add(result);

+//		try {

+//			xmlResponse = DOMResponse.toString(response, false);

+//			assertEquals("{\"Response\":[{\"Status\":{\"StatusCode\":{\"Value\":\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"},\"StatusDetail\":\"<MissingAttributeDetail><AttributeValue>1111</AttributeValue><Category>urn:oasis:names:tc:xacml:1.0:action</Category><AttributeId>mad</AttributeId><DataType>http://www.w3.org/2001/XMLSchema#string</DataType></MissingAttributeDetail>\"},\"Decision\":\"Indeterminate\"}]}", xmlResponse);

+//		} catch (Exception e) {

+//			fail("operation failed, e="+e);

+//		}

+//		

+//		// Status with StatusDetail with array valid detail with XPathExpression value when MissingAttribute

+//		response = new StdMutableResponse();

+//		result = new StdMutableResult();

+//		status = new StdMutableStatus();

+//		status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE);

+//		statusDetail = new StdMutableStatusDetail();

+//		mad = new StdMutableMissingAttributeDetail();

+//		mad.setAttributeId(new IdentifierImpl("mad"));

+//		mad.setCategory(XACML3.ID_ACTION);

+//		mad.setDataTypeId(DataTypes.DT_STRING.getId());	

+//		mad.addAttributeValue(new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper, new IdentifierImpl("xpathCategoryId1")));

+//		mad.addAttributeValue(new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper, new IdentifierImpl("xpathCategoryId2")));

+//		statusDetail.addMissingAttributeDetail(mad);

+//		status.setStatusDetail(statusDetail);

+//		result.setStatus(status);

+//		result.setDecision(Decision.INDETERMINATE);

+//		response.add(result);

+//		try {

+//			xmlResponse = DOMResponse.toString(response, false);

+//			assertEquals("{\"Response\":[{\"Status\":{\"StatusCode\":{\"Value\":\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"},\"StatusDetail\":\"<MissingAttributeDetail><AttributeValue>1111</AttributeValue><AttributeValue>2222</AttributeValue><Category>urn:oasis:names:tc:xacml:1.0:action</Category><AttributeId>mad</AttributeId><DataType>http://www.w3.org/2001/XMLSchema#string</DataType></MissingAttributeDetail>\"},\"Decision\":\"Indeterminate\"}]}", xmlResponse);

+//		} catch (Exception e) {

+//			fail("operation failed, e="+e);

+//		}

+		

+//TODO - try with other data types, esp XPathExpression		

+		

+		// Status with StatusDetail with array valid detail with value when SyntaxError

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		status = new StdMutableStatus();

+		status.setStatusCode(StdStatusCode.STATUS_CODE_SYNTAX_ERROR);

+		statusDetail = new StdMutableStatusDetail();

+		mad = new StdMutableMissingAttributeDetail();

+		mad.setAttributeId(new IdentifierImpl("mad"));

+		mad.setCategory(XACML3.ID_ACTION);

+		mad.setDataTypeId(DataTypes.DT_STRING.getId());	

+		mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "meh"));

+		mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "nu?"));

+		statusDetail.addMissingAttributeDetail(mad);

+		status.setStatusDetail(statusDetail);

+		result.setStatus(status);

+		result.setDecision(Decision.INDETERMINATE);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			fail("Operation should throw exception");

+		} catch (DOMStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from object to XML: " + e);

+		}

+		

+		// Status with StatusDetail with array valid detail with value when ProcessingError

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		status = new StdMutableStatus();

+		status.setStatusCode(StdStatusCode.STATUS_CODE_PROCESSING_ERROR);

+		statusDetail = new StdMutableStatusDetail();

+		mad = new StdMutableMissingAttributeDetail();

+		mad.setAttributeId(new IdentifierImpl("mad"));

+		mad.setCategory(XACML3.ID_ACTION);

+		mad.setDataTypeId(DataTypes.DT_STRING.getId());	

+		mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "meh"));

+		mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "nu?"));

+		statusDetail.addMissingAttributeDetail(mad);

+		status.setStatusDetail(statusDetail);

+		result.setStatus(status);

+		result.setDecision(Decision.INDETERMINATE);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			fail("Operation should throw exception");

+		} catch (DOMStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from object to XML: " + e);

+		}

+		

+		

+		

+		// Status with nested child StatusCodes (child status containing child status containing...)

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		status = new StdMutableStatus();

+		StdStatusCode child1StatusCode = new StdStatusCode(new IdentifierImpl("child1StatusCode"));

+		StdStatusCode statusCode = new StdStatusCode(XACML3.ID_STATUS_OK, child1StatusCode);

+		status = new StdMutableStatus(statusCode);

+		status.setStatusMessage("I'm ok, you're ok");

+		result.setStatus(status);

+		result.setDecision(Decision.PERMIT);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:ok\"><StatusCode Value=\"child1StatusCode\"/></StatusCode><StatusMessage>I'm ok, you're ok</StatusMessage></Status></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		status = new StdMutableStatus();

+		StdStatusCode childChildChildStatusCode = new StdStatusCode(new IdentifierImpl("childChildChildStatusCode"));

+		StdStatusCode childChildStatusCode = new StdStatusCode(new IdentifierImpl("childChildStatusCode"), childChildChildStatusCode);

+		child1StatusCode = new StdStatusCode(new IdentifierImpl("child1StatusCode"), childChildStatusCode);

+		statusCode = new StdStatusCode(XACML3.ID_STATUS_OK, child1StatusCode);

+		status = new StdMutableStatus(statusCode);

+		status.setStatusMessage("I'm ok, you're ok");

+		result.setStatus(status);

+		result.setDecision(Decision.PERMIT);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:ok\"><StatusCode Value=\"child1StatusCode\"><StatusCode Value=\"childChildStatusCode\"><StatusCode Value=\"childChildChildStatusCode\"/></StatusCode></StatusCode></StatusCode><StatusMessage>I'm ok, you're ok</StatusMessage></Status></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+

+	}

+

+

+	

+	@Test

+	public void testObligations() {

+		

+		// create an XPathExpression for use later

+		StringNamespaceContext snc = new StringNamespaceContext();

+		try {

+			snc.add("defaultURI");

+			snc.add("md", "referenceForMD");

+		} catch (Exception e) {

+			fail("unable to create NamespaceContext e="+e);

+		}

+		XPathExpressionWrapper xpathExpressionWrapper = new XPathExpressionWrapper(snc, "//md:record");

+		XPathExpressionWrapper xpathExpressionWrapper2 = new XPathExpressionWrapper(snc, "//md:hospital");

+		

+		StdMutableObligation obligation;

+

+		// test Obligation single decision no attributes

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		obligation = new StdMutableObligation();

+		obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION);

+		result.addObligation(obligation);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Obligations><Obligation ObligationId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"></Obligation></Obligations></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		// obligation missing Id

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		obligation = new StdMutableObligation();

+		result.addObligation(obligation);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			fail("Operation should throw exception");

+		} catch (DOMStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from object to XML: " + e);

+		}

+		

+		

+		

+		//	AttributeAssignment	- with AttributeId, Value,  Category, DataType, Issuer

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		obligation = new StdMutableObligation();

+		obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION);

+		obligation.addAttributeAssignment(new StdMutableAttributeAssignment(

+				XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, 

+				XACML3.ID_SUBJECT, 

+				"obligation-issuer1", 

+				new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart")));

+		result.addObligation(obligation);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Obligations><Obligation ObligationId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeAssignment></Obligation></Obligations></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		

+		//	AttributeAssignment	- with AttributeId, Value, no Category, DataType, Issuer

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		obligation = new StdMutableObligation();

+		obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION);

+		obligation.addAttributeAssignment(new StdMutableAttributeAssignment(

+				null, 

+				XACML3.ID_SUBJECT, 

+				"obligation-issuer1", 

+				new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart")));

+		result.addObligation(obligation);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Obligations><Obligation ObligationId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeAssignment></Obligation></Obligations></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		//	AttributeAssignment	- Missing AttributeId

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		obligation = new StdMutableObligation();

+		obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION);

+		obligation.addAttributeAssignment(new StdMutableAttributeAssignment(

+				XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, 

+				null, 

+				"obligation-issuer1", 

+				new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart")));

+		result.addObligation(obligation);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			fail("Operation should throw exception");

+		} catch (DOMStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from object to XML: " + e);

+		}

+		

+		//	AttributeAssignment	- Missing Value

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		obligation = new StdMutableObligation();

+		obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION);

+		obligation.addAttributeAssignment(new StdMutableAttributeAssignment(

+				XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, 

+				XACML3.ID_SUBJECT, 

+				"obligation-issuer1", 

+				null));

+		result.addObligation(obligation);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			fail("Operation should throw exception");

+		} catch (DOMStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from object to XML: " + e);

+		}

+		

+		// AttributeAssignment - missing required DataType (Different than JSON where DataType is optional with default String)

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		obligation = new StdMutableObligation();

+		obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION);

+		obligation.addAttributeAssignment(new StdMutableAttributeAssignment(

+				XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, 

+				XACML3.ID_SUBJECT, 

+				"obligation-issuer1", 

+				new StdAttributeValue<String>(null, "Bart")));

+		result.addObligation(obligation);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			fail("Operation should throw exception");

+		} catch (DOMStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from object to XML: " + e);

+		}

+		

+		// AttributeAssignment - missing issuer

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		obligation = new StdMutableObligation();

+		obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION);

+		obligation.addAttributeAssignment(new StdMutableAttributeAssignment(

+				XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, 

+				XACML3.ID_SUBJECT, 

+				null, 

+				new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart")));

+		result.addObligation(obligation);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Obligations><Obligation ObligationId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeAssignment></Obligation></Obligations></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		// AttributeAssignment - Integer type

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		obligation = new StdMutableObligation();

+		obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION);

+		obligation.addAttributeAssignment(new StdMutableAttributeAssignment(

+				XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, 

+				XACML3.ID_SUBJECT, 

+				null, 

+				new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 1111)));

+		result.addObligation(obligation);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Obligations><Obligation ObligationId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#integer\">1111</AttributeAssignment></Obligation></Obligations></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		

+		// AttributeAssignment - XPathExpression type

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		obligation = new StdMutableObligation();

+		obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION);

+		obligation.addAttributeAssignment(new StdMutableAttributeAssignment(

+				XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, 

+				XACML3.ID_SUBJECT, 

+				null, 

+				new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper, new IdentifierImpl("SimpleXPathCategory"))));

+		result.addObligation(obligation);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Obligations><Obligation ObligationId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\" xmlns:md=\"referenceForMD\" xmlns=\"defaultURI\">//md:record</AttributeAssignment></Obligation></Obligations></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		

+		

+

+		//

+		// Technically arrays cannot occur in Obligations and Advice elements.  The XML spec boils down to the following definition:

+		//		<Obligation (attributes of the obligation) >

+		//			<AttributeAssignment (attributes of this assignment) >value</AttributeAssignment>

+		//			<AttributeAssignment (attributes of this assignment) >value</AttributeAssignment>

+		//			:

+		//		</Obligation

+		//	which means that there may be multiple AttributeAssignments but each one has only one value.

+		//	This differs from the Attributes section in which each <Attribute> may have multiple <AttributeValue> elements.

+		// For Obligations and Advice we can simulate an array by having multiple AttributeAssignment elements with the same Category, Id and Issuer.

+		//

+

+		

+		//	AttributeAssignment	- Multiple values with same Category and Id (one way of doing array)

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		obligation = new StdMutableObligation();

+		obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION);

+		obligation.addAttributeAssignment(new StdMutableAttributeAssignment(

+				XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, 

+				XACML3.ID_SUBJECT, 

+				"obligation-issuer1", 

+				new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart")));

+		obligation.addAttributeAssignment(new StdMutableAttributeAssignment(

+				XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, 

+				XACML3.ID_SUBJECT, 

+				"obligation-issuer1", 

+				new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Lisa")));

+		obligation.addAttributeAssignment(new StdMutableAttributeAssignment(

+				XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, 

+				XACML3.ID_SUBJECT, 

+				"obligation-issuer1", 

+				new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Maggie")));

+		result.addObligation(obligation);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Obligations><Obligation ObligationId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Lisa</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Maggie</AttributeAssignment></Obligation></Obligations></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		

+		//	AttributeAssignment	- Multiple Integer values with same Category and Id (one way of doing array)

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		obligation = new StdMutableObligation();

+		obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION);

+		obligation.addAttributeAssignment(new StdMutableAttributeAssignment(

+				XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, 

+				XACML3.ID_SUBJECT, 

+				"obligation-issuer1", 

+				new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 1111)));

+		obligation.addAttributeAssignment(new StdMutableAttributeAssignment(

+				XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, 

+				XACML3.ID_SUBJECT, 

+				"obligation-issuer1", 

+				new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 2222)));

+		obligation.addAttributeAssignment(new StdMutableAttributeAssignment(

+				XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, 

+				XACML3.ID_SUBJECT, 

+				"obligation-issuer1", 

+				new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 3333)));

+		result.addObligation(obligation);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Obligations><Obligation ObligationId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#integer\">1111</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#integer\">2222</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#integer\">3333</AttributeAssignment></Obligation></Obligations></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		

+		// Multiple XPathExpression values with same Category and Id (one way of doing array)

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		obligation = new StdMutableObligation();

+		obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION);

+		obligation.addAttributeAssignment(new StdMutableAttributeAssignment(

+				XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, 

+				XACML3.ID_SUBJECT, 

+				null, 

+				new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper, new IdentifierImpl("SimpleXPathCategory"))));

+		obligation.addAttributeAssignment(new StdMutableAttributeAssignment(

+				XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, 

+				XACML3.ID_SUBJECT, 

+				null, 

+				new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper2, new IdentifierImpl("SimpleXPathCategory"))));

+		result.addObligation(obligation);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Obligations><Obligation ObligationId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\" xmlns:md=\"referenceForMD\" xmlns=\"defaultURI\">//md:record</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\" xmlns:md=\"referenceForMD\" xmlns=\"defaultURI\">//md:hospital</AttributeAssignment></Obligation></Obligations></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}	

+		

+	}

+	

+	

+	

+	

+	@Test

+	public void testAdvice() {

+		

+		// create an XPathExpression for use later

+		StringNamespaceContext snc = new StringNamespaceContext();

+		try {

+			snc.add("defaultURI");

+			snc.add("md", "referenceForMD");

+		} catch (Exception e) {

+			fail("unable to create NamespaceContext e="+e);

+		}

+		XPathExpressionWrapper xpathExpressionWrapper = new XPathExpressionWrapper(snc, "//md:record");

+		XPathExpressionWrapper xpathExpressionWrapper2 = new XPathExpressionWrapper(snc, "//md:hospital");

+		

+		StdMutableAdvice Advice;

+

+		// test Advice single decision no attributes

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		Advice = new StdMutableAdvice();

+		Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION);

+		result.addAdvice(Advice);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><AssociatedAdvice><Advice AdviceId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"></Advice></AssociatedAdvice></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		// Advice missing Id

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		Advice = new StdMutableAdvice();

+		result.addAdvice(Advice);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			fail("Operation should throw exception");

+		} catch (DOMStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from object to XML: " + e);

+		}

+		

+		

+		

+		//	AttributeAssignment	- with AttributeId, Value,  Category, DataType, Issuer

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		Advice = new StdMutableAdvice();

+		Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION);

+		Advice.addAttributeAssignment(new StdMutableAttributeAssignment(

+				XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, 

+				XACML3.ID_SUBJECT, 

+				"Advice-issuer1", 

+				new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart")));

+		result.addAdvice(Advice);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><AssociatedAdvice><Advice AdviceId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeAssignment></Advice></AssociatedAdvice></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		

+		//	AttributeAssignment	- with AttributeId, Value, no Category, DataType, Issuer

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		Advice = new StdMutableAdvice();

+		Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION);

+		Advice.addAttributeAssignment(new StdMutableAttributeAssignment(

+				null, 

+				XACML3.ID_SUBJECT, 

+				"Advice-issuer1", 

+				new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart")));

+		result.addAdvice(Advice);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><AssociatedAdvice><Advice AdviceId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeAssignment></Advice></AssociatedAdvice></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		//	AttributeAssignment	- Missing AttributeId

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		Advice = new StdMutableAdvice();

+		Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION);

+		Advice.addAttributeAssignment(new StdMutableAttributeAssignment(

+				XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, 

+				null, 

+				"Advice-issuer1", 

+				new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart")));

+		result.addAdvice(Advice);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			fail("Operation should throw exception");

+		} catch (DOMStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from object to XML: " + e);

+		}

+		

+		//	AttributeAssignment	- Missing Value

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		Advice = new StdMutableAdvice();

+		Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION);

+		Advice.addAttributeAssignment(new StdMutableAttributeAssignment(

+				XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, 

+				XACML3.ID_SUBJECT, 

+				"Advice-issuer1", 

+				null));

+		result.addAdvice(Advice);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			fail("Operation should throw exception");

+		} catch (DOMStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from object to XML: " + e);

+		}

+		

+		// AttributeAssignment - missing Required DataType (Different than JSON where DataType is optional with default String)

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		Advice = new StdMutableAdvice();

+		Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION);

+		Advice.addAttributeAssignment(new StdMutableAttributeAssignment(

+				XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, 

+				XACML3.ID_SUBJECT, 

+				"Advice-issuer1", 

+				new StdAttributeValue<String>(null, "Bart")));

+		result.addAdvice(Advice);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			fail("Operation should throw exception");

+		} catch (DOMStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from object to XML: " + e);

+		}

+		

+		// AttributeAssignment - missing issuer

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		Advice = new StdMutableAdvice();

+		Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION);

+		Advice.addAttributeAssignment(new StdMutableAttributeAssignment(

+				XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, 

+				XACML3.ID_SUBJECT, 

+				null, 

+				new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart")));

+		result.addAdvice(Advice);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><AssociatedAdvice><Advice AdviceId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeAssignment></Advice></AssociatedAdvice></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		// AttributeAssignment - Integer type

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		Advice = new StdMutableAdvice();

+		Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION);

+		Advice.addAttributeAssignment(new StdMutableAttributeAssignment(

+				XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, 

+				XACML3.ID_SUBJECT, 

+				null, 

+				new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 1111)));

+		result.addAdvice(Advice);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><AssociatedAdvice><Advice AdviceId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#integer\">1111</AttributeAssignment></Advice></AssociatedAdvice></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		

+		// AttributeAssignment - XPathExpression type

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		Advice = new StdMutableAdvice();

+		Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION);

+		Advice.addAttributeAssignment(new StdMutableAttributeAssignment(

+				XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, 

+				XACML3.ID_SUBJECT, 

+				null, 

+				new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper, new IdentifierImpl("SimpleXPathCategory"))));

+		result.addAdvice(Advice);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><AssociatedAdvice><Advice AdviceId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\" xmlns:md=\"referenceForMD\" xmlns=\"defaultURI\">//md:record</AttributeAssignment></Advice></AssociatedAdvice></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		

+		

+

+		//

+		// Technically arrays cannot occur in Obligations and Advice elements.  The XML spec boils down to the following definition:

+		//		<Obligation (attributes of the obligation) >

+		//			<AttributeAssignment (attributes of this assignment) >value</AttributeAssignment>

+		//			<AttributeAssignment (attributes of this assignment) >value</AttributeAssignment>

+		//			:

+		//		</Obligation

+		//	which means that there may be multiple AttributeAssignments but each one has only one value.

+		//	This differs from the Attributes section in which each <Attribute> may have multiple <AttributeValue> elements.

+		// For Obligations and Advice we can simulate an array by having multiple AttributeAssignment elements with the same Category, Id and Issuer.

+		//

+		

+		//	AttributeAssignment	- Multiple values with same Category and Id (one way of doing array)

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		Advice = new StdMutableAdvice();

+		Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION);

+		Advice.addAttributeAssignment(new StdMutableAttributeAssignment(

+				XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, 

+				XACML3.ID_SUBJECT, 

+				"Advice-issuer1", 

+				new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart")));

+		Advice.addAttributeAssignment(new StdMutableAttributeAssignment(

+				XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, 

+				XACML3.ID_SUBJECT, 

+				"Advice-issuer1", 

+				new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Lisa")));

+		Advice.addAttributeAssignment(new StdMutableAttributeAssignment(

+				XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, 

+				XACML3.ID_SUBJECT, 

+				"Advice-issuer1", 

+				new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Maggie")));

+		result.addAdvice(Advice);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><AssociatedAdvice><Advice AdviceId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Lisa</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Maggie</AttributeAssignment></Advice></AssociatedAdvice></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		

+		//	AttributeAssignment	- Multiple Integer values with same Category and Id (one way of doing array)

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		Advice = new StdMutableAdvice();

+		Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION);

+		Advice.addAttributeAssignment(new StdMutableAttributeAssignment(

+				XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, 

+				XACML3.ID_SUBJECT, 

+				"Advice-issuer1", 

+				new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 1111)));

+		Advice.addAttributeAssignment(new StdMutableAttributeAssignment(

+				XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, 

+				XACML3.ID_SUBJECT, 

+				"Advice-issuer1", 

+				new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 2222)));

+		Advice.addAttributeAssignment(new StdMutableAttributeAssignment(

+				XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, 

+				XACML3.ID_SUBJECT, 

+				"Advice-issuer1", 

+				new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 3333)));

+		result.addAdvice(Advice);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><AssociatedAdvice><Advice AdviceId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#integer\">1111</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#integer\">2222</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#integer\">3333</AttributeAssignment></Advice></AssociatedAdvice></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		

+		// Multiple XPathExpression values with same Category and Id (one way of doing array)

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		Advice = new StdMutableAdvice();

+		Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION);

+		Advice.addAttributeAssignment(new StdMutableAttributeAssignment(

+				XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, 

+				XACML3.ID_SUBJECT, 

+				null, 

+				new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper, new IdentifierImpl("SimpleXPathCategory"))));

+		Advice.addAttributeAssignment(new StdMutableAttributeAssignment(

+				XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, 

+				XACML3.ID_SUBJECT, 

+				null, 

+				new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper2, new IdentifierImpl("SimpleXPathCategory"))));

+		result.addAdvice(Advice);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><AssociatedAdvice><Advice AdviceId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\" xmlns:md=\"referenceForMD\" xmlns=\"defaultURI\">//md:record</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\" xmlns:md=\"referenceForMD\" xmlns=\"defaultURI\">//md:hospital</AttributeAssignment></Advice></AssociatedAdvice></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+	}

+	

+	

+	

+	

+	

+

+	

+	

+

+	

+	// Attributes tests

+	@Test

+	public void testAttributes() {

+		

+		// create an XPathExpression for use later

+		StringNamespaceContext snc = new StringNamespaceContext();

+		try {

+			snc.add("defaultURI");

+			snc.add("md", "referenceForMD");

+		} catch (Exception e) {

+			fail("unable to create NamespaceContext e="+e);

+		}

+		XPathExpressionWrapper xpathExpressionWrapper = new XPathExpressionWrapper(snc, "//md:record");

+		

+		

+		Identifier categoryIdentifier;

+		List<Attribute> attrList = new ArrayList<Attribute>();

+		StdMutableAttribute mutableAttribute;

+		

+		// Attr list with no entries

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		categoryIdentifier = new IdentifierImpl("firstCategory");

+		attrList.clear();

+		result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList));

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"></Attributes></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		

+		// one Attribute

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		categoryIdentifier = new IdentifierImpl("firstCategory");

+		attrList.clear();

+				attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true));

+		result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList));

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		// multiple attributes

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		categoryIdentifier = new IdentifierImpl("firstCategory");

+		attrList.clear();

+			attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true));

+			attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent2"), new StdAttributeValue<String>(DataTypes.DT_YEARMONTHDURATION.getId(), "P10Y4M"), "BIssue", true));

+			attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent3"), new StdAttributeValue<Double>(DataTypes.DT_DOUBLE.getId(), 765.432), "CIssue", true));

+			attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent4"), new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), true), "DIssue", true));

+			attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent5"), new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567), "EIssue", true));

+		result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList));

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent2\" Issuer=\"BIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#yearMonthDuration\">P10Y4M</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent3\" Issuer=\"CIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#double\">765.432</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent4\" Issuer=\"DIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#boolean\">true</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent5\" Issuer=\"EIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		// IncludeInResult=false/true

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		categoryIdentifier = new IdentifierImpl("firstCategory");

+		attrList.clear();

+				attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", false));

+		result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList));

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"></Attributes></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		// Missing AttributeId (mandatory)

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		categoryIdentifier = new IdentifierImpl("firstCategory");

+		attrList.clear();

+				attrList.add(new StdAttribute(categoryIdentifier, null, new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true));

+		result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList));

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			fail("Operation should throw exception");

+		} catch (DOMStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from object to XML: " + e);

+		}

+		

+		// Missing mandatory Value

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		categoryIdentifier = new IdentifierImpl("firstCategory");

+		attrList.clear();

+				attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), null), "AIssue", true));

+		result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList));

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			fail("Operation should throw exception");

+		} catch (DOMStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from object to XML: " + e);

+		}

+		

+		// Missing optional Issuer

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		categoryIdentifier = new IdentifierImpl("firstCategory");

+		attrList.clear();

+				attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), null, true));

+		result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList));

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		// missing required DataType (different from JSON where DataType is optional and assumed to be String)

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		categoryIdentifier = new IdentifierImpl("firstCategory");

+		attrList.clear();

+				attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(null, "Apu"), "AIssue", true));

+		result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList));

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			fail("Operation should throw exception");

+		} catch (DOMStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from object to XML: " + e);

+		}

+		

+		// same id, same type different issuer

+		// (This is not an array of values because Issuer is different)

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		categoryIdentifier = new IdentifierImpl("firstCategory");

+		attrList.clear();

+			attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true));

+			attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart"), "BIssue", true));

+			attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Simpson"), "CIssue", true));

+		result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList));

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"BIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"CIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Simpson</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		// same id, same type same issuer

+		// (This is an array of values)

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		categoryIdentifier = new IdentifierImpl("firstCategory");

+		attrList.clear();

+			attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true));

+			attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart"), "AIssue", true));

+			attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Simpson"), "AIssue", true));

+		result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList));

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Simpson</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		// same Id, different types, same issuer

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		categoryIdentifier = new IdentifierImpl("firstCategory");

+		attrList.clear();

+			attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true));

+			attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_YEARMONTHDURATION.getId(), "P10Y4M"), "AIssue", true));

+			attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<Double>(DataTypes.DT_DOUBLE.getId(), 765.432), "AIssue", true));

+			attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), true), "AIssue", true));

+			attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567), "AIssue", true));

+			attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567), "AIssue", true));

+		result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList));

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#yearMonthDuration\">P10Y4M</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#double\">765.432</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#boolean\">true</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		// same Id, different types, different issuer

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		categoryIdentifier = new IdentifierImpl("firstCategory");

+		attrList.clear();

+			attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true));

+			attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_YEARMONTHDURATION.getId(), "P10Y4M"), "BIssue", true));

+			attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<Double>(DataTypes.DT_DOUBLE.getId(), 765.432), "CIssue", true));

+			attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), true), "DIssue", true));

+			attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567), "EIssue", true));

+			attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567), null, true));

+		result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList));

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"BIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#yearMonthDuration\">P10Y4M</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"CIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#double\">765.432</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"DIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#boolean\">true</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"EIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+

+		// different Id, different types, same issuer

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		categoryIdentifier = new IdentifierImpl("firstCategory");

+		attrList.clear();

+			attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true));

+			attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent2"), new StdAttributeValue<String>(DataTypes.DT_YEARMONTHDURATION.getId(), "AIssue"), "BIssue", true));

+			attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent3"), new StdAttributeValue<Double>(DataTypes.DT_DOUBLE.getId(), 765.432), "AIssue", true));

+			attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent4"), new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), true), "AIssue", true));

+			attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent5"), new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567), "AIssue", true));

+		result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList));

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent2\" Issuer=\"BIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#yearMonthDuration\">AIssue</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent3\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#double\">765.432</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent4\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#boolean\">true</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent5\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		

+		// one Attribute of type XPathExpression (the only complex data type)

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		categoryIdentifier = new IdentifierImpl("firstCategory");

+		attrList.clear();

+				attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper, new IdentifierImpl("xpathCategory")), "AIssue", true));

+		result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList));

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\" XPathCategory=\"xpathCategory\">//md:record</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		

+		// multiple sets of values

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		categoryIdentifier = new IdentifierImpl("firstCategory");

+		attrList.clear();

+		attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true));

+		attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent2"), new StdAttributeValue<String>(DataTypes.DT_YEARMONTHDURATION.getId(), "P10Y4M"), "BIssue", false));

+		attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent3"), new StdAttributeValue<Double>(DataTypes.DT_DOUBLE.getId(), 765.432), "CIssue", true));

+		attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent4"), new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), true), "DIssue", true));

+		attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent5"), new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567), "EIssue", true));

+		attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrNoIssuer"), new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567), null, true));

+		result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList));

+		categoryIdentifier = new IdentifierImpl("secondCategory");

+		Attribute[] secondAttrList = {

+				new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent12"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu2"), "AIssue2", true),

+				new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent22"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Abc2"), "BIssue2", false),

+				new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent32"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Der2"), "CIssue2", true) };

+		result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, Arrays.asList(secondAttrList)));

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent3\" Issuer=\"CIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#double\">765.432</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent4\" Issuer=\"DIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#boolean\">true</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent5\" Issuer=\"EIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrNoIssuer\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute></Attributes><Attributes Category=\"secondCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent12\" Issuer=\"AIssue2\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu2</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent32\" Issuer=\"CIssue2\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Der2</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		

+		// array of values - same type

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		attrList.clear();

+		categoryIdentifier = new IdentifierImpl("firstCategory");

+		mutableAttribute = new StdMutableAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), (Collection<AttributeValue<?>>)null, "AIssue", true);

+

+			mutableAttribute.addValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"));

+			mutableAttribute.addValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart"));

+			mutableAttribute.addValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Homer"));

+			mutableAttribute.addValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Ned"));

+			

+		attrList.add(mutableAttribute);

+		result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList));

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeValue><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Homer</AttributeValue><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Ned</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		

+		// array of values - compatible different types

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		attrList.clear();

+		categoryIdentifier = new IdentifierImpl("firstCategory");

+		mutableAttribute = new StdMutableAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), (Collection<AttributeValue<?>>)null, "AIssue", true);

+

+			mutableAttribute.addValue(new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567));

+			mutableAttribute.addValue(new StdAttributeValue<Double>(DataTypes.DT_DOUBLE.getId(), 765.432));

+			mutableAttribute.addValue(new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567));

+		attrList.add(mutableAttribute);

+		result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList));

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#double\">765.432</AttributeValue><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		

+		// array of values - incompatible different types (Different from JSON because these are not part of an array in XML, just separate values)

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		attrList.clear();

+		categoryIdentifier = new IdentifierImpl("firstCategory");

+		mutableAttribute = new StdMutableAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), (Collection<AttributeValue<?>>)null, "AIssue", true);

+

+			mutableAttribute.addValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"));

+			mutableAttribute.addValue(new StdAttributeValue<String>(DataTypes.DT_YEARMONTHDURATION.getId(), "P10Y4M"));

+			mutableAttribute.addValue(new StdAttributeValue<Double>(DataTypes.DT_DOUBLE.getId(), 765.432));

+			mutableAttribute.addValue(new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), true));

+			mutableAttribute.addValue(new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567));

+			mutableAttribute.addValue(new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567));

+		attrList.add(mutableAttribute);

+		result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList));

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#yearMonthDuration\">P10Y4M</AttributeValue><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#double\">765.432</AttributeValue><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#boolean\">true</AttributeValue><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+	}

+	

+	

+	

+	

+	

+	// PolicyIdentifier tests

+	@Test

+	public void testPolicyIdentifier() {

+		

+		StdIdReference policyIdentifier1 = null;

+		StdIdReference policyIdentifier2 = null;

+		StdIdReference policySetIdentifier1 = null;

+		StdIdReference policySetIdentifier2 = null;

+		

+		// multiple PolicyIdentifiers of both types

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		try {

+			policyIdentifier1 = new StdIdReference(new IdentifierImpl("idRef1"), StdVersion.newInstance("1.2.3"));

+			policyIdentifier2 = new StdIdReference(new IdentifierImpl("idRef2_NoVersion"));

+			policySetIdentifier1 = new StdIdReference(new IdentifierImpl("idSetRef1"), StdVersion.newInstance("4.5.6.7.8.9.0"));

+			policySetIdentifier2 = new StdIdReference(new IdentifierImpl("idSetRef2_NoVersion"));

+		} catch (ParseException e1) {

+			fail("creating policyIds, e="+e1);

+		}

+		result.addPolicyIdentifier(policyIdentifier1);

+		result.addPolicyIdentifier(policyIdentifier2);

+		result.addPolicySetIdentifier(policySetIdentifier1);

+		result.addPolicySetIdentifier(policySetIdentifier2);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><PolicyIdentifierList><PolicyIdReference Version=\"1.2.3\">idRef1</PolicyIdReference><PolicyIdReference>idRef2_NoVersion</PolicyIdReference><PolicySetIdReference Version=\"4.5.6.7.8.9.0\">idSetRef1</PolicySetIdReference><PolicySetIdReference>idSetRef2_NoVersion</PolicySetIdReference></PolicyIdentifierList></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		

+		// PolicyIdentifier exists but has no IdReferences

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		policyIdentifier1 = null;

+		result.addPolicyIdentifier(policyIdentifier1);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			fail("Operation should throw exception");

+		} catch (DOMStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from object to XML: " + e);

+		}

+		

+		// PolicySetIdentifier exists but has not IdReferences

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		policySetIdentifier1 = null;

+		result.addPolicyIdentifier(policySetIdentifier1);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			fail("Operation should throw exception");

+		} catch (DOMStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from object to XML: " + e);

+		}

+		

+		// PolicyIdentifier with PolicyIdReference and no PolicySetIdReference

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		try {

+			policyIdentifier1 = new StdIdReference(new IdentifierImpl("idRef1"), StdVersion.newInstance("1.2.3"));

+		} catch (ParseException e1) {

+			fail("creating policyIds, e="+e1);

+		}

+		result.addPolicyIdentifier(policyIdentifier1);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><PolicyIdentifierList><PolicyIdReference Version=\"1.2.3\">idRef1</PolicyIdReference></PolicyIdentifierList></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		

+		

+		// PolicyIdentifier with no PolicyIdReference and with PolicySetIdReference

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+		try {

+			policySetIdentifier1 = new StdIdReference(new IdentifierImpl("idSetRef1"), StdVersion.newInstance("4.5.6.7.8.9.0"));

+		} catch (ParseException e1) {

+			fail("creating policyIds, e="+e1);

+		}

+		result.addPolicySetIdentifier(policySetIdentifier1);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><PolicyIdentifierList><PolicySetIdReference Version=\"4.5.6.7.8.9.0\">idSetRef1</PolicySetIdReference></PolicyIdentifierList></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+		

+		

+		// IdReferences without version

+		response = new StdMutableResponse();

+		result = new StdMutableResult();

+		result.setDecision(Decision.PERMIT);

+

+			policyIdentifier1 = new StdIdReference(new IdentifierImpl("idRef1"), null);

+			policyIdentifier2 = new StdIdReference(new IdentifierImpl("idRef2_NoVersion"));

+			policySetIdentifier1 = new StdIdReference(new IdentifierImpl("idSetRef1"));

+			policySetIdentifier2 = new StdIdReference(new IdentifierImpl("idSetRef2_NoVersion"));

+

+		result.addPolicyIdentifier(policyIdentifier1);

+		result.addPolicyIdentifier(policyIdentifier2);

+		result.addPolicySetIdentifier(policySetIdentifier1);

+		result.addPolicySetIdentifier(policySetIdentifier2);

+		response.add(result);

+		try {

+			xmlResponse = DOMResponse.toString(response, false);

+			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><PolicyIdentifierList><PolicyIdReference>idRef1</PolicyIdReference><PolicyIdReference>idRef2_NoVersion</PolicyIdReference><PolicySetIdReference>idSetRef1</PolicySetIdReference><PolicySetIdReference>idSetRef2_NoVersion</PolicySetIdReference></PolicyIdentifierList></Result></Response>", xmlResponse);

+		} catch (Exception e) {

+			fail("operation failed, e="+e);

+		}

+	}

+

+

+//TODO - the XML spec implies that the Result Attributes may include the Content (It is part of the UML)

+	

+	

+	// test indentation???

+	

+	

+}

+

+

+/*

+Place to edit long strings ouput from tests

+

+

+Expected

+<?xml version="1.0" encoding="UTF-8"?><Response xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd"><Result><Decision>Permit</Decision></Result></Response>

+<?xml version="1.0" encoding="UTF-8"?><Response xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd"><Result><Decision>Permit</Decision></Result></Response>

+Actual

+

+

+

+ */

+

+

+

+

+

+

+

+

+

+

+

+

+

diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionAccessPermittedTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionAccessPermittedTest.java
new file mode 100755
index 0000000..c7844a8
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionAccessPermittedTest.java
@@ -0,0 +1,497 @@
+package com.att.research.xacmlatt.pdp.std.functions;

+

+import com.att.research.xacml.api.Request;

+import com.att.research.xacml.api.XACML3;

+import com.att.research.xacml.std.StdMutableRequest;

+import com.att.research.xacml.std.datatypes.DataTypes;

+import com.att.research.xacml.std.dom.DOMRequest;

+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue;

+import com.att.research.xacmlatt.pdp.std.StdEvaluationContext;

+import com.att.research.xacmlatt.pdp.std.StdFunctions;

+import org.junit.Ignore;

+import org.junit.Test;

+

+import javax.xml.namespace.NamespaceContext;

+import java.io.BufferedWriter;

+import java.io.File;

+import java.io.FileWriter;

+import java.util.ArrayList;

+import java.util.Iterator;

+import java.util.List;

+

+import static org.junit.Assert.*;

+

+/**

+ * Test of PDP Functions (See XACML core spec section A.3)

+ * 

+ * TO RUN - use jUnit

+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test

+ * 

+ * NOT IMPLEMENTED!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

+ * This function is not yet implemented so these tests intentionally fail.

+ * 

+ * @author glenngriffin

+ *

+ */

+public class FunctionDefinitionAccessPermittedTest {

+	

+	//

+	// Strings for the Request contents

+	//

+	

+	String reqStrMainStart = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" 

+			+ "<Request xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" 

+			+ " http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"" 

+			+ " ReturnPolicyIdList=\"false\""

+			+ " CombinedDecision=\"false\""

+			+ " xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\""

+			+ " xmlns:md=\"http://www.medico.com/schemas/record\""

+			+ " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"

+			+ "	<Attributes Category=\"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\">"

+			+ "		<Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject:subject-id\">"

+			+ "			<AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Julius Hibbert</AttributeValue>"

+			+ "		</Attribute>"

+			+ "		<Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:2.0:conformance-test:test-attr\">"

+			+ "			<AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">   This  is IT!  </AttributeValue>"

+			+ "		</Attribute>"

+			+ "		<Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:2.0:conformance-test:test-attr\">"

+			+ "			<AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">   This  is IT!  </AttributeValue>"

+			+ "		</Attribute>"

+			+ "</Attributes>";

+	      

+	String reqStrResourceStart =   "<Attributes Category=\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\">";

+

+	String reqStrMdRecordSimpson =

+			"<md:record>" +

+                "<md:hospital_info>" +

+                   "<md:name>ABC Hospital</md:name>" +

+                    "<md:department>Surgery</md:department>" +

+                "</md:hospital_info>" +

+                "<md:patient_info>" +

+                    "<md:name>Bart Simpson</md:name>" +

+                    "<md:age>60</md:age>" +

+                    "<md:sex>male</md:sex>" +

+                    "<md:health_insurance>123456</md:health_insurance>" +

+                "</md:patient_info>" +

+                "<md:diagnosis_info>" +

+                    "<md:diagnosis>" +

+                        "<md:item type=\"primary\">Gastric Cancer</md:item>" +

+                        "<md:item type=\"secondary\">Hyper tension</md:item>" +

+                    "</md:diagnosis>" +

+                    "<md:pathological_diagnosis>" +

+                        "<md:diagnosis>" +

+                            "<md:item type=\"primary\">Well differentiated adeno carcinoma</md:item>" +

+                        "</md:diagnosis>" +

+                        "<md:date>2000-10-05</md:date>" +

+                        "<md:malignancy type=\"yes\"/>" +

+                    "</md:pathological_diagnosis>" +

+                "</md:diagnosis_info>" +             

+           " </md:record>";

+	String reqStrContentMdRecordSimpson = "<Content>" + reqStrMdRecordSimpson + "</Content>";

+	String reqStrMalformedContent = 

+			" <Content>" +

+					"<md:record>" +

+		                "<md:hospital_info>" +

+		                   "<md:name>ABC Hospital</md:name>" +

+		                        "<md:malignancy type=\"yes\"/>" +

+		    "</Content>";

+	String reqStrMdRecordSpringer =

+				"<md:record>" +

+	                "<md:hospital_info>" +

+	                   "<md:name>XYZ Hospital</md:name>" +

+	                    "<md:department>Surgery</md:department>" +

+	                "</md:hospital_info>" +

+	                "<md:patient_info>" +

+	                    "<md:name>Jerry Springer</md:name>" +

+	                    "<md:age>65</md:age>" +

+	                    "<md:sex>male</md:sex>" +

+	                    "<md:health_insurance>765432</md:health_insurance>" +

+	                "</md:patient_info>" +

+	                "<md:diagnosis_info>" +

+	                    "<md:diagnosis>" +

+	                        "<md:item type=\"primary\">Hyatal Hernia</md:item>" +

+	                        "<md:item type=\"secondary\">Diabetes</md:item>" +

+	                        "<md:item type=\"tertiary\">Neuronal Collapse</md:item>" +

+	                    "</md:diagnosis>" +

+	                    "<md:pathological_diagnosis>" +

+	                        "<md:diagnosis>" +

+	                            "<md:item type=\"primary\">We have no idea</md:item>" +

+	                        "</md:diagnosis>" +

+	                        "<md:date>2012-07-22</md:date>" +

+	                        "<md:malignancy type=\"no\"/>" +

+	                    "</md:pathological_diagnosis>" +

+	                "</md:diagnosis_info>" +             

+	           " </md:record>";

+	String reqStrContentMdRecordSpringer =

+			"<Content>" + reqStrMdRecordSpringer + "</Content>";

+	

+	String reqStrResourceEnd = "    <Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:1.0:resource:resource-id\">"

+			+ "		<AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#anyURI\">http://medico.com/record/patient/BartSimpson</AttributeValue>"

+			+ "  </Attribute>"

+			+ "</Attributes> ";

+	String reqStrActionStart =   "<Attributes Category=\"urn:oasis:names:tc:xacml:3.0:attribute-category:action\">";

+

+	String reqStrActionEnd = "<Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:1.0:action:action-id\">"

+			+ "<AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">read</AttributeValue>"

+			+ "</Attribute>"

+			+ "</Attributes> ";

+	String reqStrEnvironmentStartEnd = "  <Attributes Category=\"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\" />";

+	String reqStrMainEnd = " </Request>";

+

+	

+	// combined strings for convenience

+	String reqStrMainResourceStart = reqStrMainStart + reqStrResourceStart;

+	String reqStrResourceAllEnd = reqStrResourceEnd + reqStrActionStart + reqStrActionEnd + reqStrEnvironmentStartEnd + reqStrMainEnd;

+	

+	

+	/*

+	 * variables useful in the following tests

+	 */

+	List<FunctionArgument> arguments = new ArrayList<FunctionArgument>();

+	

+	

+	

+	// Name Spaces used in the XML as part of these examples - needed for compiling XPaths

+	NamespaceContext nameSpaceContext = new NamespaceContext() {

+	    @Override

+	    public Iterator<?> getPrefixes(String arg0) { return null;}

+

+	    @Override

+	    public String getPrefix(String arg0) {return null;}

+

+	    @Override

+	    public String getNamespaceURI(String arg0) {

+	        if("md".equals(arg0)) {

+	            return "http://www.medico.com/schemas/record";

+	        } else if ("xacml-context".equals(arg0)) {

+	        	return "urn:oasis:names:tc:xacml:3.0:context:schema:os";

+	        } else if ("xsi".equals(arg0)) {

+	        	return "http://www.w3.org/2001/XMLSchema-instance";

+	        }

+	        return null;

+	    }

+	};

+	

+	

+	

+	//

+	// URIs for attribute categroies

+	//

+	

+	FunctionArgumentAttributeValue attrUriNull = null;

+	FunctionArgumentAttributeValue attrUriEmpty = null;

+	FunctionArgumentAttributeValue attrUriResources = null;

+	FunctionArgumentAttributeValue attrUriAction = null;

+	FunctionArgumentAttributeValue attrUriNotInRequest = null;

+	FunctionArgumentAttributeValue attrUriNotCategory = null;

+

+	

+	

+	//

+	// XML Contents 

+	//

+	

+	FunctionArgumentAttributeValue attrXnull = null;

+	FunctionArgumentAttributeValue attrXEmpty = null;

+	FunctionArgumentAttributeValue attrXSimpson = null;

+	FunctionArgumentAttributeValue attrXSpringer = null;

+	FunctionArgumentAttributeValue attrXContentSimpson = null;

+	FunctionArgumentAttributeValue attrXContentSpringer = null;

+	FunctionArgumentAttributeValue attrXBadXML = null;

+	

+

+	

+

+	

+	

+	//

+	// REQUEST objects available for use in tests

+	//

+	Request requestEmpty = new StdMutableRequest();

+	Request requestMdRecord = null;

+	Request requestDoubleResources = null;

+	Request requestDoubleContent = null;

+	Request requestResourceActionContent = null;

+	Request requestContentInAction = null;

+

+

+	

+	

+	/**

+	 * Set up all variables in one place because it is complicated (lots of steps needed for each attribute)

+	 */

+	public FunctionDefinitionAccessPermittedTest() {

+		try {

+

+

+			// create Function Attributes for URIs

+			attrUriNull = null;

+			attrUriEmpty = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(""));

+			attrUriResources = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue("urn:oasis:names:tc:xacml:3.0:attribute-category:resource"));

+			attrUriAction = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue("urn:oasis:names:tc:xacml:3.0:attribute-category:action"));

+			attrUriNotInRequest = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue("NoSuchURI"));

+			attrUriNotCategory = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue("urn:oasis:names:tc:xacml:1.0:resource:resource-id"));

+			

+			// create Function Attributes for XML Strings

+			attrXnull = new FunctionArgumentAttributeValue(null);

+			attrXEmpty = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(""));

+			attrXSimpson = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(reqStrMdRecordSimpson));

+			attrXSpringer = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(reqStrMdRecordSpringer));

+			attrXContentSimpson = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(reqStrContentMdRecordSimpson));

+			attrXContentSpringer = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(reqStrContentMdRecordSpringer));

+			attrXBadXML = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(reqStrMalformedContent));

+

+

+			

+			// Request objects

+			// to create a Request object the easiest way is to put the xml into a file and use the DOMRequest to load it.

+			

+			// single Content in the Resources section (normal valid request)

+			String reqString = reqStrMainResourceStart + reqStrContentMdRecordSimpson + reqStrResourceAllEnd;

+				File tFile = File.createTempFile("functionJunit", "request");

+				BufferedWriter bw = new BufferedWriter(new FileWriter(tFile));

+				bw.append(reqString);

+				bw.flush();

+				bw.close();

+			requestMdRecord = DOMRequest.load(tFile);

+				tFile.delete();

+				

+			// Resources included twice

+			reqString = reqStrMainResourceStart + reqStrContentMdRecordSimpson + reqStrResourceEnd + reqStrResourceStart + reqStrContentMdRecordSimpson +reqStrResourceAllEnd;

+				tFile = File.createTempFile("functionJunit", "request");

+				bw = new BufferedWriter(new FileWriter(tFile));

+				bw.append(reqString);

+				bw.flush();

+				bw.close();

+			requestDoubleResources = DOMRequest.load(tFile);

+				tFile.delete();

+					

+			// Content included twice - error

+			reqString = reqStrMainResourceStart + reqStrContentMdRecordSimpson + reqStrContentMdRecordSimpson +reqStrResourceAllEnd;

+				tFile = File.createTempFile("functionJunit", "request");

+				bw = new BufferedWriter(new FileWriter(tFile));

+				bw.append(reqString);

+				bw.flush();

+				bw.close();

+			try {

+				requestDoubleContent = DOMRequest.load(tFile);

+					tFile.delete();

+			} catch (com.att.research.xacml.std.dom.DOMStructureException e) {

+				// this is what it should do, so just continue

+			} catch (Exception e) {

+				fail("Unexpected exception for bad XML, e="+e);

+			}

+			

+			// content included in both Resource and Action - ok

+			reqString = reqStrMainResourceStart + reqStrContentMdRecordSimpson + reqStrResourceEnd + reqStrActionStart + reqStrContentMdRecordSimpson + reqStrActionEnd + reqStrMainEnd;

+				tFile = File.createTempFile("functionJunit", "request");

+				bw = new BufferedWriter(new FileWriter(tFile));

+				bw.append(reqString);

+				bw.flush();

+				bw.close();	

+			requestResourceActionContent = DOMRequest.load(tFile);

+				tFile.delete();

+				

+			// Content included only in Action - missing content produces non-error result according to spec

+			reqString = reqStrMainResourceStart + reqStrResourceEnd + reqStrActionStart + reqStrContentMdRecordSimpson + reqStrActionEnd + reqStrMainEnd;

+				tFile = File.createTempFile("functionJunit", "request");

+				bw = new BufferedWriter(new FileWriter(tFile));

+				bw.append(reqString);

+				bw.flush();

+				bw.close();		

+			requestContentInAction = DOMRequest.load(tFile);

+				tFile.delete();

+			

+				

+				

+			// Test that Bad XML is caught

+			@SuppressWarnings("unused")

+			Request requestContentMisplaced = null;

+			@SuppressWarnings("unused")

+			Request requestMalformedContent = null;

+				

+				

+			// Bad XML - Content not under a Category

+			reqString = reqStrMainStart + reqStrContentMdRecordSimpson + reqStrResourceStart + reqStrResourceEnd + reqStrActionStart + reqStrActionEnd + reqStrMainEnd;

+				tFile = File.createTempFile("functionJunit", "request");

+				bw = new BufferedWriter(new FileWriter(tFile));

+				bw.append(reqString);

+				bw.flush();

+				bw.close();

+			try {

+				requestContentMisplaced = DOMRequest.load(tFile);

+					tFile.delete();

+			} catch (com.att.research.xacml.std.dom.DOMStructureException e) {

+				// this is what it should do, so just continue

+			} catch (Exception e) {

+				fail("Unexpected exception for bad XML, e="+e);

+			}

+				

+			// Bad XML - Content is not valid XML

+			reqString = reqStrMainResourceStart + reqStrMalformedContent + reqStrResourceAllEnd;

+				tFile = File.createTempFile("functionJunit", "request");

+				bw = new BufferedWriter(new FileWriter(tFile));

+				bw.append(reqString);

+				bw.flush();

+				bw.close();

+			try {

+				requestMalformedContent = DOMRequest.load(tFile);

+					tFile.delete();

+			} catch (com.att.research.xacml.std.dom.DOMStructureException e) {

+				// this is what it should do, so just continue

+			} catch (Exception e) {

+				fail("Unexpected exception for bad XML, e="+e);

+			}

+			

+		} catch (Exception e) {

+			fail("Constructor initializing variables, e="+ e + "  cause="+e.getCause());

+		}

+		

+	}

+	

+

+	

+	

+	

+	

+	

+	@Ignore

+	@Test

+	public void testAccess_permitted() {

+

+		ExpressionResult res = null;

+		Boolean resValue = null;

+		

+		FunctionDefinitionAccessPermitted fd = (FunctionDefinitionAccessPermitted) StdFunctions.FD_ACCESS_PERMITTED;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_ACCESS_PERMITTED, fd.getId());

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+

+		

+

+		// successful invoke returns true

+		arguments.clear();

+		arguments.add(attrUriResources);

+		arguments.add(attrXEmpty);

+		res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+

+				

+		// successful invoke returns false

+		

+		

+		// URI not in Request (ok - evaluate anyway)

+	

+		// test for infinite loop

+		

+		// second arg ok both with and without <Content> tag

+		arguments.clear();

+		arguments.add(attrUriResources);

+		arguments.add(attrXContentSpringer);

+		res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		arguments.clear();

+		arguments.add(attrUriResources);

+		arguments.add(attrXSpringer);

+		res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// second arg not valid XML

+		arguments.clear();

+		arguments.add(attrUriResources);

+		arguments.add(attrXBadXML);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:access-permitted Parsing of XML string failed.  Cause='The element type \"md:hospital_info\" must be terminated by the matching end-tag \"</md:hospital_info>\".'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());	

+		

+		// null Evaluation Context

+		arguments.clear();

+		arguments.add(attrUriNotCategory);

+		arguments.add(attrXContentSimpson);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:access-permitted First argument must be a urn for an attribute-category, not 'urn:oasis:names:tc:xacml:1.0:resource:resource-id", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// null Request

+		arguments.clear();

+		arguments.add(attrUriAction);

+		arguments.add(attrXContentSimpson);

+		res = fd.evaluate(new StdEvaluationContext(null, null, null), arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:access-permitted Got null Request in EvaluationContext", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+	

+		// first arg not uri

+		arguments.clear();

+		arguments.add(attrUriNotCategory);

+		arguments.add(attrXContentSimpson);

+		res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:access-permitted First argument must be a urn for an attribute-category, not 'urn:oasis:names:tc:xacml:1.0:resource:resource-id", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// first arg not attribute-category urn

+		arguments.clear();

+		arguments.add(attrXContentSimpson);

+		arguments.add(attrXContentSimpson);

+		res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:access-permitted Expected data type 'anyURI' saw 'string'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// second arg not string

+		arguments.clear();

+		arguments.add(attrUriAction);

+		arguments.add(attrUriAction);

+		res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:access-permitted Expected data type 'string' saw 'anyURI'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+

+		// too few args

+		arguments.clear();

+		res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:access-permitted Expected 2 arguments, got 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		arguments.clear();

+		arguments.add(attrXContentSimpson);

+		res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:access-permitted Expected 2 arguments, got 1", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		

+		// too many args

+		arguments.clear();

+		arguments.add(attrUriEmpty);

+		arguments.add(attrXContentSimpson);

+		arguments.add(attrXContentSimpson);

+		res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:access-permitted Expected 2 arguments, got 3", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		

+	}

+	

+}

diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmeticTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmeticTest.java
new file mode 100755
index 0000000..3887198
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmeticTest.java
@@ -0,0 +1,707 @@
+/*

+ *                        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.std.functions;

+

+import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.assertFalse;

+import static org.junit.Assert.assertTrue;

+import static org.junit.Assert.fail;

+

+import java.math.BigInteger;

+import java.util.ArrayList;

+import java.util.List;

+

+import org.junit.Test;

+

+import com.att.research.xacml.api.XACML3;

+import com.att.research.xacml.std.datatypes.DataTypes;

+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue;

+import com.att.research.xacmlatt.pdp.std.StdFunctions;

+

+/**

+ * Test of PDP Functions (See XACML core spec section A.3)

+ * 

+ * TO RUN - use jUnit

+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test

+ * 

+ * @author glenngriffin

+ *

+ */

+public class FunctionDefinitionArithmeticTest {

+

+	/*

+	 * variables useful in the following tests

+	 */

+	List<FunctionArgument> arguments = new ArrayList<FunctionArgument>();

+	

+	@Test

+	public void testInteger_add() {

+		

+		FunctionArgumentAttributeValue attr1 = null;

+		FunctionArgumentAttributeValue attr2 = null;

+		FunctionArgumentAttributeValue attrBadType = null;

+		try {

+			attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1));

+			attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1));

+			attrBadType = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.1));

+		} catch (Exception e) {

+			fail("creating attributes e="+ e);

+		}

+		

+		FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_INTEGER_ADD;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_INTEGER_ADD, fd.getId());

+		assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		

+		// test normal add

+		arguments.add(attr1);

+		arguments.add(attr2);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		BigInteger resValue = (BigInteger)res.getValue().getValue();

+		assertEquals(new BigInteger("2"), resValue);

+		

+		arguments.clear();

+		arguments.add(attr1);

+		arguments.add(attrBadType);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:integer-add Expected data type 'integer' saw 'double' at arg index 1", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+	}

+

+	

+	@Test

+	public void testDouble_add() {

+		

+		FunctionArgumentAttributeValue attr1 = null;

+		FunctionArgumentAttributeValue attr2  = null;

+

+		try {

+			attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.5));

+			attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(2.5));

+		} catch (Exception e) {

+			fail("creating attributes e="+e);

+		}

+		

+		FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_DOUBLE_ADD;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_DOUBLE_ADD, fd.getId());

+		assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		

+		// test normal add

+		arguments.add(attr1);

+		arguments.add(attr2);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Double resValue = (Double)res.getValue().getValue();

+		assertEquals(new Double(4.0), resValue);

+		

+	}

+	

+	

+	@Test

+	public void testInteger_subtract() {

+		

+		FunctionArgumentAttributeValue attr1 = null;

+		FunctionArgumentAttributeValue attr2 = null;

+		try {

+			attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(6));

+			attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1));

+		} catch (Exception e) {

+			fail("creating attributes e="+ e);

+		}

+		

+		FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_INTEGER_SUBTRACT;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_INTEGER_SUBTRACT, fd.getId());

+		assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		

+		// test normal 

+		arguments.add(attr1);

+		arguments.add(attr2);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		BigInteger resValue = (BigInteger)res.getValue().getValue();

+		assertEquals(new BigInteger("5"), resValue);

+		

+	}

+

+	

+	@Test

+	public void testDouble_subtract() {

+		

+		FunctionArgumentAttributeValue attr1 = null;

+		FunctionArgumentAttributeValue attr2  = null;

+

+		try {

+			attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(8.5));

+			attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(2.3));

+		} catch (Exception e) {

+			fail("creating attributes e="+e);

+		}

+		

+		FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_DOUBLE_SUBTRACT;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_DOUBLE_SUBTRACT, fd.getId());

+		assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		

+		// test normal 

+		arguments.add(attr1);

+		arguments.add(attr2);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Double resValue = (Double)res.getValue().getValue();

+		assertEquals(new Double(6.2), resValue);

+		

+	}

+	

+	

+	@Test

+	public void testInteger_multiply() {

+		

+		FunctionArgumentAttributeValue attr0 = null;

+		FunctionArgumentAttributeValue attr1 = null;

+		FunctionArgumentAttributeValue attr2 = null;

+		try {

+			attr0 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(0));

+			attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(5));

+			attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(2));

+		} catch (Exception e) {

+			fail("creating attributes e="+ e);

+		}

+		

+		FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_INTEGER_MULTIPLY;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_INTEGER_MULTIPLY, fd.getId());

+		assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		

+		// test normal 

+		arguments.add(attr1);

+		arguments.add(attr2);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		BigInteger resValue = (BigInteger)res.getValue().getValue();

+		assertEquals(new BigInteger("10"), resValue);

+		

+		

+		// test 0

+		arguments.clear();

+		arguments.add(attr1);

+		arguments.add(attr0);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (BigInteger)res.getValue().getValue();

+		assertEquals(new BigInteger("0"), resValue);

+	}

+

+	

+	@Test

+	public void testDouble_multiply() {

+		

+		FunctionArgumentAttributeValue attr0 = null;

+		FunctionArgumentAttributeValue attr1 = null;

+		FunctionArgumentAttributeValue attr2  = null;

+

+		try {

+			attr0 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(0));

+			attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.5));

+			attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(2.5));

+		} catch (Exception e) {

+			fail("creating attributes e="+e);

+		}

+		

+		FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_DOUBLE_MULTIPLY;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_DOUBLE_MULTIPLY, fd.getId());

+		assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		

+		// test normal add

+		arguments.add(attr1);

+		arguments.add(attr2);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Double resValue = (Double)res.getValue().getValue();

+		assertEquals(new Double(3.75), resValue);

+		

+		// test multiply by 0

+		arguments.clear();

+		arguments.add(attr1);

+		arguments.add(attr0);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Double)res.getValue().getValue();

+		assertEquals(new Double(0), resValue);

+	}

+	

+	

+	@Test

+	public void testInteger_divide() {

+		

+		FunctionArgumentAttributeValue attr0 = null;

+		FunctionArgumentAttributeValue attr1 = null;

+		FunctionArgumentAttributeValue attr2 = null;

+		try {

+			attr0 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(0));

+			attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(5));

+			attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(2));

+		} catch (Exception e) {

+			fail("creating attributes e="+ e);

+		}

+		

+		FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_INTEGER_DIVIDE;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_INTEGER_DIVIDE, fd.getId());

+		assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		

+		// test normal 

+		arguments.add(attr1);

+		arguments.add(attr2);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		BigInteger resValue = (BigInteger)res.getValue().getValue();

+		assertEquals(new BigInteger("2"), resValue);

+		

+		

+		// test 0

+		arguments.clear();

+		arguments.add(attr1);

+		arguments.add(attr0);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:integer-divide Divide by 0 error: 5, 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+

+	}

+

+	

+	@Test

+	public void testDouble_divide() {

+		

+		FunctionArgumentAttributeValue attr0 = null;

+		FunctionArgumentAttributeValue attr1 = null;

+		FunctionArgumentAttributeValue attr2  = null;

+

+		try {

+			attr0 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(0));

+			attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.5));

+			attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(2.5));

+

+		} catch (Exception e) {

+			fail("creating attributes e="+e);

+		}

+		FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_DOUBLE_DIVIDE;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_DOUBLE_DIVIDE, fd.getId());

+		assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		

+		// test normal 

+		arguments.add(attr1);

+		arguments.add(attr2);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Double resValue = (Double)res.getValue().getValue();

+		assertEquals(new Double(0.6), resValue);

+		

+		// test multiply by 0

+		arguments.clear();

+		arguments.add(attr1);

+		arguments.add(attr0);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:double-divide Divide by 0 error: 1.5, 0.0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+

+	}

+	

+	

+	

+	

+	

+	

+	@Test

+	public void testInteger_mod() {

+		

+		FunctionArgumentAttributeValue attr0 = null;

+		FunctionArgumentAttributeValue attr1 = null;

+		FunctionArgumentAttributeValue attr2 = null;

+		try {

+			attr0 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(0));

+			attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(28));

+			attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(5));

+		} catch (Exception e) {

+			fail("creating attributes e="+ e);

+		}

+		

+		FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_INTEGER_MOD;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_INTEGER_MOD, fd.getId());

+		assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		

+		// test normal 

+		arguments.add(attr1);

+		arguments.add(attr2);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		BigInteger resValue = (BigInteger)res.getValue().getValue();

+		assertEquals(new BigInteger("3"), resValue);

+		

+		

+		// test 0

+		arguments.clear();

+		arguments.add(attr1);

+		arguments.add(attr0);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:integer-mod Divide by 0 error: 28, 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+

+	}

+	

+

+	@Test

+	public void testInteger_abs() {

+

+		FunctionArgumentAttributeValue attr0 = null;

+		FunctionArgumentAttributeValue attr1 = null;

+		FunctionArgumentAttributeValue attrM1 = null;

+		try {

+			attr0 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(0));

+			attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(5));

+			attrM1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(-7));

+		} catch (Exception e) {

+			fail("creating attributes e="+ e);

+		}

+		

+		FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_INTEGER_ABS;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_INTEGER_ABS, fd.getId());

+		assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(1), fd.getNumArgs());

+		

+		

+		// test normal 

+		arguments.add(attr1);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		BigInteger resValue = (BigInteger)res.getValue().getValue();

+		assertEquals(new BigInteger("5"), resValue);

+		

+		arguments.clear();

+		arguments.add(attrM1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (BigInteger)res.getValue().getValue();

+		assertEquals(new BigInteger("7"), resValue);

+

+		arguments.clear();

+		arguments.add(attr0);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (BigInteger)res.getValue().getValue();

+		assertEquals(new BigInteger("0"), resValue);

+	}

+

+	

+	@Test

+	public void testDouble_abs() {

+		

+		FunctionArgumentAttributeValue attr0 = null;

+		FunctionArgumentAttributeValue attr1 = null;

+		FunctionArgumentAttributeValue attr2  = null;

+

+		try {

+			attr0 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(0));

+			attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.5));

+			attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(-2.5));

+

+		} catch (Exception e) {

+			fail("creating attributes e="+e);

+		}

+		

+		FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_DOUBLE_ABS;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_DOUBLE_ABS, fd.getId());

+		assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(1), fd.getNumArgs());

+		

+		

+		// test normal 

+		arguments.add(attr1);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Double resValue = (Double)res.getValue().getValue();

+		assertEquals(new Double(1.5), resValue);

+		

+		arguments.clear();

+		arguments.add(attr2);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Double)res.getValue().getValue();

+		assertEquals(new Double(2.5), resValue);

+		

+		arguments.clear();

+		arguments.add(attr0);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Double)res.getValue().getValue();

+		assertEquals(new Double(0), resValue);

+

+	}

+	

+	

+	@Test

+	public void testDouble_round() {

+

+		FunctionArgumentAttributeValue attr0 = null;

+		FunctionArgumentAttributeValue attr1 = null;

+		FunctionArgumentAttributeValue attr2  = null;

+		FunctionArgumentAttributeValue attr3 = null;

+		FunctionArgumentAttributeValue attr4 = null;

+		FunctionArgumentAttributeValue attr5 = null;

+		FunctionArgumentAttributeValue attr6 = null;

+		try {

+			attr0 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(0));

+			attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.5));

+			attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.49));

+			attr3 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.51));

+			attr4 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(-2.5));

+			attr5 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(-2.49));

+			attr6 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(-2.51));

+		} catch (Exception e) {

+			fail("creating attributes e="+e);

+		}

+		

+		

+		

+		FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_ROUND;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_ROUND, fd.getId());

+		assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(1), fd.getNumArgs());

+		

+		

+		// test normal 

+		arguments.add(attr0);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Double resValue = (Double)res.getValue().getValue();

+		assertEquals(new Double(0), resValue);

+		

+		arguments.clear();

+		arguments.add(attr1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Double)res.getValue().getValue();

+		assertEquals(new Double(2), resValue);

+		

+		arguments.clear();

+		arguments.add(attr2);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Double)res.getValue().getValue();

+		assertEquals(new Double(1), resValue);

+		

+		arguments.clear();

+		arguments.add(attr3);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Double)res.getValue().getValue();

+		assertEquals(new Double(2), resValue);

+		

+		arguments.clear();

+		arguments.add(attr4);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Double)res.getValue().getValue();

+		assertEquals(new Double(-2), resValue);

+	

+		arguments.clear();

+		arguments.add(attr5);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Double)res.getValue().getValue();

+		assertEquals(new Double(-2), resValue);

+		

+		arguments.clear();

+		arguments.add(attr6);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Double)res.getValue().getValue();

+		assertEquals(new Double(-3), resValue);

+	}

+	

+	

+	@Test

+	public void testDouble_floor() {

+		FunctionArgumentAttributeValue attr0 = null;

+		FunctionArgumentAttributeValue attr1 = null;

+		FunctionArgumentAttributeValue attr2  = null;

+		FunctionArgumentAttributeValue attr3 = null;

+		FunctionArgumentAttributeValue attr4 = null;

+		FunctionArgumentAttributeValue attr5 = null;

+		FunctionArgumentAttributeValue attr6 = null;

+		try {

+			attr0 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(0));

+			attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.5));

+			attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.49));

+			attr3 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.51));

+			attr4 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(-2.5));

+			attr5 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(-2.49));

+			attr6 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(-2.51));

+		} catch (Exception e) {

+			fail("creating attributes e="+e);

+		}

+		

+		FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_FLOOR;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_FLOOR, fd.getId());

+		assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(1), fd.getNumArgs());

+		

+		

+		// test normal 

+		arguments.add(attr0);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Double resValue = (Double)res.getValue().getValue();

+		assertEquals(new Double(0), resValue);

+		

+		arguments.clear();

+		arguments.add(attr1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Double)res.getValue().getValue();

+		assertEquals(new Double(1), resValue);

+		

+		arguments.clear();

+		arguments.add(attr2);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Double)res.getValue().getValue();

+		assertEquals(new Double(1), resValue);

+		

+		arguments.clear();

+		arguments.add(attr3);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Double)res.getValue().getValue();

+		assertEquals(new Double(1), resValue);

+		

+		arguments.clear();

+		arguments.add(attr4);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Double)res.getValue().getValue();

+		assertEquals(new Double(-3), resValue);

+	

+		arguments.clear();

+		arguments.add(attr5);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Double)res.getValue().getValue();

+		assertEquals(new Double(-3), resValue);

+		

+		arguments.clear();

+		arguments.add(attr6);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Double)res.getValue().getValue();

+		assertEquals(new Double(-3), resValue);

+	}

+	

+}

diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagIsInTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagIsInTest.java
new file mode 100755
index 0000000..d097122
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagIsInTest.java
@@ -0,0 +1,201 @@
+package com.att.research.xacmlatt.pdp.std.functions;

+

+import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.assertFalse;

+import static org.junit.Assert.assertTrue;

+import static org.junit.Assert.fail;

+

+import java.util.ArrayList;

+import java.util.List;

+

+import org.junit.Test;

+

+import com.att.research.xacml.api.XACML3;

+import com.att.research.xacml.std.StdAttributeValue;

+import com.att.research.xacml.std.datatypes.DataTypes;

+import com.att.research.xacmlatt.pdp.policy.Bag;

+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgumentBag;

+import com.att.research.xacmlatt.pdp.std.StdFunctions;

+

+/**

+ * Test of PDP Functions (See XACML core spec section A.3)

+ * 

+ * TO RUN - use jUnit

+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test

+ * 

+ * @author glenngriffin

+ *

+ */

+public class FunctionDefinitionBagIsInTest {

+

+

+	/*

+	 * variables useful in the following tests

+	 */

+	List<FunctionArgument> arguments = new ArrayList<FunctionArgument>();

+	

+	

+	@Test

+	public void testString() {

+		String v1 = new String("abc");

+		String v2 = new String("def");

+		String notInBag = new String("lmnop");

+		String sameValueV1 = new String("abc");

+		Integer vOtherType = new Integer(11);

+		

+		

+		FunctionArgumentAttributeValue attrV1 = null;

+		FunctionArgumentAttributeValue attrV2 = null;

+		FunctionArgumentAttributeValue attrNotInBag = null;

+		FunctionArgumentAttributeValue attrSameValueV1 = null;

+		FunctionArgumentAttributeValue attrOtherType = null;

+		try {

+			attrV1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v1));

+			attrV2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v2));

+			attrNotInBag = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(notInBag));

+			attrSameValueV1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(sameValueV1));

+			attrOtherType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(vOtherType));

+		} catch (Exception e) {

+			fail("creating attributes e="+ e);

+		}

+		

+		Bag bag0 = new Bag();

+		Bag bag1 = new Bag();

+			bag1.add(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), v1));

+		Bag bag2 = new Bag();

+			bag2.add(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), v1)); 

+			bag2.add(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), v2));;

+

+		

+		

+		FunctionArgumentBag attrBag0 = new FunctionArgumentBag(bag0);

+		FunctionArgumentBag attrBag1 = new FunctionArgumentBag(bag1);

+		FunctionArgumentBag attrBag2 = new FunctionArgumentBag(bag2);

+

+		

+		

+		FunctionDefinitionBagIsIn<?> fd = (FunctionDefinitionBagIsIn<?>) StdFunctions.FD_STRING_IS_IN;

+

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_STRING_IS_IN, fd.getId());

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+

+		

+		// element is in bag

+		arguments.clear();

+		arguments.add(attrV1);

+		arguments.add(attrBag2);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertEquals(true, resValue);

+		

+		// element not in bag

+		arguments.clear();

+		arguments.add(attrNotInBag);

+		arguments.add(attrBag2);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(false, resValue);

+		

+		// different element with the same value is in bag

+		arguments.clear();

+		arguments.add(attrSameValueV1);

+		arguments.add(attrBag2);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(true, resValue);

+		

+		// empty bag

+		arguments.clear();

+		arguments.add(attrV1);

+		arguments.add(attrBag0);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(false, resValue);

+		

+		// missing arg

+		arguments.clear();

+		arguments.add(attrSameValueV1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-is-in Expected 2 arguments, got 1", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// 1st arg is bag

+		arguments.clear();

+		arguments.add(attrBag1);

+		arguments.add(attrBag2);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-is-in Expected a simple value, saw a bag", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// 2nd arg not bag

+		arguments.clear();

+		arguments.add(attrV1);

+		arguments.add(attrV2);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-is-in Expected a bag, saw a simple value", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// first arg null

+		arguments.clear();

+		arguments.add(null);

+		arguments.add(attrBag2);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-is-in Got null argument", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// 2nd arg null

+		arguments.clear();

+		arguments.add(attrV1);

+		arguments.add(null);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-is-in Got null argument", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// first arg type does not match bag elements

+		arguments.clear();

+		arguments.add(attrOtherType);

+		arguments.add(attrBag2);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-is-in Expected data type 'string' saw 'integer'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// bag has mixed element types

+// behavior not specified for this case in spec.  It ASSUMES that all elements in bag are same type.

+		

+	}

+	

+

+	

+	

+	//

+	//

+	//  REST OF DATA TYPES OMITTED 

+	//	because they "should" all work the same

+	//

+	//

+	

+	

+	

+

+}

diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagOneAndOnlyTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagOneAndOnlyTest.java
new file mode 100755
index 0000000..13c5161
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagOneAndOnlyTest.java
@@ -0,0 +1,204 @@
+package com.att.research.xacmlatt.pdp.std.functions;

+

+import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.assertFalse;

+import static org.junit.Assert.assertTrue;

+

+import java.util.ArrayList;

+import java.util.List;

+import java.math.BigInteger;

+

+import org.junit.Test;

+

+import com.att.research.xacml.api.XACML3;

+import com.att.research.xacml.std.StdAttributeValue;

+import com.att.research.xacml.std.datatypes.DataTypes;

+import com.att.research.xacmlatt.pdp.policy.Bag;

+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgumentBag;

+import com.att.research.xacmlatt.pdp.std.StdFunctions;

+

+/**

+ * Test of PDP Functions (See XACML core spec section A.3)

+ * 

+ * TO RUN - use jUnit

+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test

+ * 

+ * @author glenngriffin

+ *

+ */

+public class FunctionDefinitionBagOneAndOnlyTest {

+

+

+	/*

+	 * variables useful in the following tests

+	 */

+	List<FunctionArgument> arguments = new ArrayList<FunctionArgument>();

+	

+	

+	@Test

+	public void testString() {

+		String v1 = new String("abc");

+		String v2 = new String("def");

+		BigInteger vOtherType = BigInteger.valueOf(11);

+		

+		Bag bag0 = new Bag();

+		Bag bag1 = new Bag();

+			bag1.add(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), v1));  

+		Bag bag2 = new Bag();

+			bag2.add(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), v1));  

+			bag2.add(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), v2));

+		Bag bagOtherType = new Bag();

+			bagOtherType.add(new StdAttributeValue<BigInteger>(DataTypes.DT_INTEGER.getId(), vOtherType));

+		

+		FunctionArgumentBag attrBag0 = new FunctionArgumentBag(bag0);

+		FunctionArgumentBag attrBag1 = new FunctionArgumentBag(bag1);

+		FunctionArgumentBag attrBag2 = new FunctionArgumentBag(bag2);

+		FunctionArgumentBag attrBagOtherType = new FunctionArgumentBag(bagOtherType);

+		

+		

+		FunctionDefinitionBagOneAndOnly<?> fd = (FunctionDefinitionBagOneAndOnly<?>) StdFunctions.FD_STRING_ONE_AND_ONLY;

+

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_STRING_ONE_AND_ONLY, fd.getId());

+		assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+

+		

+		

+		

+		// bag with only one

+		arguments.clear();

+		arguments.add(attrBag1);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(String.class, res.getValue().getValue().getClass());

+		String resValue = (String)res.getValue().getValue();

+		assertEquals(v1, resValue);

+		

+		// null bag

+		arguments.clear();

+		arguments.add(null);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-one-and-only Got null argument", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// bag with exactly one but of other type in it

+		arguments.clear();

+		arguments.add(attrBagOtherType);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-one-and-only Element in bag of wrong type. Expected string got integer", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// bag with none

+		arguments.clear();

+		arguments.add(attrBag0);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-one-and-only Expected 1 but Bag has 0 elements", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// bag with multiple

+		arguments.clear();

+		arguments.add(attrBag2);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-one-and-only Expected 1 but Bag has 2 elements", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+	}

+	

+	

+	

+	@Test

+	public void testBoolean() {

+		Boolean v1 = new Boolean(true);

+		Boolean v2 = new Boolean(false);

+		BigInteger vOtherType = BigInteger.valueOf(11);

+		

+		Bag bag0 = new Bag();

+		Bag bag1 = new Bag();

+			bag1.add(new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), v1));  

+		Bag bag2 = new Bag();

+			bag2.add(new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), v1));  

+			bag2.add(new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), v2)); 

+		Bag bagOtherType = new Bag();

+			bagOtherType.add(new StdAttributeValue<BigInteger>(DataTypes.DT_STRING.getId(), vOtherType));  

+

+		

+		FunctionArgumentBag attrBag0 = new FunctionArgumentBag(bag0);

+		FunctionArgumentBag attrBag1 = new FunctionArgumentBag(bag1);

+		FunctionArgumentBag attrBag2 = new FunctionArgumentBag(bag2);

+		FunctionArgumentBag attrBagOtherType = new FunctionArgumentBag(bagOtherType);

+		

+		

+		FunctionDefinitionBagOneAndOnly<?> fd = (FunctionDefinitionBagOneAndOnly<?>) StdFunctions.FD_BOOLEAN_ONE_AND_ONLY;

+

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_BOOLEAN_ONE_AND_ONLY, fd.getId());

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+

+		

+		

+		

+		// bag with only one

+		arguments.clear();

+		arguments.add(attrBag1);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertEquals(new Boolean(true), resValue);

+		

+		// null bag

+		arguments.clear();

+		arguments.add(null);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:boolean-one-and-only Got null argument", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// bag with exactly one but of other type in it

+		arguments.clear();

+		arguments.add(attrBagOtherType);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:boolean-one-and-only Element in bag of wrong type. Expected boolean got string", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// bag with none

+		arguments.clear();

+		arguments.add(attrBag0);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:boolean-one-and-only Expected 1 but Bag has 0 elements", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// bag with multiple

+		arguments.clear();

+		arguments.add(attrBag2);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:boolean-one-and-only Expected 1 but Bag has 2 elements", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+	}

+	

+	

+	//

+	//

+	//  REST OF DATA TYPES OMITTED 

+	//	because they "should" all work the same

+	//

+	//

+	

+	

+	

+

+}

diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagSizeTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagSizeTest.java
new file mode 100755
index 0000000..afc5e09
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagSizeTest.java
@@ -0,0 +1,138 @@
+package com.att.research.xacmlatt.pdp.std.functions;

+

+import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.assertFalse;

+import static org.junit.Assert.assertTrue;

+

+import java.math.BigInteger;

+import java.util.ArrayList;

+import java.util.List;

+

+import org.junit.Test;

+

+import com.att.research.xacml.api.XACML3;

+import com.att.research.xacml.std.StdAttributeValue;

+import com.att.research.xacml.std.datatypes.DataTypes;

+import com.att.research.xacmlatt.pdp.policy.Bag;

+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgumentBag;

+import com.att.research.xacmlatt.pdp.std.StdFunctions;

+

+/**

+ * Test of PDP Functions (See XACML core spec section A.3)

+ * 

+ * TO RUN - use jUnit

+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test

+ * 

+ * @author glenngriffin

+ *

+ */

+public class FunctionDefinitionBagSizeTest {

+

+

+	/*

+	 * variables useful in the following tests

+	 */

+	List<FunctionArgument> arguments = new ArrayList<FunctionArgument>();

+	

+	

+	@Test

+	public void testString() {

+		String v1 = new String("abc");

+		String v2 = new String("def");

+		Integer vOtherType = new Integer(11);

+		

+

+		

+		Bag bag0 = new Bag();

+		Bag bag1 = new Bag();

+			bag1.add(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), v1));  

+		Bag bag2 = new Bag();

+			bag2.add(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), v1));  

+			bag2.add(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), v2)); 

+		Bag bagOtherType = new Bag();

+			bagOtherType.add(new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), vOtherType));  

+

+		

+		FunctionArgumentBag attrBag0 = new FunctionArgumentBag(bag0);

+		FunctionArgumentBag attrBag1 = new FunctionArgumentBag(bag1);

+		FunctionArgumentBag attrBag2 = new FunctionArgumentBag(bag2);

+		FunctionArgumentBag attrBagOtherType = new FunctionArgumentBag(bagOtherType);

+		

+		

+		FunctionDefinitionBagSize<?> fd = (FunctionDefinitionBagSize<?>) StdFunctions.FD_STRING_BAG_SIZE;

+

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_STRING_BAG_SIZE, fd.getId());

+		assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+

+		

+		

+		

+		// bag with only one

+		arguments.clear();

+		arguments.add(attrBag1);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(BigInteger.class, res.getValue().getValue().getClass());

+		BigInteger resValue = (BigInteger)res.getValue().getValue();

+		assertEquals(BigInteger.valueOf(1), resValue);

+		

+		// null bag

+		arguments.clear();

+		arguments.add(null);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-bag-size Got null argument", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// bag with exactly one but of other type in it

+		arguments.clear();

+		arguments.add(attrBagOtherType);

+		res = fd.evaluate(null, arguments);

+		// NOTE: Size does not care about content type!

+		assertTrue(res.isOk());

+		assertEquals(BigInteger.class, res.getValue().getValue().getClass());

+		resValue = (BigInteger)res.getValue().getValue();

+		assertEquals(BigInteger.valueOf(1), resValue);

+		

+		// bag with none

+		arguments.clear();

+		arguments.add(attrBag0);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(BigInteger.class, res.getValue().getValue().getClass());

+		resValue = (BigInteger)res.getValue().getValue();

+		assertEquals(BigInteger.valueOf(0), resValue);

+		

+		// bag with multiple

+		arguments.clear();

+		arguments.add(attrBag2);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(BigInteger.class, res.getValue().getValue().getClass());

+		resValue = (BigInteger)res.getValue().getValue();

+		assertEquals(BigInteger.valueOf(2), resValue);

+	}

+	

+	

+

+	

+	

+	

+	

+	//

+	//

+	//  REST OF DATA TYPES OMITTED 

+	//	because they "should" all work the same

+	//

+	//

+	

+	

+	

+

+}

diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagTest.java
new file mode 100755
index 0000000..4901916
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagTest.java
@@ -0,0 +1,527 @@
+package com.att.research.xacmlatt.pdp.std.functions;

+

+import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.assertFalse;

+import static org.junit.Assert.assertNotNull;

+import static org.junit.Assert.assertTrue;

+import static org.junit.Assert.fail;

+

+import java.math.BigInteger;

+import java.util.ArrayList;

+import java.util.Iterator;

+import java.util.List;

+

+import org.junit.Test;

+

+import com.att.research.xacml.api.AttributeValue;

+import com.att.research.xacml.api.XACML3;

+import com.att.research.xacml.std.datatypes.DataTypes;

+import com.att.research.xacmlatt.pdp.policy.Bag;

+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue;

+import com.att.research.xacmlatt.pdp.std.StdFunctions;

+

+/**

+ * Test of PDP Functions (See XACML core spec section A.3)

+ * 

+ * TO RUN - use jUnit

+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test

+ * 

+ * @author glenngriffin

+ *

+ */

+public class FunctionDefinitionBagTest {

+

+

+	/*

+	 * variables useful in the following tests

+	 */

+	List<FunctionArgument> arguments = new ArrayList<FunctionArgument>();

+	

+	

+	FunctionArgumentAttributeValue attrInteger = null;

+	FunctionArgumentAttributeValue attrString = null;

+

+	public FunctionDefinitionBagTest() {

+		try {

+			attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1111111111));

+			attrString = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("a string value"));

+		} catch (Exception e) {

+			fail("creating attributes e="+e);

+		}

+	}

+	

+	@Test

+	public void testString() {

+

+		String s1 = "abc";

+		String s2 = "def";

+		FunctionArgumentAttributeValue attr1 = null;

+		FunctionArgumentAttributeValue attr2 = null;

+		try {

+			attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(s1));

+			attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(s2));

+		} catch (Exception e) {

+			fail("creating attributes e="+e);

+		}

+		

+		FunctionDefinitionBag<?> fd = (FunctionDefinitionBag<?>) StdFunctions.FD_STRING_BAG;

+

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_STRING_BAG, fd.getId());

+		assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertTrue(fd.returnsBag());

+

+		// bag with only one

+		arguments.clear();

+		arguments.add(attr1);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Bag bag = res.getBag();

+		assertNotNull(bag);

+		Iterator<AttributeValue<?>> it = bag.getAttributeValues();

+		assertEquals(1, bag.size());

+		AttributeValue<?> attrValueObject = it.next();

+		assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId());

+		assertEquals(s1, attrValueObject.getValue());

+		

+		// zero args => empty bag

+		arguments.clear();

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		assertEquals(0, bag.size());

+

+		

+		// null argument

+		arguments.clear();

+		arguments.add(null);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-bag Got null argument", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// argument of other type

+		arguments.clear();

+		arguments.add(attrInteger);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-bag Expected data type 'string' saw 'integer'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// 2 args (check response is correct)

+		arguments.clear();

+		arguments.add(attr1);

+		arguments.add(attr2);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		it = bag.getAttributeValues();

+		assertEquals(2, bag.size());

+		attrValueObject = it.next();

+		assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId());

+		assertEquals(s1, attrValueObject.getValue());

+		attrValueObject = it.next();

+		assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId());

+		assertEquals(s2, attrValueObject.getValue());

+		

+		// duplicate args (verify return)

+		arguments.clear();

+		arguments.add(attr1);

+		arguments.add(attr2);

+		arguments.add(attr1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		it = bag.getAttributeValues();

+		assertEquals(3, bag.size());

+		attrValueObject = it.next();

+		assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId());

+		assertEquals(s1, attrValueObject.getValue());

+		attrValueObject = it.next();

+		assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId());

+		assertEquals(s2, attrValueObject.getValue());

+		attrValueObject = it.next();

+		assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId());

+		assertEquals(s1, attrValueObject.getValue());

+		

+		// lots of args

+		arguments.clear();

+		for (int i = 0; i < 1000; i++) {

+			arguments.add(attr1);

+		}

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		it = bag.getAttributeValues();

+		assertEquals(1000, bag.size());

+		

+	}

+	

+

+	@Test

+	public void testBoolean() {

+

+		Boolean s1 = true;

+		Boolean s2 = false;

+		FunctionArgumentAttributeValue attr1 = null;

+		FunctionArgumentAttributeValue attr2 = null;

+		try {

+			attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_BOOLEAN.createAttributeValue(s1));

+			attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_BOOLEAN.createAttributeValue(s2));

+		} catch (Exception e) {

+			fail("creating attributes e="+e);

+		}

+		

+		FunctionDefinitionBag<?> fd = (FunctionDefinitionBag<?>) StdFunctions.FD_BOOLEAN_BAG;

+

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_BOOLEAN_BAG, fd.getId());

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertTrue(fd.returnsBag());

+

+		// bag with only one

+		arguments.clear();

+		arguments.add(attr1);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Bag bag = res.getBag();

+		assertNotNull(bag);

+		Iterator<AttributeValue<?>> it = bag.getAttributeValues();

+		assertEquals(1, bag.size());

+		AttributeValue<?> attrValueObject = it.next();

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), attrValueObject.getDataTypeId());

+		assertEquals(s1, attrValueObject.getValue());

+		

+		// zero args => empty bag

+		arguments.clear();

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		assertEquals(0, bag.size());

+

+		

+		// null argument

+		arguments.clear();

+		arguments.add(null);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:boolean-bag Got null argument", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// argument of other type

+		arguments.clear();

+		arguments.add(attrInteger);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:boolean-bag Expected data type 'boolean' saw 'integer'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// 2 args (check response is correct)

+		arguments.clear();

+		arguments.add(attr1);

+		arguments.add(attr2);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		it = bag.getAttributeValues();

+		assertEquals(2, bag.size());

+		attrValueObject = it.next();

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), attrValueObject.getDataTypeId());

+		assertEquals(s1, attrValueObject.getValue());

+		attrValueObject = it.next();

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), attrValueObject.getDataTypeId());

+		assertEquals(s2, attrValueObject.getValue());

+		

+		// duplicate args (verify return)

+		arguments.clear();

+		arguments.add(attr1);

+		arguments.add(attr2);

+		arguments.add(attr1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		it = bag.getAttributeValues();

+		assertEquals(3, bag.size());

+		attrValueObject = it.next();

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), attrValueObject.getDataTypeId());

+		assertEquals(s1, attrValueObject.getValue());

+		attrValueObject = it.next();

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), attrValueObject.getDataTypeId());

+		assertEquals(s2, attrValueObject.getValue());

+		attrValueObject = it.next();

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), attrValueObject.getDataTypeId());

+		assertEquals(s1, attrValueObject.getValue());

+		

+		// lots of args

+		arguments.clear();

+		for (int i = 0; i < 1000; i++) {

+			arguments.add(attr1);

+		}

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		it = bag.getAttributeValues();

+		assertEquals(1000, bag.size());

+		

+	}

+	

+	

+

+	@Test

+	public void testInteger() {

+

+		BigInteger s1 = new BigInteger("123");

+		BigInteger s2 = new BigInteger("456");

+		FunctionArgumentAttributeValue attr1 = null;

+		FunctionArgumentAttributeValue attr2 = null;

+		try {

+			attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(s1));

+			attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(s2));

+		} catch (Exception e) {

+			fail("creating attributes e="+e);

+		}

+		

+		FunctionDefinitionBag<?> fd = (FunctionDefinitionBag<?>) StdFunctions.FD_INTEGER_BAG;

+

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_INTEGER_BAG, fd.getId());

+		assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertTrue(fd.returnsBag());

+

+		// bag with only one

+		arguments.clear();

+		arguments.add(attr1);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Bag bag = res.getBag();

+		assertNotNull(bag);

+		Iterator<AttributeValue<?>> it = bag.getAttributeValues();

+		assertEquals(1, bag.size());

+		AttributeValue<?> attrValueObject = it.next();

+		assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId());

+		assertEquals(s1, attrValueObject.getValue());

+		

+		// zero args => empty bag

+		arguments.clear();

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		assertEquals(0, bag.size());

+

+		

+		// null argument

+		arguments.clear();

+		arguments.add(null);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:integer-bag Got null argument", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// argument of other type

+		arguments.clear();

+		arguments.add(attrString);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:integer-bag Expected data type 'integer' saw 'string'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// 2 args (check response is correct)

+		arguments.clear();

+		arguments.add(attr1);

+		arguments.add(attr2);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		it = bag.getAttributeValues();

+		assertEquals(2, bag.size());

+		attrValueObject = it.next();

+		assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId());

+		assertEquals(s1, attrValueObject.getValue());

+		attrValueObject = it.next();

+		assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId());

+		assertEquals(s2, attrValueObject.getValue());

+		

+		// duplicate args (verify return)

+		arguments.clear();

+		arguments.add(attr1);

+		arguments.add(attr2);

+		arguments.add(attr1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		it = bag.getAttributeValues();

+		assertEquals(3, bag.size());

+		attrValueObject = it.next();

+		assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId());

+		assertEquals(s1, attrValueObject.getValue());

+		attrValueObject = it.next();

+		assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId());

+		assertEquals(s2, attrValueObject.getValue());

+		attrValueObject = it.next();

+		assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId());

+		assertEquals(s1, attrValueObject.getValue());

+		

+		// lots of args

+		arguments.clear();

+		for (int i = 0; i < 1000; i++) {

+			arguments.add(attr1);

+		}

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		it = bag.getAttributeValues();

+		assertEquals(1000, bag.size());

+		

+	}

+	

+	

+	

+

+	@Test

+	public void testDouble() {

+

+		Double s1 = 123.45;

+		Double s2 = 678.901;

+		FunctionArgumentAttributeValue attr1 = null;

+		FunctionArgumentAttributeValue attr2 = null;

+		try {

+			attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(s1));

+			attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(s2));

+		} catch (Exception e) {

+			fail("creating attributes e="+e);

+		}

+		

+		FunctionDefinitionBag<?> fd = (FunctionDefinitionBag<?>) StdFunctions.FD_DOUBLE_BAG;

+

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_DOUBLE_BAG, fd.getId());

+		assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertTrue(fd.returnsBag());

+

+		// bag with only one

+		arguments.clear();

+		arguments.add(attr1);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Bag bag = res.getBag();

+		assertNotNull(bag);

+		Iterator<AttributeValue<?>> it = bag.getAttributeValues();

+		assertEquals(1, bag.size());

+		AttributeValue<?> attrValueObject = it.next();

+		assertEquals(DataTypes.DT_DOUBLE.getId(), attrValueObject.getDataTypeId());

+		assertEquals(s1, attrValueObject.getValue());

+		

+		// zero args => empty bag

+		arguments.clear();

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		assertEquals(0, bag.size());

+

+		

+		// null argument

+		arguments.clear();

+		arguments.add(null);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:double-bag Got null argument", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// argument of other type

+		arguments.clear();

+		arguments.add(attrInteger);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:double-bag Expected data type 'double' saw 'integer'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// 2 args (check response is correct)

+		arguments.clear();

+		arguments.add(attr1);

+		arguments.add(attr2);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		it = bag.getAttributeValues();

+		assertEquals(2, bag.size());

+		attrValueObject = it.next();

+		assertEquals(DataTypes.DT_DOUBLE.getId(), attrValueObject.getDataTypeId());

+		assertEquals(s1, attrValueObject.getValue());

+		attrValueObject = it.next();

+		assertEquals(DataTypes.DT_DOUBLE.getId(), attrValueObject.getDataTypeId());

+		assertEquals(s2, attrValueObject.getValue());

+		

+		// duplicate args (verify return)

+		arguments.clear();

+		arguments.add(attr1);

+		arguments.add(attr2);

+		arguments.add(attr1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		it = bag.getAttributeValues();

+		assertEquals(3, bag.size());

+		attrValueObject = it.next();

+		assertEquals(DataTypes.DT_DOUBLE.getId(), attrValueObject.getDataTypeId());

+		assertEquals(s1, attrValueObject.getValue());

+		attrValueObject = it.next();

+		assertEquals(DataTypes.DT_DOUBLE.getId(), attrValueObject.getDataTypeId());

+		assertEquals(s2, attrValueObject.getValue());

+		attrValueObject = it.next();

+		assertEquals(DataTypes.DT_DOUBLE.getId(), attrValueObject.getDataTypeId());

+		assertEquals(s1, attrValueObject.getValue());

+		

+		// lots of args

+		arguments.clear();

+		for (int i = 0; i < 1000; i++) {

+			arguments.add(attr1);

+		}

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		it = bag.getAttributeValues();

+		assertEquals(1000, bag.size());

+		

+	}

+	

+	

+

+	

+	

+	//

+	//

+	//  REST OF DATA TYPES OMITTED 

+	//	because they "should" all work the same

+	//

+	//

+	

+	

+	

+

+}

diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBaseTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBaseTest.java
new file mode 100755
index 0000000..0a967f5
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBaseTest.java
@@ -0,0 +1,121 @@
+/*

+ *                        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.std.functions;

+

+

+import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.assertFalse;

+import static org.junit.Assert.assertTrue;

+

+import org.junit.Test;

+

+import com.att.research.xacml.api.Identifier;

+import com.att.research.xacml.api.XACML3;

+import com.att.research.xacmlatt.pdp.policy.FunctionDefinition;

+import com.att.research.xacmlatt.pdp.std.StdFunctions;

+

+/**

+ * Test functions in the abstract FunctionDefinitionSimpleTest class.

+ * Functions are tested by creating instances of other classes that should have appropriate properties to verify all variations of the responses expected.

+ * 

+ * Note: we do not test getDataTypeId() because all it does is get the String out of the Identity object and we assume that the Data Type Identity objects

+ * are tested enough in everything else that any errors in them will be found and fixed quickly.

+ * 

+ * TO RUN - use jUnit

+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test

+ * 

+ * @author glenngriffin

+ *

+ */

+public class FunctionDefinitionBaseTest {

+	/**

+	 * getId() is pretty trivial, so verifying one should be enough to check that the mechanism is working ok

+	 */

+	@Test

+	public void testGetId() {

+		FunctionDefinition fd = StdFunctions.FD_STRING_EQUAL;

+		Identifier id = fd.getId();

+		assertTrue(XACML3.ID_FUNCTION_STRING_EQUAL.stringValue().equals(id.stringValue()) );

+	}

+

+	/**

+	 * check an instance of every result type that we can deal with

+	 */	

+	@Test

+	public void testGetDataType() {

+		

+//?? Need functions that return each of these data types except for Boolean which is returned by any of the EQUAL functions

+		FunctionDefinition fdstring = StdFunctions.FD_STRING_NORMALIZE_SPACE;

+		assertEquals(XACML3.ID_DATATYPE_STRING, fdstring.getDataTypeId());

+

+		FunctionDefinition fdboolean = StdFunctions.FD_STRING_EQUAL;

+		assertEquals(XACML3.ID_DATATYPE_BOOLEAN, fdboolean.getDataTypeId());

+		

+		FunctionDefinition fdinteger = StdFunctions.FD_INTEGER_ADD;

+		assertEquals(XACML3.ID_DATATYPE_INTEGER, fdinteger.getDataTypeId());

+

+		FunctionDefinition fddouble = StdFunctions.FD_DOUBLE_ADD;

+		assertEquals(XACML3.ID_DATATYPE_DOUBLE, fddouble.getDataTypeId());

+

+		FunctionDefinition fddate = StdFunctions.FD_DATE_BAG;

+		assertEquals(XACML3.ID_DATATYPE_DATE, fddate.getDataTypeId());

+

+		FunctionDefinition fdtime = StdFunctions.FD_TIME_BAG;

+		assertEquals(XACML3.ID_DATATYPE_TIME, fdtime.getDataTypeId());

+

+		FunctionDefinition fddateTime = StdFunctions.FD_DATETIME_BAG;

+		assertEquals(XACML3.ID_DATATYPE_DATETIME, fddateTime.getDataTypeId());

+

+		FunctionDefinition fddayTimeDuration = StdFunctions.FD_DAYTIMEDURATION_FROM_STRING;

+		assertEquals(XACML3.ID_DATATYPE_DAYTIMEDURATION, fddayTimeDuration.getDataTypeId());

+

+		FunctionDefinition fdyearMonthDuration = StdFunctions.FD_YEARMONTHDURATION_FROM_STRING;

+		assertEquals(XACML3.ID_DATATYPE_YEARMONTHDURATION, fdyearMonthDuration.getDataTypeId());

+

+		FunctionDefinition fdanyURI = StdFunctions.FD_ANYURI_FROM_STRING;

+		assertEquals(XACML3.ID_DATATYPE_ANYURI, fdanyURI.getDataTypeId());

+

+		FunctionDefinition fdhexBinary = StdFunctions.FD_HEXBINARY_UNION;

+		assertEquals(XACML3.ID_DATATYPE_HEXBINARY, fdhexBinary.getDataTypeId());

+

+		FunctionDefinition fdbase64Binary = StdFunctions.FD_BASE64BINARY_UNION;

+		assertEquals(XACML3.ID_DATATYPE_BASE64BINARY, fdbase64Binary.getDataTypeId());

+

+		FunctionDefinition fdrfc822Name = StdFunctions.FD_RFC822NAME_FROM_STRING;

+		assertEquals(XACML3.ID_DATATYPE_RFC822NAME, fdrfc822Name.getDataTypeId());

+

+		FunctionDefinition fdx500Name = StdFunctions.FD_X500NAME_FROM_STRING;

+		assertEquals(XACML3.ID_DATATYPE_X500NAME, fdx500Name.getDataTypeId());

+

+//TODO - There are currently no functions that return XPathExpression objects

+//		FunctionDefinition fdxpathExpression = StdFunctions.FD_XPATHEXPRESSION_FROM_STRING;

+//		assertEquals(XACML3.ID_DATATYPE_XPATHEXPRESSION, fdxpathExpression.getDataTypeId());

+

+		FunctionDefinition fdipAddress = StdFunctions.FD_IPADDRESS_FROM_STRING;

+		assertEquals(XACML3.ID_DATATYPE_IPADDRESS, fdipAddress.getDataTypeId());

+

+		FunctionDefinition fddnsName = StdFunctions.FD_DNSNAME_FROM_STRING;

+		assertEquals(XACML3.ID_DATATYPE_DNSNAME, fddnsName.getDataTypeId());

+	}

+	

+	/**

+	 * check the type of return, single vs multiple values

+	 */

+	@Test

+	public void testReturnsBag() {

+		FunctionDefinition fdNotBag = StdFunctions.FD_BOOLEAN_EQUAL;

+		assertFalse(fdNotBag.returnsBag());

+		

+		FunctionDefinitionBag<?> fdBag = (FunctionDefinitionBag<?>) StdFunctions.FD_STRING_BAG;

+		assertTrue(fdBag.returnsBag());

+	}

+	

+}

diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparisonTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparisonTest.java
new file mode 100755
index 0000000..a93bf14
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparisonTest.java
@@ -0,0 +1,1356 @@
+/*

+ *                        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.std.functions;

+

+import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.assertFalse;

+import static org.junit.Assert.assertTrue;

+import static org.junit.Assert.fail;

+

+import java.util.ArrayList;

+import java.util.Calendar;

+import java.util.Date;

+import java.util.List;

+

+import org.junit.Test;

+

+import com.att.research.xacml.api.XACML3;

+import com.att.research.xacml.std.datatypes.DataTypes;

+import com.att.research.xacml.std.datatypes.ISO8601Date;

+import com.att.research.xacml.std.datatypes.ISO8601DateTime;

+import com.att.research.xacml.std.datatypes.ISO8601Time;

+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue;

+import com.att.research.xacmlatt.pdp.std.StdFunctions;

+

+/**

+ * Test FunctionDefinitionComparison

+ * 

+ * TO RUN - use jUnit

+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test

+ * 

+ * @author glenngriffin

+ *

+ */

+public class FunctionDefinitionComparisonTest {

+

+	/*

+	 * variables useful in the following tests

+	 */

+	List<FunctionArgument> arguments = new ArrayList<FunctionArgument>();

+	

+	FunctionArgumentAttributeValue stringAttr1 = null;

+	FunctionArgumentAttributeValue stringAttr1a = null;

+	FunctionArgumentAttributeValue stringAttr2 = null;

+	FunctionArgumentAttributeValue stringAttrNeg1 = null;

+

+

+	FunctionArgumentAttributeValue intAttr1 = null;

+	FunctionArgumentAttributeValue intAttr1a = null;

+	FunctionArgumentAttributeValue intAttr2 = null;

+	FunctionArgumentAttributeValue intAttr0 = null;

+	FunctionArgumentAttributeValue intAttrNeg1 = null;

+	

+	FunctionArgumentAttributeValue attr1 = null;

+	FunctionArgumentAttributeValue attr1a = null;

+	FunctionArgumentAttributeValue attr2 = null;

+	FunctionArgumentAttributeValue attrNeg1 = null;

+	

+	FunctionArgumentAttributeValue attrDateToday = null;

+	FunctionArgumentAttributeValue attrDateSameDay = null;

+	FunctionArgumentAttributeValue attrDateTommorrow = null;

+	FunctionArgumentAttributeValue attrDateYesterday = null;

+	FunctionArgumentAttributeValue attrDateWithTimeZone = null;

+	FunctionArgumentAttributeValue attrDateNoTimeZone = null;

+

+	

+	FunctionArgumentAttributeValue attrTimeToday = null;

+	FunctionArgumentAttributeValue attrTimeSameDay = null;

+	FunctionArgumentAttributeValue attrTimeTommorrow = null;

+	FunctionArgumentAttributeValue attrTimeYesterday = null;

+	FunctionArgumentAttributeValue attrTimeWithTimeZone = null;

+	FunctionArgumentAttributeValue attrTimeNoTimeZone = null;

+	

+	FunctionArgumentAttributeValue attrDateTimeToday = null;

+	FunctionArgumentAttributeValue attrDateTimeSameDay = null;

+	FunctionArgumentAttributeValue attrDateTimeTommorrow = null;

+	FunctionArgumentAttributeValue attrDateTimeYesterday = null;

+	FunctionArgumentAttributeValue attrDateTimeWithTimeZone = null;

+	FunctionArgumentAttributeValue attrDateTimeNoTimeZone = null;

+	

+	/**

+	 * Set up some common variables on startup

+	 */

+	public FunctionDefinitionComparisonTest() {

+	try {

+		stringAttr1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("abc"));

+		stringAttr1a = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("abc"));

+		stringAttr2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("def"));

+		stringAttrNeg1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("AAA"));

+

+

+		intAttr1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1));

+		intAttr1a = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1));

+		intAttr2 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(2));

+		intAttr0 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(0));

+		intAttrNeg1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(-1));

+		

+		attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.0));

+		attr1a = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.0));

+		attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(2.4));

+		attrNeg1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(-1.0));

+		

+		// create dates

+		Calendar calendar = Calendar.getInstance();

+		Date today = calendar.getTime();

+		Date longAgo = new Date(1234);

+		// create a date that is different than "today" but within the same day (i.e. has a different hour)

+		if (calendar.get(Calendar.HOUR_OF_DAY) > 3) {

+			calendar.set(Calendar.HOUR_OF_DAY, 3);

+		} else {

+			calendar.set(Calendar.HOUR_OF_DAY, 5);

+		}

+		Date todayPlus = calendar.getTime();

+		calendar.add(Calendar.DATE, 1);

+		Date tommorrow = calendar.getTime();

+		attrDateToday = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(today));

+		attrDateSameDay = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(todayPlus));

+		attrDateTommorrow = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(tommorrow));

+		attrDateYesterday = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(longAgo));

+		ISO8601Date isoDate = new ISO8601Date(1920, 5, 8);

+		attrDateNoTimeZone = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(isoDate));

+		isoDate = new ISO8601Date("GMT+00:02", 1920, 5, 8);

+		attrDateWithTimeZone = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(isoDate));

+		

+		// create Times

+		ISO8601Time isoTime = new ISO8601Time(14, 43, 12, 145);

+		attrTimeToday = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue(isoTime));

+		attrTimeSameDay = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue(isoTime));

+		isoTime = new ISO8601Time(18, 53, 34, 423);

+		attrTimeTommorrow = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue(isoTime));

+		isoTime = new ISO8601Time(7, 34, 6,543);

+		attrTimeYesterday = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue(isoTime));

+		isoTime = new ISO8601Time(12, 12, 12, 12);

+		attrTimeNoTimeZone = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue(isoTime));

+		isoTime = new ISO8601Time("GMT:+00:03", 12, 12, 12, 12);

+		attrTimeWithTimeZone = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue(isoTime));

+		

+		// create DateTimes

+		isoDate = new ISO8601Date(1920, 5, 8);

+		isoTime = new ISO8601Time( 18, 53, 34, 423);

+		ISO8601DateTime isoDateTime = new ISO8601DateTime((String)null, 1920, 5, 8, 18, 53, 34, 423);

+		attrDateTimeToday = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(isoDateTime));

+		attrDateTimeSameDay = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(isoDateTime));

+		isoTime = new ISO8601Time(20, 53, 34, 423);

+		isoDateTime = new ISO8601DateTime((String)null, 1920, 5, 8, 20, 53, 34, 423);

+		attrDateTimeTommorrow = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(isoDateTime));

+		isoTime = new ISO8601Time(7, 34, 6,543);

+		isoDateTime = new ISO8601DateTime((String)null, 1920, 5, 8, 7, 34, 6, 543);

+		attrDateTimeYesterday = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(isoDateTime));

+		isoTime = new ISO8601Time(12, 12, 12, 12);

+		isoDateTime = new ISO8601DateTime((String)null, 1920, 5, 8, 12, 12, 12, 12);

+		attrDateTimeNoTimeZone = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(isoDateTime));

+		isoTime = new ISO8601Time("GMT:+00:03", 12, 12, 12, 12);

+		isoDate = new ISO8601Date("GMT:+00:03", 1920, 5, 8);

+		isoDateTime = new ISO8601DateTime("GMT:+00:03", 1920, 5, 8, 12, 12, 12, 12);

+		attrDateTimeWithTimeZone = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(isoDateTime));

+		

+		

+		

+		

+	} catch (Exception e) {

+		fail("Error creating values e="+ e);

+	}

+	}

+	

+	/**

+	 * String

+	 */

+	@Test

+	public void testString_GT() {

+		

+		FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_STRING_GREATER_THAN;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_STRING_GREATER_THAN, fd.getId());

+		assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		// first == second

+		arguments.add(stringAttr1);

+		arguments.add(stringAttr1a);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+

+		// check first < second

+		arguments.clear();

+		arguments.add(stringAttr1);

+		arguments.add(stringAttr2);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// first > second

+		arguments.clear();

+		arguments.add(stringAttr1);

+		arguments.add(stringAttrNeg1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		// test bad args data types?  Not needed?

+		arguments.clear();

+		arguments.add(intAttr1);

+		arguments.add(stringAttr1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+	}

+	

+	@Test

+	public void testString_GTE() {

+		

+		FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_STRING_GREATER_THAN_OR_EQUAL;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_STRING_GREATER_THAN_OR_EQUAL, fd.getId());

+		assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		// first == second

+		arguments.add(stringAttr1);

+		arguments.add(stringAttr1a);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		// check first < second

+		arguments.clear();

+		arguments.add(stringAttr1);

+		arguments.add(stringAttr2);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// first > second

+		arguments.clear();

+		arguments.add(stringAttr1);

+		arguments.add(stringAttrNeg1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+	}

+	

+	@Test

+	public void testString_LT() {

+		

+		FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_STRING_LESS_THAN;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_STRING_LESS_THAN, fd.getId());

+		assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		// first == second

+		arguments.add(stringAttr1);

+		arguments.add(stringAttr1a);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+

+		// check first < second

+		arguments.clear();

+		arguments.add(stringAttr1);

+		arguments.add(stringAttr2);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// first > second

+		arguments.clear();

+		arguments.add(stringAttr1);

+		arguments.add(stringAttrNeg1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+	}

+	

+	@Test

+	public void testString_LTE() {

+		

+		FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_STRING_LESS_THAN_OR_EQUAL;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_STRING_LESS_THAN_OR_EQUAL, fd.getId());

+		assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		// first == second

+		arguments.add(stringAttr1);

+		arguments.add(stringAttr1a);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		// check first < second

+		arguments.clear();

+		arguments.add(stringAttr1);

+		arguments.add(stringAttr2);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// first > second

+		arguments.clear();

+		arguments.add(stringAttr1);

+		arguments.add(stringAttrNeg1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+	}

+

+	

+	

+	/**

+	 * Integer

+	 */

+	@Test

+	public void testInteger_GT() {

+		

+		FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_INTEGER_GREATER_THAN;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_INTEGER_GREATER_THAN, fd.getId());

+		assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		// first == second

+		arguments.add(intAttr1);

+		arguments.add(intAttr1a);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+

+		// check first < second

+		arguments.clear();

+		arguments.add(intAttr1);

+		arguments.add(intAttr2);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// first > second

+		arguments.clear();

+		arguments.add(intAttr1);

+		arguments.add(intAttrNeg1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		// test bad args data types?  Not needed?

+		arguments.clear();

+		arguments.add(stringAttr1);

+		arguments.add(intAttr1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+	}

+	

+	@Test

+	public void testInteger_GTE() {

+		

+		FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_INTEGER_GREATER_THAN_OR_EQUAL;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_INTEGER_GREATER_THAN_OR_EQUAL, fd.getId());

+		assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		// first == second

+		arguments.add(intAttr1);

+		arguments.add(intAttr1a);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		// check first < second

+		arguments.clear();

+		arguments.add(intAttr1);

+		arguments.add(intAttr2);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// first > second

+		arguments.clear();

+		arguments.add(intAttr1);

+		arguments.add(intAttrNeg1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+	}

+	

+	@Test

+	public void testInteger_LT() {

+		

+		FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_INTEGER_LESS_THAN;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_INTEGER_LESS_THAN, fd.getId());

+		assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		// first == second

+		arguments.add(intAttr1);

+		arguments.add(intAttr1a);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+

+		// check first < second

+		arguments.clear();

+		arguments.add(intAttr1);

+		arguments.add(intAttr2);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// first > second

+		arguments.clear();

+		arguments.add(intAttr1);

+		arguments.add(intAttrNeg1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+	}

+	

+	@Test

+	public void testInteger_LTE() {

+		

+		FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_INTEGER_LESS_THAN_OR_EQUAL;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_INTEGER_LESS_THAN_OR_EQUAL, fd.getId());

+		assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		// first == second

+		arguments.add(intAttr1);

+		arguments.add(intAttr1a);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		// check first < second

+		arguments.clear();

+		arguments.add(intAttr1);

+		arguments.add(intAttr2);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// first > second

+		arguments.clear();

+		arguments.add(intAttr1);

+		arguments.add(intAttrNeg1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+	}

+	

+	

+	

+	

+	/**

+	 * Double

+	 */

+	@Test

+	public void testDouble_GT() {

+

+		FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DOUBLE_GREATER_THAN;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_DOUBLE_GREATER_THAN, fd.getId());

+		assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		// first == second

+		arguments.add(attr1);

+		arguments.add(attr1a);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+

+		// first < second

+		arguments.clear();

+		arguments.add(attr1);

+		arguments.add(attr2);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// first > second

+		arguments.clear();

+		arguments.add(attr1);

+		arguments.add(attrNeg1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		// test bad args data types?  Not needed?

+		arguments.clear();

+		arguments.add(stringAttr1);

+		arguments.add(intAttr1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+

+	}

+	

+	@Test

+	public void testDouble_GTE() {

+

+		FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DOUBLE_GREATER_THAN_OR_EQUAL;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_DOUBLE_GREATER_THAN_OR_EQUAL, fd.getId());

+		assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		// first == second

+		arguments.add(attr1);

+		arguments.add(attr1a);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		// first < second

+		arguments.clear();

+		arguments.add(attr1);

+		arguments.add(attr2);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// first > second

+		arguments.clear();

+		arguments.add(attr1);

+		arguments.add(attrNeg1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+	}

+	

+	@Test

+	public void testDouble_LT() {

+

+		FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DOUBLE_LESS_THAN;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_DOUBLE_LESS_THAN, fd.getId());

+		assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		// first == second

+		arguments.add(attr1);

+		arguments.add(attr1a);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+

+		// first < second

+		arguments.clear();

+		arguments.add(attr1);

+		arguments.add(attr2);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// first > second

+		arguments.clear();

+		arguments.add(attr1);

+		arguments.add(attrNeg1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+	}

+	

+	@Test

+	public void testDouble_LTE() {

+

+		FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DOUBLE_LESS_THAN_OR_EQUAL;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_DOUBLE_LESS_THAN_OR_EQUAL, fd.getId());

+		assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		// first == second

+		arguments.add(attr1);

+		arguments.add(attr1a);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		// first < second

+		arguments.clear();

+		arguments.add(attr1);

+		arguments.add(attr2);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// first > second

+		arguments.clear();

+		arguments.add(attr1);

+		arguments.add(attrNeg1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+	}

+

+	

+	

+	/**

+	 * Date

+	 */

+	

+	@Test

+	public void testDate_GT() {

+

+		FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DATE_GREATER_THAN;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_DATE_GREATER_THAN, fd.getId());

+		assertEquals(DataTypes.DT_DATE.getId(), fd.getDataTypeArgs().getId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		// first == second

+		arguments.add(attrDateToday);

+		arguments.add(attrDateSameDay);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+

+		// first < second

+		arguments.clear();

+		arguments.add(attrDateToday);

+		arguments.add(attrDateTommorrow);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// first > second

+		arguments.clear();

+		arguments.add(attrDateToday);

+		arguments.add(attrDateYesterday);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		// test bad args data types?  One with TimeZone and one without

+		arguments.clear();

+		arguments.add(stringAttr1);

+		arguments.add(intAttr1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+

+		// test with TimeZone vs without

+		arguments.clear();

+		arguments.add(attrDateWithTimeZone);

+		arguments.add(attrDateNoTimeZone);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:date-greater-than Cannot compare this ISO8601DateTime with non-time-zoned ISO8601DateTime", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+	

+

+	}

+

+	@Test

+	public void testDate_GTE() {

+

+		FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DATE_GREATER_THAN_OR_EQUAL;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_DATE_GREATER_THAN_OR_EQUAL, fd.getId());

+		assertEquals(DataTypes.DT_DATE.getId(), fd.getDataTypeArgs().getId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		// first == second

+		arguments.add(attrDateToday);

+		arguments.add(attrDateSameDay);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		// first < second

+		arguments.clear();

+		arguments.add(attrDateToday);

+		arguments.add(attrDateTommorrow);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// first > second

+		arguments.clear();

+		arguments.add(attrDateToday);

+		arguments.add(attrDateYesterday);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+	}

+	

+	@Test

+	public void testDate_LT() {

+

+		FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DATE_LESS_THAN;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_DATE_LESS_THAN, fd.getId());

+		assertEquals(DataTypes.DT_DATE.getId(), fd.getDataTypeArgs().getId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		// first == second

+		arguments.add(attrDateToday);

+		arguments.add(attrDateSameDay);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+

+		// first < second

+		arguments.clear();

+		arguments.add(attrDateToday);

+		arguments.add(attrDateTommorrow);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// first > second

+		arguments.clear();

+		arguments.add(attrDateToday);

+		arguments.add(attrDateYesterday);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+	}

+	

+	@Test

+	public void testDate_LTE() {

+

+		FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DATE_LESS_THAN_OR_EQUAL;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_DATE_LESS_THAN_OR_EQUAL, fd.getId());

+		assertEquals(DataTypes.DT_DATE.getId(), fd.getDataTypeArgs().getId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+

+		// first == second

+		arguments.add(attrDateToday);

+		arguments.add(attrDateSameDay);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		// first < second

+		arguments.clear();

+		arguments.add(attrDateToday);

+		arguments.add(attrDateTommorrow);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// first > second

+		arguments.clear();

+		arguments.add(attrDateToday);

+		arguments.add(attrDateYesterday);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+	}

+	

+	

+	

+	

+	

+	

+	

+	/**

+	 * Time

+	 */

+	

+	@Test

+	public void testTime_GT() {

+

+		FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_TIME_GREATER_THAN;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_TIME_GREATER_THAN, fd.getId());

+		assertEquals(DataTypes.DT_TIME.getId(), fd.getDataTypeArgs().getId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		// first == second

+		arguments.add(attrTimeToday);

+		arguments.add(attrTimeSameDay);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+

+		// first < second

+		arguments.clear();

+		arguments.add(attrTimeToday);

+		arguments.add(attrTimeTommorrow);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// first > second

+		arguments.clear();

+		arguments.add(attrTimeToday);

+		arguments.add(attrTimeYesterday);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		// test bad args data types?  One with TimeZone and one without

+		arguments.clear();

+		arguments.add(stringAttr1);

+		arguments.add(intAttr1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+

+		// test with TimeZone vs without

+		arguments.clear();

+		arguments.add(attrTimeWithTimeZone);

+		arguments.add(attrTimeNoTimeZone);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:time-greater-than Cannot compare this ISO8601DateTime with non-time-zoned ISO8601DateTime", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+	

+

+	}

+	

+	@Test

+	public void testTime_GTE() {

+

+		FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_TIME_GREATER_THAN_OR_EQUAL;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_TIME_GREATER_THAN_OR_EQUAL, fd.getId());

+		assertEquals(DataTypes.DT_TIME.getId(), fd.getDataTypeArgs().getId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		// first == second

+		arguments.add(attrTimeToday);

+		arguments.add(attrTimeSameDay);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		// first < second

+		arguments.clear();

+		arguments.add(attrTimeToday);

+		arguments.add(attrTimeTommorrow);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// first > second

+		arguments.clear();

+		arguments.add(attrTimeToday);

+		arguments.add(attrTimeYesterday);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+	}

+	

+	@Test

+	public void testTime_LT() {

+

+		FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_TIME_LESS_THAN;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_TIME_LESS_THAN, fd.getId());

+		assertEquals(DataTypes.DT_TIME.getId(), fd.getDataTypeArgs().getId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		// first == second

+		arguments.add(attrTimeToday);

+		arguments.add(attrTimeSameDay);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+

+		// first < second

+		arguments.clear();

+		arguments.add(attrTimeToday);

+		arguments.add(attrTimeTommorrow);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// first > second

+		arguments.clear();

+		arguments.add(attrTimeToday);

+		arguments.add(attrTimeYesterday);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+	}

+	

+	@Test

+	public void testTime_LTE() {

+

+		FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_TIME_LESS_THAN_OR_EQUAL;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_TIME_LESS_THAN_OR_EQUAL, fd.getId());

+		assertEquals(DataTypes.DT_TIME.getId(), fd.getDataTypeArgs().getId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		// first == second

+		arguments.add(attrTimeToday);

+		arguments.add(attrTimeSameDay);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		// first < second

+		arguments.clear();

+		arguments.add(attrTimeToday);

+		arguments.add(attrTimeTommorrow);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// first > second

+		arguments.clear();

+		arguments.add(attrTimeToday);

+		arguments.add(attrTimeYesterday);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+	}

+	

+	

+	

+	

+	

+	/**

+	 * Time-in-range

+	 */

+	@Test

+	public void testTime_in_range() {

+

+		FunctionDefinitionTimeInRange<?> fd = (FunctionDefinitionTimeInRange<?>) StdFunctions.FD_TIME_IN_RANGE;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_TIME_IN_RANGE, fd.getId());

+		assertEquals(DataTypes.DT_TIME.getId(), fd.getDataTypeArgs().getId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(3), fd.getNumArgs());

+		

+		// arg 0 in range of others

+		arguments.add(attrTimeToday);

+		arguments.add(attrTimeYesterday);

+		arguments.add(attrTimeTommorrow);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// below range

+		arguments.clear();

+		arguments.add(attrTimeYesterday);

+		arguments.add(attrTimeToday);

+		arguments.add(attrTimeTommorrow);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// above range

+		arguments.clear();

+		arguments.add(attrTimeTommorrow);

+		arguments.add(attrTimeYesterday);

+		arguments.add(attrTimeToday);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// range bad

+		arguments.clear();

+		arguments.add(attrTimeToday);

+		arguments.add(attrTimeTommorrow);

+		arguments.add(attrTimeYesterday);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// bad types

+		arguments.clear();

+		arguments.add(attrDateTimeWithTimeZone);

+		arguments.add(attrDateTimeNoTimeZone);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:time-in-range Expected 3 arguments, got 2", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+	

+		arguments.clear();

+		arguments.add(attrDateTimeWithTimeZone);

+		arguments.add(attrDateTimeNoTimeZone);

+		arguments.add(intAttr1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:time-in-range Expected data type 'time' saw 'dateTime' at arg index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+	

+	}

+

+	

+	

+	

+	

+	

+	/**

+	 * DateTime

+	 */

+	

+	@Test

+	public void testDateTime_GT() {

+

+		FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DATETIME_GREATER_THAN;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_DATETIME_GREATER_THAN, fd.getId());

+		assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeArgs().getId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		// first == second

+		arguments.add(attrDateTimeToday);

+		arguments.add(attrDateTimeSameDay);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+

+		// first < second

+		arguments.clear();

+		arguments.add(attrDateTimeToday);

+		arguments.add(attrDateTimeTommorrow);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// first > second

+		arguments.clear();

+		arguments.add(attrDateTimeToday);

+		arguments.add(attrDateTimeYesterday);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		// test bad args data types?  One with TimeZone and one without

+		arguments.clear();

+		arguments.add(stringAttr1);

+		arguments.add(intAttr1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+

+		// test with TimeZone vs without

+		arguments.clear();

+		arguments.add(attrDateTimeWithTimeZone);

+		arguments.add(attrDateTimeNoTimeZone);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dateTime-greater-than Cannot compare this ISO8601DateTime with non-time-zoned ISO8601DateTime", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+	

+

+	}

+	

+	@Test

+	public void testDateTime_GTE() {

+

+		FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DATETIME_GREATER_THAN_OR_EQUAL;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_DATETIME_GREATER_THAN_OR_EQUAL, fd.getId());

+		assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeArgs().getId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		// first == second

+		arguments.add(attrDateTimeToday);

+		arguments.add(attrDateTimeSameDay);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		// first < second

+		arguments.clear();

+		arguments.add(attrDateTimeToday);

+		arguments.add(attrDateTimeTommorrow);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// first > second

+		arguments.clear();

+		arguments.add(attrDateTimeToday);

+		arguments.add(attrDateTimeYesterday);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+	}

+	

+	@Test

+	public void testDateTime_LT() {

+

+		FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DATETIME_LESS_THAN;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_DATETIME_LESS_THAN, fd.getId());

+		assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeArgs().getId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		// first == second

+		arguments.add(attrDateTimeToday);

+		arguments.add(attrDateTimeSameDay);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+

+		// first < second

+		arguments.clear();

+		arguments.add(attrDateTimeToday);

+		arguments.add(attrDateTimeTommorrow);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// first > second

+		arguments.clear();

+		arguments.add(attrDateTimeToday);

+		arguments.add(attrDateTimeYesterday);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+	}

+	

+	@Test

+	public void testDateTime_LTE() {

+

+		FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DATETIME_LESS_THAN_OR_EQUAL;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_DATETIME_LESS_THAN_OR_EQUAL, fd.getId());

+		assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeArgs().getId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		// first == second

+		arguments.add(attrDateTimeToday);

+		arguments.add(attrDateTimeSameDay);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		// first < second

+		arguments.clear();

+		arguments.add(attrDateTimeToday);

+		arguments.add(attrDateTimeTommorrow);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// first > second

+		arguments.clear();

+		arguments.add(attrDateTimeToday);

+		arguments.add(attrDateTimeYesterday);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+	}

+

+

+

+}
\ No newline at end of file
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmeticTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmeticTest.java
new file mode 100755
index 0000000..d502375
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmeticTest.java
@@ -0,0 +1,1582 @@
+package com.att.research.xacmlatt.pdp.std.functions;

+

+import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.assertFalse;

+import static org.junit.Assert.assertTrue;

+import static org.junit.Assert.fail;

+

+import java.util.ArrayList;

+import java.util.List;

+

+import org.junit.Test;

+

+import com.att.research.xacml.api.XACML3;

+import com.att.research.xacml.std.datatypes.DataTypes;

+import com.att.research.xacml.std.datatypes.ISO8601Date;

+import com.att.research.xacml.std.datatypes.ISO8601DateTime;

+import com.att.research.xacml.std.datatypes.ISO8601Time;

+import com.att.research.xacml.std.datatypes.ISO8601TimeZone;

+import com.att.research.xacml.std.datatypes.XPathDayTimeDuration;

+import com.att.research.xacml.std.datatypes.XPathYearMonthDuration;

+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue;

+import com.att.research.xacmlatt.pdp.std.StdFunctions;

+

+/**

+ * Test of PDP Functions (See XACML core spec section A.3)

+ * 

+ * TO RUN - use jUnit

+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test

+ * 

+ * @author glenngriffin

+ *

+ */

+public class FunctionDefinitionDateTimeArithmeticTest {

+

+

+	/*

+	 * variables useful in the following tests

+	 */

+	List<FunctionArgument> arguments = new ArrayList<FunctionArgument>();

+	

+	ExpressionResult res;

+

+	

+	@Test

+	public void testDateTime_add_dayTimeDuration() {

+		// Date objects to be adjusted

+		ISO8601DateTime dateTimeStdExample1 = new ISO8601DateTime(null, 

+				new ISO8601Date(2000, 1, 12), 

+				new ISO8601Time(12, 13, 14, 0));

+		ISO8601DateTime dateTimeMsecs = new ISO8601DateTime(null, 

+				new ISO8601Date(2000, 1, 12), 

+				new ISO8601Time(12, 13, 14, 777));

+		ISO8601DateTime dateTimeCrossover = new ISO8601DateTime(null, 

+				new ISO8601Date(2000, 12, 31), 

+				new ISO8601Time(23, 59, 30, 1));

+		ISO8601DateTime dateTimeBC = new ISO8601DateTime(null, 

+				new ISO8601Date(-2000, 1, 12), 

+				new ISO8601Time(12, 13, 14, 0));

+		ISO8601TimeZone timeZone0 = new ISO8601TimeZone(0);

+		ISO8601TimeZone timeZone5 = new ISO8601TimeZone(5 * 60);

+		ISO8601DateTime dateTimeTimeZone0 = new ISO8601DateTime(timeZone0, 

+				new ISO8601Date(timeZone0, 2000, 1, 12), 

+				new ISO8601Time(timeZone0, 12, 13, 14, 0));

+		ISO8601DateTime dateTimeTimeZone5 = new ISO8601DateTime(timeZone5, 

+				new ISO8601Date(timeZone5, 2000, 1, 12), 

+				new ISO8601Time(timeZone5, 12, 13, 14, 0));

+		ISO8601DateTime dateTimeIIC102Result = null;

+		

+		// Durations

+		XPathDayTimeDuration duration0 = new XPathDayTimeDuration(1, 0, 0, 0, 0);

+		XPathDayTimeDuration durationStdExample1 = new XPathDayTimeDuration(1, 5, 7, 10, 3.3);

+		XPathDayTimeDuration durationNStdExample1 = new XPathDayTimeDuration(-1, 5, 7, 10, 3.3);

+		XPathDayTimeDuration durationMsecs = new XPathDayTimeDuration(1, 5, 7, 10, 3.223);

+		XPathDayTimeDuration durationCrossover = new XPathDayTimeDuration(1, 0, 0, 0, 29.999);

+

+		// ARGS declarations

+		// Dates

+		FunctionArgumentAttributeValue attrDateTimeStdExample1 = null;

+		FunctionArgumentAttributeValue attrDateTimeMsecs = null;

+		FunctionArgumentAttributeValue attrDateTimeCrossover = null;

+		FunctionArgumentAttributeValue attrDateTimeBC = null;

+		FunctionArgumentAttributeValue attrDateTimeTimeZone0 = null;

+		FunctionArgumentAttributeValue attrDateTimeTimeZone5 = null;

+		FunctionArgumentAttributeValue attrDateTimeIIC102 = null;

+

+		// Durations

+		FunctionArgumentAttributeValue attrDuration0 = null;

+		FunctionArgumentAttributeValue attrDurationStdExample1 = null;

+		FunctionArgumentAttributeValue attrDurationNStdExample1 = null;

+		FunctionArgumentAttributeValue attrDurationMsecs = null;

+		FunctionArgumentAttributeValue attrDurationCrossover = null;

+		FunctionArgumentAttributeValue attrDurationIIC102 = null;

+

+		// misc bad

+		FunctionArgumentAttributeValue attrNull = null;

+		FunctionArgumentAttributeValue attrBlank = null;

+		FunctionArgumentAttributeValue attrInteger = null;

+		// set values

+		try {

+			// Date attrs

+			attrDateTimeStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeStdExample1));

+			attrDateTimeMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeMsecs));

+			attrDateTimeCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeCrossover));

+			attrDateTimeBC = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeBC));

+			attrDateTimeTimeZone0 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeTimeZone0));

+			attrDateTimeTimeZone5 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeTimeZone5));

+			attrDateTimeIIC102 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(DataTypes.DT_DATETIME.convert("2002-03-22T08:23:47-05:00")));

+

+			dateTimeIIC102Result = DataTypes.DT_DATETIME.convert("2002-03-27T10:23:47-05:00");

+			

+			// Duration attrs

+			attrDuration0 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(duration0));

+			attrDurationStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(durationStdExample1));

+			attrDurationNStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(durationNStdExample1));

+			attrDurationMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(durationMsecs));

+			attrDurationCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(durationCrossover));

+			attrDurationIIC102 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue("P5DT2H0M0S"));

+

+			// misc bad

+			attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(""));

+			attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(null));

+			attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234));

+		} catch (Exception e) {

+			fail("creating attributes e="+ e);

+		}

+		

+		FunctionDefinitionDateTimeArithmetic<?,?> fd = (FunctionDefinitionDateTimeArithmetic<?,?>) StdFunctions.FD_DATETIME_ADD_DAYTIMEDURATION;

+

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_DATETIME_ADD_DAYTIMEDURATION, fd.getId());

+		assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		

+		// Duration = 0 => same as original

+		arguments.clear();

+		arguments.add(attrDateTimeStdExample1);

+		arguments.add(attrDuration0);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());

+		ISO8601DateTime resValue = (ISO8601DateTime)res.getValue().getValue();

+		assertEquals(dateTimeStdExample1, resValue);

+

+		

+		// simple positive operation

+		arguments.clear();

+		arguments.add(attrDateTimeStdExample1);

+		arguments.add(attrDurationStdExample1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());

+		resValue = (ISO8601DateTime)res.getValue().getValue();

+		ISO8601DateTime testResponse = new ISO8601DateTime(

+				null,

+				new ISO8601Date(2000, 1, 17),

+				new ISO8601Time(19, 23, 17, 300) );

+		assertEquals(testResponse, resValue);	

+		

+		// negative operation

+		arguments.clear();

+		arguments.add(attrDateTimeStdExample1);

+		arguments.add(attrDurationNStdExample1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());

+		resValue = (ISO8601DateTime)res.getValue().getValue();

+		testResponse = new ISO8601DateTime(

+				null,

+				new ISO8601Date(2000, 1, 7),

+				new ISO8601Time(5, 3, 10, 700) );

+		assertEquals(testResponse, resValue);

+		

+		// millisecs work correctly

+		arguments.clear();

+		arguments.add(attrDateTimeMsecs);

+		arguments.add(attrDurationMsecs);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());

+		resValue = (ISO8601DateTime)res.getValue().getValue();

+		testResponse = new ISO8601DateTime(

+				null,

+				new ISO8601Date(2000, 1, 17),

+				new ISO8601Time(19, 23, 18, 0) );

+		assertEquals(testResponse, resValue);

+	

+		// cross minute => cross day => cross month => cross year

+		arguments.clear();

+		arguments.add(attrDateTimeCrossover);

+		arguments.add(attrDurationCrossover);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());

+		resValue = (ISO8601DateTime)res.getValue().getValue();

+		testResponse = new ISO8601DateTime(

+				null,

+				new ISO8601Date(2001, 1, 1),

+				new ISO8601Time(0, 0, 0, 0) );

+		assertEquals(testResponse, resValue);

+		

+		// negative (BC) original date add goes the right direction

+		arguments.clear();

+		arguments.add(attrDateTimeBC);

+		arguments.add(attrDurationStdExample1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());

+		resValue = (ISO8601DateTime)res.getValue().getValue();

+		testResponse = new ISO8601DateTime(

+				null,

+				new ISO8601Date(-2000, 1, 17),

+				new ISO8601Time(19, 23, 17, 300) );

+		assertEquals(testResponse, resValue);	

+		

+		// non-null timezone not changed

+		// original has timezone offset = 0

+		arguments.clear();

+		arguments.add(attrDateTimeTimeZone0);

+		arguments.add(attrDurationStdExample1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());

+		resValue = (ISO8601DateTime)res.getValue().getValue();

+		testResponse = new ISO8601DateTime(

+				timeZone0,

+				new ISO8601Date(timeZone0, 2000, 1, 17),

+				new ISO8601Time(timeZone0, 19, 23, 17, 300) );

+		assertEquals(testResponse, resValue);

+		

+		// original has timezone offset not 0

+		arguments.clear();

+		arguments.add(attrDateTimeTimeZone5);

+		arguments.add(attrDurationStdExample1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());

+		resValue = (ISO8601DateTime)res.getValue().getValue();

+		testResponse = new ISO8601DateTime(

+				timeZone5,

+				new ISO8601Date(timeZone5, 2000, 1, 17),

+				new ISO8601Time(timeZone5, 19, 23, 17, 300) );

+		assertEquals(testResponse, resValue);

+		

+		// conformance test IIC102

+		arguments.clear();

+		arguments.add(attrDateTimeIIC102);

+		arguments.add(attrDurationIIC102);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());

+		resValue = (ISO8601DateTime)res.getValue().getValue();

+		assertEquals(dateTimeIIC102Result, resValue);

+

+		// empty non-null first arg

+		arguments.clear();

+		arguments.add(attrBlank);

+		arguments.add(attrDurationStdExample1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dateTime-add-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+

+		// empty non-null second arg

+		arguments.clear();

+		arguments.add(attrDateTimeStdExample1);

+		arguments.add(attrBlank);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dateTime-add-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+

+		// two blanks

+		arguments.clear();

+		arguments.add(attrBlank);

+		arguments.add(attrBlank);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dateTime-add-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+			

+		// null firat arg

+		arguments.clear();

+		arguments.add(attrNull);

+		arguments.add(attrBlank);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dateTime-add-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+

+		// null second arg

+		arguments.clear();

+		arguments.add(attrDateTimeStdExample1);

+		arguments.add(attrNull);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dateTime-add-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// bad arg type

+		arguments.clear();

+		arguments.add(attrInteger);

+		arguments.add(attrDurationStdExample1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dateTime-add-dayTimeDuration Expected data type 'dateTime' saw 'integer'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// null second arg

+		arguments.clear();

+		arguments.add(attrDateTimeStdExample1);

+		arguments.add(attrNull);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dateTime-add-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+	}

+	

+

+	

+	@Test

+	public void testDateTime_subtract_dayTimeDuration() {

+		// Date objects to be adjusted

+		ISO8601DateTime dateTimeStdExample1 = new ISO8601DateTime(null, 

+				new ISO8601Date(2000, 1, 12), 

+				new ISO8601Time(12, 13, 14, 0));

+		ISO8601DateTime dateTimeMsecs = new ISO8601DateTime(null, 

+				new ISO8601Date(2000, 1, 12), 

+				new ISO8601Time(12, 13, 14, 777));

+		ISO8601DateTime dateTimeCrossover = new ISO8601DateTime(null, 

+				new ISO8601Date(2001, 1, 1),

+				new ISO8601Time(0, 0, 0, 0) );

+		ISO8601DateTime dateTimeBC = new ISO8601DateTime(null, 

+				new ISO8601Date(-2000, 1, 12), 

+				new ISO8601Time(12, 13, 14, 0));

+		ISO8601TimeZone timeZone0 = new ISO8601TimeZone(0);

+		ISO8601TimeZone timeZone5 = new ISO8601TimeZone(5 * 60);

+		ISO8601DateTime dateTimeTimeZone0 = new ISO8601DateTime(timeZone0, 

+				new ISO8601Date(timeZone0, 2000, 1, 12), 

+				new ISO8601Time(timeZone0, 12, 13, 14, 0));

+		ISO8601DateTime dateTimeTimeZone5 = new ISO8601DateTime(timeZone5, 

+				new ISO8601Date(timeZone5, 2000, 1, 12), 

+				new ISO8601Time(timeZone5, 12, 13, 14, 0));

+		

+		// Durations

+		XPathDayTimeDuration duration0 = new XPathDayTimeDuration(1, 0, 0, 0, 0);

+		XPathDayTimeDuration durationStdExample1 = new XPathDayTimeDuration(1, 5, 7, 10, 3.3);

+		XPathDayTimeDuration durationNStdExample1 = new XPathDayTimeDuration(-1, 5, 7, 10, 3.3);

+		XPathDayTimeDuration durationMsecs = new XPathDayTimeDuration(1, 5, 7, 10, 14.778);

+		XPathDayTimeDuration durationCrossover = new XPathDayTimeDuration(1, 0, 0, 0, 29.999);

+

+		// ARGS declarations

+		// Dates

+		FunctionArgumentAttributeValue attrDateTimeStdExample1 = null;

+		FunctionArgumentAttributeValue attrDateTimeMsecs = null;

+		FunctionArgumentAttributeValue attrDateTimeCrossover = null;

+		FunctionArgumentAttributeValue attrDateTimeBC = null;

+		FunctionArgumentAttributeValue attrDateTimeTimeZone0 = null;

+		FunctionArgumentAttributeValue attrDateTimeTimeZone5 = null;

+	

+		// Durations

+		FunctionArgumentAttributeValue attrDuration0 = null;

+		FunctionArgumentAttributeValue attrDurationStdExample1 = null;

+		FunctionArgumentAttributeValue attrDurationNStdExample1 = null;

+		FunctionArgumentAttributeValue attrDurationMsecs = null;

+		FunctionArgumentAttributeValue attrDurationCrossover = null;

+	

+		// misc bad

+		FunctionArgumentAttributeValue attrNull = null;

+		FunctionArgumentAttributeValue attrBlank = null;

+		FunctionArgumentAttributeValue attrInteger = null;

+		// set values

+		try {

+			// Date attrs

+			attrDateTimeStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeStdExample1));

+			attrDateTimeMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeMsecs));

+			attrDateTimeCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeCrossover));

+			attrDateTimeBC = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeBC));

+			attrDateTimeTimeZone0 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeTimeZone0));

+			attrDateTimeTimeZone5 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeTimeZone5));

+			

+			// Duration attrs

+			attrDuration0 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(duration0));

+			attrDurationStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(durationStdExample1));

+			attrDurationNStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(durationNStdExample1));

+			attrDurationMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(durationMsecs));

+			attrDurationCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(durationCrossover));

+

+			// misc bad

+			attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(""));

+			attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(null));

+			attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234));

+		} catch (Exception e) {

+			fail("creating attributes e="+ e);

+		}

+		

+		FunctionDefinitionDateTimeArithmetic<?,?> fd = (FunctionDefinitionDateTimeArithmetic<?,?>) StdFunctions.FD_DATETIME_SUBTRACT_DAYTIMEDURATION;

+

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_DATETIME_SUBTRACT_DAYTIMEDURATION, fd.getId());

+		assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		

+		// Duration = 0 => same as original

+		arguments.clear();

+		arguments.add(attrDateTimeStdExample1);

+		arguments.add(attrDuration0);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());

+		ISO8601DateTime resValue = (ISO8601DateTime)res.getValue().getValue();

+		assertEquals(dateTimeStdExample1, resValue);

+

+		

+		// simple positive operation

+		arguments.clear();

+		arguments.add(attrDateTimeStdExample1);

+		arguments.add(attrDurationStdExample1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());

+		resValue = (ISO8601DateTime)res.getValue().getValue();

+		ISO8601DateTime testResponse = new ISO8601DateTime(

+				null,	

+				new ISO8601Date(2000, 1, 7),

+				new ISO8601Time(5, 3, 10, 700) );

+		assertEquals(testResponse, resValue);	

+

+		

+		// negative operation

+		arguments.clear();

+		arguments.add(attrDateTimeStdExample1);

+		arguments.add(attrDurationNStdExample1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());

+		resValue = (ISO8601DateTime)res.getValue().getValue();

+		testResponse = new ISO8601DateTime(

+				null,

+				new ISO8601Date(2000, 1, 17),

+				new ISO8601Time(19, 23, 17, 300) );

+		assertEquals(testResponse, resValue);

+		

+		// millisecs work correctly

+		arguments.clear();

+		arguments.add(attrDateTimeMsecs);

+		arguments.add(attrDurationMsecs);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());

+		resValue = (ISO8601DateTime)res.getValue().getValue();

+		testResponse = new ISO8601DateTime(

+				null,

+				new ISO8601Date(2000, 1, 7),

+				new ISO8601Time(5, 2, 59, 999) );

+		assertEquals(testResponse, resValue);

+	

+		// cross minute => cross day => cross month => cross year

+		arguments.clear();

+		arguments.add(attrDateTimeCrossover);

+		arguments.add(attrDurationCrossover);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());

+		resValue = (ISO8601DateTime)res.getValue().getValue();

+		testResponse = new ISO8601DateTime(

+				null,

+				new ISO8601Date(2000, 12, 31), 

+				new ISO8601Time(23, 59, 30, 1));

+		assertEquals(testResponse, resValue);

+		

+		// negative (BC) original date add goes the right direction

+		arguments.clear();

+		arguments.add(attrDateTimeBC);

+		arguments.add(attrDurationStdExample1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());

+		resValue = (ISO8601DateTime)res.getValue().getValue();

+		testResponse = new ISO8601DateTime(

+				null,

+				new ISO8601Date(-2000, 1, 7),

+				new ISO8601Time(5, 3, 10, 700) );

+		assertEquals(testResponse, resValue);	

+		

+		// non-null timezone not changed

+		// original has timezone offset = 0

+		arguments.clear();

+		arguments.add(attrDateTimeTimeZone0);

+		arguments.add(attrDurationStdExample1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());

+		resValue = (ISO8601DateTime)res.getValue().getValue();

+		testResponse = new ISO8601DateTime(

+				timeZone0,

+				new ISO8601Date(timeZone0, 2000, 1, 7),

+				new ISO8601Time(timeZone0, 5, 3, 10, 700) );

+		assertEquals(testResponse, resValue);

+		

+		// original has timezone offset not 0

+		arguments.clear();

+		arguments.add(attrDateTimeTimeZone5);

+		arguments.add(attrDurationStdExample1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());

+		resValue = (ISO8601DateTime)res.getValue().getValue();

+		testResponse = new ISO8601DateTime(

+				timeZone5,

+				new ISO8601Date(timeZone5, 2000, 1, 7),

+				new ISO8601Time(timeZone5, 5, 3, 10, 700) );

+		assertEquals(testResponse, resValue);

+

+		// empty non-null first arg

+		arguments.clear();

+		arguments.add(attrBlank);

+		arguments.add(attrDurationStdExample1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dateTime-subtract-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+

+		// empty non-null second arg

+		arguments.clear();

+		arguments.add(attrDateTimeStdExample1);

+		arguments.add(attrBlank);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dateTime-subtract-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+

+		// two blanks

+		arguments.clear();

+		arguments.add(attrBlank);

+		arguments.add(attrBlank);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dateTime-subtract-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+			

+		// null firat arg

+		arguments.clear();

+		arguments.add(attrNull);

+		arguments.add(attrBlank);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dateTime-subtract-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+

+		// null second arg

+		arguments.clear();

+		arguments.add(attrDateTimeStdExample1);

+		arguments.add(attrNull);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dateTime-subtract-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// bad arg type

+		arguments.clear();

+		arguments.add(attrInteger);

+		arguments.add(attrDurationStdExample1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dateTime-subtract-dayTimeDuration Expected data type 'dateTime' saw 'integer'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// null second arg

+		arguments.clear();

+		arguments.add(attrDateTimeStdExample1);

+		arguments.add(attrNull);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dateTime-subtract-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+	}

+	

+

+

+	

+	

+	

+	

+	

+	

+	@Test

+	public void testDateTime_add_yearMonthDuration() {

+		// Date objects to be adjusted

+		ISO8601DateTime dateTimeStdExample1 = new ISO8601DateTime(null, 

+				new ISO8601Date(2000, 1, 12), 

+				new ISO8601Time(12, 13, 14, 0));

+		ISO8601DateTime dateTimeMsecs = new ISO8601DateTime(null, 

+				new ISO8601Date(2000, 1, 12), 

+				new ISO8601Time(12, 13, 14, 777));

+		ISO8601DateTime dateTimeCrossover = new ISO8601DateTime(null, 

+				new ISO8601Date(2000, 12, 31), 

+				new ISO8601Time(23, 59, 30, 1));

+		ISO8601DateTime dateTimeBC = new ISO8601DateTime(null, 

+				new ISO8601Date(-2000, 1, 12), 

+				new ISO8601Time(12, 13, 14, 0));

+		ISO8601TimeZone timeZone0 = new ISO8601TimeZone(0);

+		ISO8601TimeZone timeZone5 = new ISO8601TimeZone(5 * 60);

+		ISO8601DateTime dateTimeTimeZone0 = new ISO8601DateTime(timeZone0, 

+				new ISO8601Date(timeZone0, 2000, 1, 12), 

+				new ISO8601Time(timeZone0, 12, 13, 14, 0));

+		ISO8601DateTime dateTimeTimeZone5 = new ISO8601DateTime(timeZone5, 

+				new ISO8601Date(timeZone5, 2000, 1, 12), 

+				new ISO8601Time(timeZone5, 12, 13, 14, 0));

+		

+		// Durations

+		XPathYearMonthDuration duration0 = new XPathYearMonthDuration(1, 0, 0);

+		XPathYearMonthDuration durationStdExample1 = new XPathYearMonthDuration(1, 5, 7);

+		XPathYearMonthDuration durationNStdExample1 = new XPathYearMonthDuration(-1, 5, 7);

+		XPathYearMonthDuration durationMsecs = new XPathYearMonthDuration(1, 5, 7);

+		XPathYearMonthDuration durationCrossover = new XPathYearMonthDuration(1, 0, 1);

+

+		// ARGS declarations

+		// Dates

+		FunctionArgumentAttributeValue attrDateTimeStdExample1 = null;

+		FunctionArgumentAttributeValue attrDateTimeMsecs = null;

+		FunctionArgumentAttributeValue attrDateTimeCrossover = null;

+		FunctionArgumentAttributeValue attrDateTimeBC = null;

+		FunctionArgumentAttributeValue attrDateTimeTimeZone0 = null;

+		FunctionArgumentAttributeValue attrDateTimeTimeZone5 = null;

+	

+		// Durations

+		FunctionArgumentAttributeValue attrDuration0 = null;

+		FunctionArgumentAttributeValue attrDurationStdExample1 = null;

+		FunctionArgumentAttributeValue attrDurationNStdExample1 = null;

+		FunctionArgumentAttributeValue attrDurationMsecs = null;

+		FunctionArgumentAttributeValue attrDurationCrossover = null;

+	

+		// misc bad

+		FunctionArgumentAttributeValue attrNull = null;

+		FunctionArgumentAttributeValue attrBlank = null;

+		FunctionArgumentAttributeValue attrInteger = null;

+		// set values

+		try {

+			// Date attrs

+			attrDateTimeStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeStdExample1));

+			attrDateTimeMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeMsecs));

+			attrDateTimeCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeCrossover));

+			attrDateTimeBC = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeBC));

+			attrDateTimeTimeZone0 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeTimeZone0));

+			attrDateTimeTimeZone5 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeTimeZone5));

+			

+			// Duration attrs

+			attrDuration0 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(duration0));

+			attrDurationStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationStdExample1));

+			attrDurationNStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationNStdExample1));

+			attrDurationMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationMsecs));

+			attrDurationCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationCrossover));

+

+			// misc bad

+			attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(""));

+			attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(null));

+			attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234));

+		} catch (Exception e) {

+			fail("creating attributes e="+ e);

+		}

+		

+		FunctionDefinitionDateTimeArithmetic<?,?> fd = (FunctionDefinitionDateTimeArithmetic<?,?>) StdFunctions.FD_DATETIME_ADD_YEARMONTHDURATION;

+

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_DATETIME_ADD_YEARMONTHDURATION, fd.getId());

+		assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		

+		// Duration = 0 => same as original

+		arguments.clear();

+		arguments.add(attrDateTimeStdExample1);

+		arguments.add(attrDuration0);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());

+		ISO8601DateTime resValue = (ISO8601DateTime)res.getValue().getValue();

+		assertEquals(dateTimeStdExample1, resValue);

+

+		

+		// simple positive operation

+		arguments.clear();

+		arguments.add(attrDateTimeStdExample1);

+		arguments.add(attrDurationStdExample1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());

+		resValue = (ISO8601DateTime)res.getValue().getValue();

+		ISO8601DateTime testResponse = new ISO8601DateTime(

+				null,

+				new ISO8601Date(2005, 8, 12),

+				new ISO8601Time(12, 13, 14, 0) );

+		assertEquals(testResponse, resValue);	

+		

+		// negative operation

+		arguments.clear();

+		arguments.add(attrDateTimeStdExample1);

+		arguments.add(attrDurationNStdExample1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());

+		resValue = (ISO8601DateTime)res.getValue().getValue();

+		testResponse = new ISO8601DateTime(

+				null,

+				new ISO8601Date(1994, 6, 12),

+				new ISO8601Time(12, 13, 14, 0) );

+		assertEquals(testResponse, resValue);

+		

+		// millisecs work correctly (not relevant to YearMonth, but should not break

+		arguments.clear();

+		arguments.add(attrDateTimeMsecs);

+		arguments.add(attrDurationMsecs);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());

+		resValue = (ISO8601DateTime)res.getValue().getValue();

+		testResponse = new ISO8601DateTime(

+				null,

+				new ISO8601Date(2005, 8, 12),

+				new ISO8601Time(12, 13, 14, 777) );

+		assertEquals(testResponse, resValue);

+	

+		// cross minute => cross day => cross month => cross year

+		arguments.clear();

+		arguments.add(attrDateTimeCrossover);

+		arguments.add(attrDurationCrossover);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());

+		resValue = (ISO8601DateTime)res.getValue().getValue();

+		testResponse = new ISO8601DateTime(

+				null,

+				new ISO8601Date(2001, 1, 31),

+				new ISO8601Time(23, 59, 30, 1) );

+		assertEquals(testResponse, resValue);

+		

+		// negative (BC) original date add goes the right direction

+		arguments.clear();

+		arguments.add(attrDateTimeBC);

+		arguments.add(attrDurationStdExample1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());

+		resValue = (ISO8601DateTime)res.getValue().getValue();

+		testResponse = new ISO8601DateTime(

+				null,

+				new ISO8601Date(-1995, 8, 12),

+				new ISO8601Time(12, 13, 14, 0) );

+		assertEquals(testResponse, resValue);	

+		

+		// non-null timezone not changed

+		// original has timezone offset = 0

+		arguments.clear();

+		arguments.add(attrDateTimeTimeZone0);

+		arguments.add(attrDurationStdExample1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());

+		resValue = (ISO8601DateTime)res.getValue().getValue();

+		testResponse = new ISO8601DateTime(

+				timeZone0,

+				new ISO8601Date(timeZone0, 2005, 8, 12),

+				new ISO8601Time(timeZone0, 12, 13, 14, 0) );

+		assertEquals(testResponse, resValue);

+		

+		// original has timezone offset not 0

+		arguments.clear();

+		arguments.add(attrDateTimeTimeZone5);

+		arguments.add(attrDurationStdExample1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());

+		resValue = (ISO8601DateTime)res.getValue().getValue();

+		testResponse = new ISO8601DateTime(

+				timeZone5,

+				new ISO8601Date(timeZone5, 2005, 8, 12),

+				new ISO8601Time(timeZone5, 12, 13, 14, 0) );

+		assertEquals(testResponse, resValue);

+

+		// empty non-null first arg

+		arguments.clear();

+		arguments.add(attrBlank);

+		arguments.add(attrDurationStdExample1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dateTime-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+

+		// empty non-null second arg

+		arguments.clear();

+		arguments.add(attrDateTimeStdExample1);

+		arguments.add(attrBlank);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dateTime-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+

+		// two blanks

+		arguments.clear();

+		arguments.add(attrBlank);

+		arguments.add(attrBlank);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dateTime-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+			

+		// null firat arg

+		arguments.clear();

+		arguments.add(attrNull);

+		arguments.add(attrBlank);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dateTime-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+

+		// null second arg

+		arguments.clear();

+		arguments.add(attrDateTimeStdExample1);

+		arguments.add(attrNull);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dateTime-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// bad arg type

+		arguments.clear();

+		arguments.add(attrInteger);

+		arguments.add(attrDurationStdExample1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dateTime-add-yearMonthDuration Expected data type 'dateTime' saw 'integer'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// null second arg

+		arguments.clear();

+		arguments.add(attrDateTimeStdExample1);

+		arguments.add(attrNull);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dateTime-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+	}

+	

+

+	

+	

+	@Test

+	public void testDateTime_subtract_yearMonthDuration() {

+		// Date objects to be adjusted

+		ISO8601DateTime dateTimeStdExample1 = new ISO8601DateTime(null, 

+				new ISO8601Date(2000, 1, 12), 

+				new ISO8601Time(12, 13, 14, 0));

+		ISO8601DateTime dateTimeMsecs = new ISO8601DateTime(null, 

+				new ISO8601Date(2000, 1, 12), 

+				new ISO8601Time(12, 13, 14, 777));

+		ISO8601DateTime dateTimeCrossover = new ISO8601DateTime(null, 

+				new ISO8601Date(2000, 1, 1), 

+				new ISO8601Time(23, 59, 30, 1));

+		ISO8601DateTime dateTimeBC = new ISO8601DateTime(null, 

+				new ISO8601Date(-2000, 1, 12), 

+				new ISO8601Time(12, 13, 14, 0));

+		ISO8601TimeZone timeZone0 = new ISO8601TimeZone(0);

+		ISO8601TimeZone timeZone5 = new ISO8601TimeZone(5 * 60);

+		ISO8601DateTime dateTimeTimeZone0 = new ISO8601DateTime(timeZone0, 

+				new ISO8601Date(timeZone0, 2000, 1, 12), 

+				new ISO8601Time(timeZone0, 12, 13, 14, 0));

+		ISO8601DateTime dateTimeTimeZone5 = new ISO8601DateTime(timeZone5, 

+				new ISO8601Date(timeZone5, 2000, 1, 12), 

+				new ISO8601Time(timeZone5, 12, 13, 14, 0));

+		

+		// Durations

+		XPathYearMonthDuration duration0 = new XPathYearMonthDuration(1, 0, 0);

+		XPathYearMonthDuration durationStdExample1 = new XPathYearMonthDuration(1, 5, 7);

+		XPathYearMonthDuration durationNStdExample1 = new XPathYearMonthDuration(-1, 5, 7);

+		XPathYearMonthDuration durationMsecs = new XPathYearMonthDuration(1, 5, 7);

+		XPathYearMonthDuration durationCrossover = new XPathYearMonthDuration(1, 0, 1);

+

+		// ARGS declarations

+		// Dates

+		FunctionArgumentAttributeValue attrDateTimeStdExample1 = null;

+		FunctionArgumentAttributeValue attrDateTimeMsecs = null;

+		FunctionArgumentAttributeValue attrDateTimeCrossover = null;

+		FunctionArgumentAttributeValue attrDateTimeBC = null;

+		FunctionArgumentAttributeValue attrDateTimeTimeZone0 = null;

+		FunctionArgumentAttributeValue attrDateTimeTimeZone5 = null;

+	

+		// Durations

+		FunctionArgumentAttributeValue attrDuration0 = null;

+		FunctionArgumentAttributeValue attrDurationStdExample1 = null;

+		FunctionArgumentAttributeValue attrDurationNStdExample1 = null;

+		FunctionArgumentAttributeValue attrDurationMsecs = null;

+		FunctionArgumentAttributeValue attrDurationCrossover = null;

+	

+		// misc bad

+		FunctionArgumentAttributeValue attrNull = null;

+		FunctionArgumentAttributeValue attrBlank = null;

+		FunctionArgumentAttributeValue attrInteger = null;

+		// set values

+		try {

+			// Date attrs

+			attrDateTimeStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeStdExample1));

+			attrDateTimeMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeMsecs));

+			attrDateTimeCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeCrossover));

+			attrDateTimeBC = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeBC));

+			attrDateTimeTimeZone0 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeTimeZone0));

+			attrDateTimeTimeZone5 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeTimeZone5));

+			

+			// Duration attrs

+			attrDuration0 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(duration0));

+			attrDurationStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationStdExample1));

+			attrDurationNStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationNStdExample1));

+			attrDurationMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationMsecs));

+			attrDurationCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationCrossover));

+

+			// misc bad

+			attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(""));

+			attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(null));

+			attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234));

+		} catch (Exception e) {

+			fail("creating attributes e="+ e);

+		}

+		

+		FunctionDefinitionDateTimeArithmetic<?,?> fd = (FunctionDefinitionDateTimeArithmetic<?,?>) StdFunctions.FD_DATETIME_SUBTRACT_YEARMONTHDURATION;

+

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_DATETIME_SUBTRACT_YEARMONTHDURATION, fd.getId());

+		assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		

+		// Duration = 0 => same as original

+		arguments.clear();

+		arguments.add(attrDateTimeStdExample1);

+		arguments.add(attrDuration0);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());

+		ISO8601DateTime resValue = (ISO8601DateTime)res.getValue().getValue();

+		assertEquals(dateTimeStdExample1, resValue);

+

+		

+		// simple positive operation

+		arguments.clear();

+		arguments.add(attrDateTimeStdExample1);

+		arguments.add(attrDurationStdExample1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());

+		resValue = (ISO8601DateTime)res.getValue().getValue();

+		ISO8601DateTime testResponse = new ISO8601DateTime(

+				null,

+				new ISO8601Date(1994, 6, 12),

+				new ISO8601Time(12, 13, 14, 0) );

+		assertEquals(testResponse, resValue);	

+		

+		// negative operation

+		arguments.clear();

+		arguments.add(attrDateTimeStdExample1);

+		arguments.add(attrDurationNStdExample1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());

+		resValue = (ISO8601DateTime)res.getValue().getValue();

+		testResponse = new ISO8601DateTime(

+				null,

+				new ISO8601Date(2005, 8, 12),

+				new ISO8601Time(12, 13, 14, 0) );

+		assertEquals(testResponse, resValue);

+		

+		// millisecs work correctly (not relevant to YearMonth, but should not break

+		arguments.clear();

+		arguments.add(attrDateTimeMsecs);

+		arguments.add(attrDurationMsecs);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());

+		resValue = (ISO8601DateTime)res.getValue().getValue();

+		testResponse = new ISO8601DateTime(

+				null,

+				new ISO8601Date(1994, 6, 12),

+				new ISO8601Time(12, 13, 14, 777) );

+		assertEquals(testResponse, resValue);

+	

+		// cross minute => cross day => cross month => cross year

+		arguments.clear();

+		arguments.add(attrDateTimeCrossover);

+		arguments.add(attrDurationCrossover);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());

+		resValue = (ISO8601DateTime)res.getValue().getValue();

+		testResponse = new ISO8601DateTime(

+				null,

+				new ISO8601Date(1999, 12, 1),

+				new ISO8601Time(23, 59, 30, 1) );

+		assertEquals(testResponse, resValue);

+		

+		// negative (BC) original date add goes the right direction

+		arguments.clear();

+		arguments.add(attrDateTimeBC);

+		arguments.add(attrDurationStdExample1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());

+		resValue = (ISO8601DateTime)res.getValue().getValue();

+		testResponse = new ISO8601DateTime(

+				null,

+				new ISO8601Date(-2006, 6, 12),

+				new ISO8601Time(12, 13, 14, 0) );

+		assertEquals(testResponse, resValue);	

+		

+		// non-null timezone not changed

+		// original has timezone offset = 0

+		arguments.clear();

+		arguments.add(attrDateTimeTimeZone0);

+		arguments.add(attrDurationStdExample1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());

+		resValue = (ISO8601DateTime)res.getValue().getValue();

+		testResponse = new ISO8601DateTime(

+				timeZone0,

+				new ISO8601Date(timeZone0, 1994, 6, 12),

+				new ISO8601Time(timeZone0, 12, 13, 14, 0) );

+		assertEquals(testResponse, resValue);

+		

+		// original has timezone offset not 0

+		arguments.clear();

+		arguments.add(attrDateTimeTimeZone5);

+		arguments.add(attrDurationStdExample1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());

+		resValue = (ISO8601DateTime)res.getValue().getValue();

+		testResponse = new ISO8601DateTime(

+				timeZone5,

+				new ISO8601Date(timeZone5, 1994, 6, 12),

+				new ISO8601Time(timeZone5, 12, 13, 14, 0) );

+		assertEquals(testResponse, resValue);

+

+		// empty non-null first arg

+		arguments.clear();

+		arguments.add(attrBlank);

+		arguments.add(attrDurationStdExample1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dateTime-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+

+		// empty non-null second arg

+		arguments.clear();

+		arguments.add(attrDateTimeStdExample1);

+		arguments.add(attrBlank);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dateTime-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+

+		// two blanks

+		arguments.clear();

+		arguments.add(attrBlank);

+		arguments.add(attrBlank);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dateTime-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+			

+		// null firat arg

+		arguments.clear();

+		arguments.add(attrNull);

+		arguments.add(attrBlank);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dateTime-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+

+		// null second arg

+		arguments.clear();

+		arguments.add(attrDateTimeStdExample1);

+		arguments.add(attrNull);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dateTime-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// bad arg type

+		arguments.clear();

+		arguments.add(attrInteger);

+		arguments.add(attrDurationStdExample1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dateTime-subtract-yearMonthDuration Expected data type 'dateTime' saw 'integer'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// null second arg

+		arguments.clear();

+		arguments.add(attrDateTimeStdExample1);

+		arguments.add(attrNull);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dateTime-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+	}

+	

+	

+	

+	

+	

+	

+	

+	

+	

+	

+	

+	@Test

+	public void testDate_add_yearMonthDuration() {

+		// Date objects to be adjusted

+		ISO8601Date dateTimeStdExample1 = new ISO8601Date(2000, 1, 12);

+		ISO8601Date dateTimeMsecs =new ISO8601Date(2000, 1, 12);

+		ISO8601Date dateTimeCrossover = new ISO8601Date(2000, 12, 31);

+		ISO8601Date dateTimeBC = new ISO8601Date(-2000, 1, 12);

+		ISO8601TimeZone timeZone0 = new ISO8601TimeZone(0);

+		ISO8601TimeZone timeZone5 = new ISO8601TimeZone(5 * 60);

+		ISO8601Date dateTimeTimeZone0 = new ISO8601Date(timeZone0, 2000, 1, 12);

+		ISO8601Date dateTimeTimeZone5 = new ISO8601Date(timeZone5, 2000, 1, 12);

+		

+		// Durations

+		XPathYearMonthDuration duration0 = new XPathYearMonthDuration(1, 0, 0);

+		XPathYearMonthDuration durationStdExample1 = new XPathYearMonthDuration(1, 5, 7);

+		XPathYearMonthDuration durationNStdExample1 = new XPathYearMonthDuration(-1, 5, 7);

+		XPathYearMonthDuration durationMsecs = new XPathYearMonthDuration(1, 5, 7);

+		XPathYearMonthDuration durationCrossover = new XPathYearMonthDuration(1, 0, 1);

+

+		// ARGS declarations

+		// Dates

+		FunctionArgumentAttributeValue attrDateTimeStdExample1 = null;

+		FunctionArgumentAttributeValue attrDateTimeMsecs = null;

+		FunctionArgumentAttributeValue attrDateTimeCrossover = null;

+		FunctionArgumentAttributeValue attrDateTimeBC = null;

+		FunctionArgumentAttributeValue attrDateTimeTimeZone0 = null;

+		FunctionArgumentAttributeValue attrDateTimeTimeZone5 = null;

+	

+		// Durations

+		FunctionArgumentAttributeValue attrDuration0 = null;

+		FunctionArgumentAttributeValue attrDurationStdExample1 = null;

+		FunctionArgumentAttributeValue attrDurationNStdExample1 = null;

+		FunctionArgumentAttributeValue attrDurationMsecs = null;

+		FunctionArgumentAttributeValue attrDurationCrossover = null;

+	

+		// misc bad

+		FunctionArgumentAttributeValue attrNull = null;

+		FunctionArgumentAttributeValue attrBlank = null;

+		FunctionArgumentAttributeValue attrInteger = null;

+		// set values

+		try {

+			// Date attrs

+			attrDateTimeStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeStdExample1));

+			attrDateTimeMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeMsecs));

+			attrDateTimeCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeCrossover));

+			attrDateTimeBC = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeBC));

+			attrDateTimeTimeZone0 = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeTimeZone0));

+			attrDateTimeTimeZone5 = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeTimeZone5));

+			

+			// Duration attrs

+			attrDuration0 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(duration0));

+			attrDurationStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationStdExample1));

+			attrDurationNStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationNStdExample1));

+			attrDurationMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationMsecs));

+			attrDurationCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationCrossover));

+

+			// misc bad

+			attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(""));

+			attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(null));

+			attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234));

+		} catch (Exception e) {

+			fail("creating attributes e="+ e);

+		}

+		

+		FunctionDefinitionDateTimeArithmetic<?,?> fd = (FunctionDefinitionDateTimeArithmetic<?,?>) StdFunctions.FD_DATE_ADD_YEARMONTHDURATION;

+

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_DATE_ADD_YEARMONTHDURATION, fd.getId());

+		assertEquals(DataTypes.DT_DATE.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		

+		// Duration = 0 => same as original

+		arguments.clear();

+		arguments.add(attrDateTimeStdExample1);

+		arguments.add(attrDuration0);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601Date.class, res.getValue().getValue().getClass());

+		ISO8601Date resValue = (ISO8601Date)res.getValue().getValue();

+		assertEquals(dateTimeStdExample1, resValue);

+

+		

+		// simple positive operation

+		arguments.clear();

+		arguments.add(attrDateTimeStdExample1);

+		arguments.add(attrDurationStdExample1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601Date.class, res.getValue().getValue().getClass());

+		resValue = (ISO8601Date)res.getValue().getValue();

+		ISO8601Date testResponse = new ISO8601Date(2005, 8, 12);

+		assertEquals(testResponse, resValue);	

+		

+		// negative operation

+		arguments.clear();

+		arguments.add(attrDateTimeStdExample1);

+		arguments.add(attrDurationNStdExample1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601Date.class, res.getValue().getValue().getClass());

+		resValue = (ISO8601Date)res.getValue().getValue();

+		testResponse = new ISO8601Date(1994, 6, 12);

+		assertEquals(testResponse, resValue);

+		

+		// millisecs work correctly (not relevant to YearMonth, but should not break

+		arguments.clear();

+		arguments.add(attrDateTimeMsecs);

+		arguments.add(attrDurationMsecs);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601Date.class, res.getValue().getValue().getClass());

+		resValue = (ISO8601Date)res.getValue().getValue();

+		testResponse = new ISO8601Date(2005, 8, 12);

+		assertEquals(testResponse, resValue);

+	

+		// cross minute => cross day => cross month => cross year

+		arguments.clear();

+		arguments.add(attrDateTimeCrossover);

+		arguments.add(attrDurationCrossover);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601Date.class, res.getValue().getValue().getClass());

+		resValue = (ISO8601Date)res.getValue().getValue();

+		testResponse = new ISO8601Date(2001, 1, 31);

+		assertEquals(testResponse, resValue);

+		

+		// negative (BC) original date add goes the right direction

+		arguments.clear();

+		arguments.add(attrDateTimeBC);

+		arguments.add(attrDurationStdExample1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601Date.class, res.getValue().getValue().getClass());

+		resValue = (ISO8601Date)res.getValue().getValue();

+		testResponse = new ISO8601Date(-1995, 8, 12);

+		assertEquals(testResponse, resValue);	

+		

+		// non-null timezone not changed

+		// original has timezone offset = 0

+		arguments.clear();

+		arguments.add(attrDateTimeTimeZone0);

+		arguments.add(attrDurationStdExample1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601Date.class, res.getValue().getValue().getClass());

+		resValue = (ISO8601Date)res.getValue().getValue();

+		testResponse = new ISO8601Date(timeZone0, 2005, 8, 12);

+		assertEquals(testResponse, resValue);

+		

+		// original has timezone offset not 0

+		arguments.clear();

+		arguments.add(attrDateTimeTimeZone5);

+		arguments.add(attrDurationStdExample1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601Date.class, res.getValue().getValue().getClass());

+		resValue = (ISO8601Date)res.getValue().getValue();

+		testResponse = new ISO8601Date(timeZone5, 2005, 8, 12);

+		assertEquals(testResponse, resValue);

+

+		// empty non-null first arg

+		arguments.clear();

+		arguments.add(attrBlank);

+		arguments.add(attrDurationStdExample1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:date-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+

+		// empty non-null second arg

+		arguments.clear();

+		arguments.add(attrDateTimeStdExample1);

+		arguments.add(attrBlank);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:date-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+

+		// two blanks

+		arguments.clear();

+		arguments.add(attrBlank);

+		arguments.add(attrBlank);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:date-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+			

+		// null firat arg

+		arguments.clear();

+		arguments.add(attrNull);

+		arguments.add(attrBlank);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:date-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+

+		// null second arg

+		arguments.clear();

+		arguments.add(attrDateTimeStdExample1);

+		arguments.add(attrNull);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:date-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// bad arg type

+		arguments.clear();

+		arguments.add(attrInteger);

+		arguments.add(attrDurationStdExample1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:date-add-yearMonthDuration Expected data type 'date' saw 'integer'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// null second arg

+		arguments.clear();

+		arguments.add(attrDateTimeStdExample1);

+		arguments.add(attrNull);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:date-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+	}

+	

+	

+	

+	

+	

+	

+	@Test

+	public void testDate_subtract_yearMonthDuration() {

+		// Date objects to be adjusted

+		ISO8601Date dateTimeStdExample1 =new ISO8601Date(2000, 1, 12);

+		ISO8601Date dateTimeMsecs = new ISO8601Date(2000, 1, 12);

+		ISO8601Date dateTimeCrossover = new ISO8601Date(2000, 1, 1);

+		ISO8601Date dateTimeBC = new ISO8601Date(-2000, 1, 12);

+		ISO8601TimeZone timeZone0 = new ISO8601TimeZone(0);

+		ISO8601TimeZone timeZone5 = new ISO8601TimeZone(5 * 60);

+		ISO8601Date dateTimeTimeZone0 = new ISO8601Date(timeZone0, 2000, 1, 12);

+		ISO8601Date dateTimeTimeZone5 = new ISO8601Date(timeZone5, 2000, 1, 12);

+		

+		// Durations

+		XPathYearMonthDuration duration0 = new XPathYearMonthDuration(1, 0, 0);

+		XPathYearMonthDuration durationStdExample1 = new XPathYearMonthDuration(1, 5, 7);

+		XPathYearMonthDuration durationNStdExample1 = new XPathYearMonthDuration(-1, 5, 7);

+		XPathYearMonthDuration durationMsecs = new XPathYearMonthDuration(1, 5, 7);

+		XPathYearMonthDuration durationCrossover = new XPathYearMonthDuration(1, 0, 1);

+

+		// ARGS declarations

+		// Dates

+		FunctionArgumentAttributeValue attrDateTimeStdExample1 = null;

+		FunctionArgumentAttributeValue attrDateTimeMsecs = null;

+		FunctionArgumentAttributeValue attrDateTimeCrossover = null;

+		FunctionArgumentAttributeValue attrDateTimeBC = null;

+		FunctionArgumentAttributeValue attrDateTimeTimeZone0 = null;

+		FunctionArgumentAttributeValue attrDateTimeTimeZone5 = null;

+	

+		// Durations

+		FunctionArgumentAttributeValue attrDuration0 = null;

+		FunctionArgumentAttributeValue attrDurationStdExample1 = null;

+		FunctionArgumentAttributeValue attrDurationNStdExample1 = null;

+		FunctionArgumentAttributeValue attrDurationMsecs = null;

+		FunctionArgumentAttributeValue attrDurationCrossover = null;

+	

+		// misc bad

+		FunctionArgumentAttributeValue attrNull = null;

+		FunctionArgumentAttributeValue attrBlank = null;

+		FunctionArgumentAttributeValue attrInteger = null;

+		// set values

+		try {

+			// Date attrs

+			attrDateTimeStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeStdExample1));

+			attrDateTimeMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeMsecs));

+			attrDateTimeCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeCrossover));

+			attrDateTimeBC = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeBC));

+			attrDateTimeTimeZone0 = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeTimeZone0));

+			attrDateTimeTimeZone5 = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeTimeZone5));

+			

+			// Duration attrs

+			attrDuration0 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(duration0));

+			attrDurationStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationStdExample1));

+			attrDurationNStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationNStdExample1));

+			attrDurationMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationMsecs));

+			attrDurationCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationCrossover));

+

+			// misc bad

+			attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(""));

+			attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(null));

+			attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234));

+		} catch (Exception e) {

+			fail("creating attributes e="+ e);

+		}

+		

+		FunctionDefinitionDateTimeArithmetic<?,?> fd = (FunctionDefinitionDateTimeArithmetic<?,?>) StdFunctions.FD_DATE_SUBTRACT_YEARMONTHDURATION;

+

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_DATE_SUBTRACT_YEARMONTHDURATION, fd.getId());

+		assertEquals(DataTypes.DT_DATE.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		

+		// Duration = 0 => same as original

+		arguments.clear();

+		arguments.add(attrDateTimeStdExample1);

+		arguments.add(attrDuration0);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601Date.class, res.getValue().getValue().getClass());

+		ISO8601Date resValue = (ISO8601Date)res.getValue().getValue();

+		assertEquals(dateTimeStdExample1, resValue);

+

+		

+		// simple positive operation

+		arguments.clear();

+		arguments.add(attrDateTimeStdExample1);

+		arguments.add(attrDurationStdExample1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601Date.class, res.getValue().getValue().getClass());

+		resValue = (ISO8601Date)res.getValue().getValue();

+		ISO8601Date testResponse = new ISO8601Date(1994, 6, 12);

+		assertEquals(testResponse, resValue);	

+		

+		// negative operation

+		arguments.clear();

+		arguments.add(attrDateTimeStdExample1);

+		arguments.add(attrDurationNStdExample1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601Date.class, res.getValue().getValue().getClass());

+		resValue = (ISO8601Date)res.getValue().getValue();

+		testResponse = new ISO8601Date(2005, 8, 12);

+		assertEquals(testResponse, resValue);

+		

+		// millisecs work correctly (not relevant to YearMonth, but should not break

+		arguments.clear();

+		arguments.add(attrDateTimeMsecs);

+		arguments.add(attrDurationMsecs);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601Date.class, res.getValue().getValue().getClass());

+		resValue = (ISO8601Date)res.getValue().getValue();

+		testResponse = new ISO8601Date(1994, 6, 12);

+		assertEquals(testResponse, resValue);

+	

+		// cross minute => cross day => cross month => cross year

+		arguments.clear();

+		arguments.add(attrDateTimeCrossover);

+		arguments.add(attrDurationCrossover);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601Date.class, res.getValue().getValue().getClass());

+		resValue = (ISO8601Date)res.getValue().getValue();

+		testResponse = new ISO8601Date(1999, 12, 1);

+		assertEquals(testResponse, resValue);

+		

+		// negative (BC) original date add goes the right direction

+		arguments.clear();

+		arguments.add(attrDateTimeBC);

+		arguments.add(attrDurationStdExample1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601Date.class, res.getValue().getValue().getClass());

+		resValue = (ISO8601Date)res.getValue().getValue();

+		testResponse = new ISO8601Date(-2006, 6, 12);

+		assertEquals(testResponse, resValue);	

+		

+		// non-null timezone not changed

+		// original has timezone offset = 0

+		arguments.clear();

+		arguments.add(attrDateTimeTimeZone0);

+		arguments.add(attrDurationStdExample1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601Date.class, res.getValue().getValue().getClass());

+		resValue = (ISO8601Date)res.getValue().getValue();

+		testResponse = new ISO8601Date(timeZone0, 1994, 6, 12);

+		assertEquals(testResponse, resValue);

+		

+		// original has timezone offset not 0

+		arguments.clear();

+		arguments.add(attrDateTimeTimeZone5);

+		arguments.add(attrDurationStdExample1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(ISO8601Date.class, res.getValue().getValue().getClass());

+		resValue = (ISO8601Date)res.getValue().getValue();

+		testResponse = new ISO8601Date(timeZone5, 1994, 6, 12);

+		assertEquals(testResponse, resValue);

+

+		// empty non-null first arg

+		arguments.clear();

+		arguments.add(attrBlank);

+		arguments.add(attrDurationStdExample1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:date-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+

+		// empty non-null second arg

+		arguments.clear();

+		arguments.add(attrDateTimeStdExample1);

+		arguments.add(attrBlank);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:date-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+

+		// two blanks

+		arguments.clear();

+		arguments.add(attrBlank);

+		arguments.add(attrBlank);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:date-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+			

+		// null firat arg

+		arguments.clear();

+		arguments.add(attrNull);

+		arguments.add(attrBlank);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:date-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+

+		// null second arg

+		arguments.clear();

+		arguments.add(attrDateTimeStdExample1);

+		arguments.add(attrNull);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:date-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// bad arg type

+		arguments.clear();

+		arguments.add(attrInteger);

+		arguments.add(attrDurationStdExample1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:date-subtract-yearMonthDuration Expected data type 'date' saw 'integer'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// null second arg

+		arguments.clear();

+		arguments.add(attrDateTimeStdExample1);

+		arguments.add(attrNull);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:date-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+	}

+	

+	

+	

+}

diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionEqualityTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionEqualityTest.java
new file mode 100755
index 0000000..d092f60
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionEqualityTest.java
@@ -0,0 +1,1182 @@
+/*

+ *                        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.std.functions;

+

+import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.assertFalse;

+import static org.junit.Assert.assertNotNull;

+import static org.junit.Assert.assertTrue;

+import static org.junit.Assert.fail;

+

+import java.net.URI;

+import java.util.ArrayList;

+import java.util.Calendar;

+import java.util.Date;

+import java.util.List;

+

+import javax.security.auth.x500.X500Principal;

+

+import org.junit.Test;

+

+import com.att.research.xacml.api.XACML1;

+import com.att.research.xacml.api.XACML3;

+import com.att.research.xacml.std.datatypes.Base64Binary;

+import com.att.research.xacml.std.datatypes.DataTypeRFC822Name;

+import com.att.research.xacml.std.datatypes.DataTypes;

+import com.att.research.xacml.std.datatypes.HexBinary;

+import com.att.research.xacml.std.datatypes.RFC822Name;

+import com.att.research.xacml.std.datatypes.XPathDayTimeDuration;

+import com.att.research.xacml.std.datatypes.XPathYearMonthDuration;

+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue;

+import com.att.research.xacmlatt.pdp.std.StdFunctions;

+

+/**

+ * Test FunctionDefinitionEquality, all of its super-classes, and all XACML functions supported by that class.

+ * 

+ * TO RUN - use jUnit

+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test

+ * 

+ * In the first implementation of XACML we had separate files for each XACML Function.

+ * This release combines multiple Functions in fewer files to minimize code duplication.

+ * This file supports the following XACML codes:

+ * 		string-equal

+ * 		boolean-equal

+ * 		integer-equal

+ * 		double-equal

+ * 		date-equal

+ * 		time-equal

+ * 		dateTime-equal

+ * 		dayTimeDuration-equal

+ * 		yearMonthDuration-equal

+ * 

+ * Each of these is put into a separate test method just to keep things organized.

+ * 

+ * @author glenngriffin

+ *

+ */

+public class FunctionDefinitionEqualityTest {

+

+	/*

+	 * variables useful in the following tests

+	 */

+	List<FunctionArgument> arguments = new ArrayList<FunctionArgument>();

+	

+	FunctionArgumentAttributeValue stringAttr1 = null;

+	FunctionArgumentAttributeValue stringAttr2 = null;

+	FunctionArgumentAttributeValue stringAttr3 = null;

+	FunctionArgumentAttributeValue stringAttr4 =  null;

+

+	FunctionArgumentAttributeValue booleanAttrT1 = null;

+	FunctionArgumentAttributeValue booleanAttrT2 = null;

+	FunctionArgumentAttributeValue booleanAttrF1 = null;

+	FunctionArgumentAttributeValue booleanAttrF2 = null;

+

+	FunctionArgumentAttributeValue intAttr1 = null;

+	FunctionArgumentAttributeValue intAttr1a = null;

+	FunctionArgumentAttributeValue intAttr2 = null;

+	FunctionArgumentAttributeValue intAttr0 = null;

+	FunctionArgumentAttributeValue intAttrNeg1 = null;

+

+	public FunctionDefinitionEqualityTest() {

+		try {

+			stringAttr1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("abc"));

+			stringAttr2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("abc"));

+			stringAttr3 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("ABC"));

+			stringAttr4 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("def"));

+

+			booleanAttrT1 = new FunctionArgumentAttributeValue(DataTypes.DT_BOOLEAN.createAttributeValue(true));

+			booleanAttrT2 = new FunctionArgumentAttributeValue(DataTypes.DT_BOOLEAN.createAttributeValue(true));

+			booleanAttrF1 = new FunctionArgumentAttributeValue(DataTypes.DT_BOOLEAN.createAttributeValue(false));

+			booleanAttrF2 = new FunctionArgumentAttributeValue(DataTypes.DT_BOOLEAN.createAttributeValue(false));

+

+			intAttr1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1));

+			intAttr1a = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1));

+			intAttr2 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(2));

+			intAttr0 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(0));

+			intAttrNeg1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(-1));

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+	}

+	

+	

+	

+	

+	/**

+	 * String (matching case)

+	 */

+	@Test

+	public void testString_Equal() {

+		

+		// String exact match

+		FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_STRING_EQUAL;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_STRING_EQUAL, fd.getId());

+		assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		// test normal equals and non-equals

+		// check "abc" with "abc" - separate string objects with same value

+		arguments.add(stringAttr1);

+		arguments.add(stringAttr2);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		// check "abc" with "ABC" (not same)

+		arguments.clear();

+		arguments.add(stringAttr1);

+		arguments.add(stringAttr3);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// test bad args data types?  Not needed?

+		arguments.clear();

+		arguments.add(stringAttr1);

+		arguments.add(intAttr1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+

+	}

+

+	

+	

+	/**

+	 * Boolean

+	 */

+	@Test

+	public void testBoolean_Equal() {

+		

+		// String exact match

+		FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_BOOLEAN_EQUAL;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_BOOLEAN_EQUAL, fd.getId());

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeArgs().getId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		// test normal equals and non-equals

+		// check separate objects with same value

+		arguments.add(booleanAttrT1);

+		arguments.add(booleanAttrT2);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		// check different values

+		arguments.clear();

+		arguments.add(booleanAttrT1);

+		arguments.add(booleanAttrF1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// test bad args data types?  Not needed?

+		arguments.clear();

+		arguments.add(stringAttr1);

+		arguments.add(intAttr1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+

+	}

+	

+	

+	/**

+	 * Integer

+	 */

+	@Test

+	public void testInteger_Equal() {

+		

+		// String exact match

+		FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_INTEGER_EQUAL;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_INTEGER_EQUAL, fd.getId());

+		assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		// test normal equals and non-equals

+		// check separate objects with same value

+		arguments.add(intAttr1);

+		arguments.add(intAttr1a);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		// check not same

+		arguments.clear();

+		arguments.add(intAttr1);

+		arguments.add(intAttr2);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		arguments.clear();

+		arguments.add(intAttr1);

+		arguments.add(intAttrNeg1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		

+		// test bad args data types?  Not needed?

+		arguments.clear();

+		arguments.add(stringAttr1);

+		arguments.add(intAttr1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+

+	}

+	

+	

+	

+	/**

+	 * Double

+	 */

+	@Test

+	public void testDouble_Equal() {

+		FunctionArgumentAttributeValue attr1 = null;

+		FunctionArgumentAttributeValue attr1a = null;

+		FunctionArgumentAttributeValue attr2 = null;

+		FunctionArgumentAttributeValue attrNeg1 = null;

+		try {

+			attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.0));

+			attr1a = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.0));

+			attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(2.4));

+			attrNeg1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(-1.0));

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+		

+		// String exact match

+		FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_DOUBLE_EQUAL;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_DOUBLE_EQUAL, fd.getId());

+		assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		// test normal equals and non-equals

+		// check separate objects with the same value

+		arguments.add(attr1);

+		arguments.add(attr1a);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		// check not same

+		arguments.clear();

+		arguments.add(attr1);

+		arguments.add(attr2);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		arguments.clear();

+		arguments.add(attr1);

+		arguments.add(attrNeg1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		

+		// test bad args data types?  Not needed?

+		arguments.clear();

+		arguments.add(stringAttr1);

+		arguments.add(intAttr1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+

+	}

+	

+	

+	

+	

+	

+	/**

+	 * Date

+	 */

+	@Test

+	public void testDate_Equal() {

+		Calendar calendar = Calendar.getInstance();

+		Date today = calendar.getTime();

+		Date longAgo = new Date(1234);

+		// create a date that is different than "today" but within the same day (i.e. has a different hour)

+		if (calendar.get(Calendar.HOUR_OF_DAY) > 3) {

+			calendar.set(Calendar.HOUR_OF_DAY, 3);

+		} else {

+			calendar.set(Calendar.HOUR_OF_DAY, 5);

+		}

+		Date todayPlus = calendar.getTime();

+

+

+		FunctionArgumentAttributeValue attrToday = null;

+		FunctionArgumentAttributeValue attrToday2 = null;

+		FunctionArgumentAttributeValue attrLaterToday = null;		

+		FunctionArgumentAttributeValue attrYesterday = null;

+		try {

+			attrToday = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(today));

+			attrToday2 = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(today));

+			attrLaterToday = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(todayPlus));		

+			attrYesterday = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(longAgo));

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+		

+		// String exact match

+		FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_DATE_EQUAL;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_DATE_EQUAL, fd.getId());

+		assertEquals(DataTypes.DT_DATE.getId(), fd.getDataTypeArgs().getId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		// test normal equals and non-equals

+		// check separate objects with the same value

+		arguments.add(attrToday);

+		arguments.add(attrToday2);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		// check not same

+		arguments.clear();

+		arguments.add(attrToday);

+		arguments.add(attrYesterday);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// Date objects with different times but within the same day should match

+		arguments.clear();

+		arguments.add(attrToday);

+		arguments.add(attrLaterToday);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		// test bad args data types?  Not needed?

+		arguments.clear();

+		arguments.add(stringAttr1);

+		arguments.add(intAttr1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+

+	}

+	

+	

+	

+	

+	/**

+	 * Time

+	 */

+	@Test

+	public void testTime_Equal() {

+		

+		Date now = new Date();

+		Date now2 = new Date(now.getTime());

+		Date notNow = new Date(now.getTime() - 100000);

+		

+		FunctionArgumentAttributeValue attrNow = null;

+		FunctionArgumentAttributeValue attrNow2 = null;

+		FunctionArgumentAttributeValue attrNotNow = null;

+		try {

+			attrNow = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue(now));

+			attrNow2 = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue(now2));

+			attrNotNow = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue(notNow));

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+

+		// String exact match

+		FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_TIME_EQUAL;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_TIME_EQUAL, fd.getId());

+		assertEquals(DataTypes.DT_TIME.getId(), fd.getDataTypeArgs().getId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		// test normal equals and non-equals

+		// check separate objects with the same value

+		arguments.add(attrNow);

+		arguments.add(attrNow2);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		// check not same

+		arguments.clear();

+		arguments.add(attrNow);

+		arguments.add(attrNotNow);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// test bad args data types?  Not needed?

+		arguments.clear();

+		arguments.add(stringAttr1);

+		arguments.add(intAttr1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+

+	}

+	

+	

+	

+	

+	/**

+	 * DateTime

+	 */

+	@Test

+	public void testDateTime_Equal() {

+		Calendar calendar = Calendar.getInstance();

+		Date today = calendar.getTime();

+		Date longAgo = new Date(1234);

+		// create a dateTime that is different than "today" changing only the Timezone

+		if (calendar.get(Calendar.ZONE_OFFSET) > 3) {

+			calendar.set(Calendar.ZONE_OFFSET, 3);

+		} else {

+			calendar.set(Calendar.ZONE_OFFSET, 5);

+		}

+		Date todayPlus = calendar.getTime();

+

+

+		FunctionArgumentAttributeValue attrToday = null;

+		FunctionArgumentAttributeValue attrToday2 = null;

+		FunctionArgumentAttributeValue attrLaterToday = null;		

+		FunctionArgumentAttributeValue attrYesterday = null;

+		try {

+			attrToday = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(today));

+			attrToday2 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(today));

+			attrLaterToday = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(todayPlus));		

+			attrYesterday = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(longAgo));

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+		

+		// String exact match

+		FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_DATETIME_EQUAL;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_DATETIME_EQUAL, fd.getId());

+		assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeArgs().getId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		// test normal equals and non-equals

+		// check separate objects with the same value

+		arguments.add(attrToday);

+		arguments.add(attrToday2);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		// check not same

+		arguments.clear();

+		arguments.add(attrToday);

+		arguments.add(attrYesterday);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// DateTime with different Zones should not match

+		arguments.clear();

+		arguments.add(attrToday);

+		arguments.add(attrLaterToday);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+

+		// test bad args data types?  Not needed?

+		arguments.clear();

+		arguments.add(stringAttr1);

+		arguments.add(intAttr1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+

+	}

+	

+	

+	/**

+	 * dayTimeDuration - Version1

+	 */

+	@Test

+	public void testDayTimeDuration_Equal_V1() {

+		

+		XPathDayTimeDuration dur1 = new XPathDayTimeDuration(1, 3, 5, 12, 38);

+		XPathDayTimeDuration dur2 = new XPathDayTimeDuration(1, 3, 5, 12, 38);

+		XPathDayTimeDuration differentDur = new XPathDayTimeDuration(-1, 4, 7, 5, 33);

+

+		FunctionArgumentAttributeValue attrDur1 = null;

+		FunctionArgumentAttributeValue attrDur2 = null;

+		FunctionArgumentAttributeValue attrDifferentDur = null;

+		try {

+			attrDur1 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(dur1));

+			attrDur2 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(dur2));

+			attrDifferentDur = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(differentDur));		

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+		

+		FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_DAYTIMEDURATION_EQUAL_VERSION1;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML1.ID_FUNCTION_DAYTIMEDURATION_EQUAL, fd.getId());

+		assertEquals(DataTypes.DT_DAYTIMEDURATION.getId(), fd.getDataTypeArgs().getId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		// test normal equals and non-equals

+		// check separate objects with the same value

+		arguments.add(attrDur1);

+		arguments.add(attrDur2);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		// check not same

+		arguments.clear();

+		arguments.add(attrDur1);

+		arguments.add(attrDifferentDur);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+

+		// test bad args data types?  Not needed?

+		arguments.clear();

+		arguments.add(stringAttr1);

+		arguments.add(intAttr1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+

+	}

+	

+	

+	/**

+	 * dayTimeDuration - Current version

+	 */

+	@Test

+	public void testDayTimeDuration_Equal() {

+		

+		XPathDayTimeDuration dur1 = new XPathDayTimeDuration(1, 3, 5, 12, 38);

+		XPathDayTimeDuration dur2 = new XPathDayTimeDuration(1, 3, 5, 12, 38);

+		XPathDayTimeDuration differentDur = new XPathDayTimeDuration(-1, 4, 7, 5, 33);

+

+		FunctionArgumentAttributeValue attrDur1 = null;

+		FunctionArgumentAttributeValue attrDur2 = null;

+		FunctionArgumentAttributeValue attrDifferentDur = null;		

+		try {

+			attrDur1 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(dur1));

+			attrDur2 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(dur2));

+			attrDifferentDur = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(differentDur));	

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+		

+		FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_DAYTIMEDURATION_EQUAL;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_DAYTIMEDURATION_EQUAL, fd.getId());

+		assertEquals(DataTypes.DT_DAYTIMEDURATION.getId(), fd.getDataTypeArgs().getId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		// test normal equals and non-equals

+		// check separate objects with the same value

+		arguments.add(attrDur1);

+		arguments.add(attrDur2);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		// check not same

+		arguments.clear();

+		arguments.add(attrDur1);

+		arguments.add(attrDifferentDur);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+

+		// test bad args data types?  Not needed?

+		arguments.clear();

+		arguments.add(stringAttr1);

+		arguments.add(intAttr1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+

+	}

+	

+	

+	

+	/**

+	 * dayTimeDuration - Version1

+	 */

+	@Test

+	public void testYearMonthDuration_Equal_V1() {

+		

+		XPathYearMonthDuration dur1 = new XPathYearMonthDuration(1, 3, 5);

+		XPathYearMonthDuration dur2 = new XPathYearMonthDuration(1, 3, 5);

+		XPathYearMonthDuration differentDur = new XPathYearMonthDuration(-1, 4, 7);

+

+		FunctionArgumentAttributeValue attrDur1 = null;

+		FunctionArgumentAttributeValue attrDur2 = null;

+		FunctionArgumentAttributeValue attrDifferentDur = null;		

+		try {

+			attrDur1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(dur1));

+			attrDur2 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(dur2));

+			attrDifferentDur = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(differentDur));

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+

+		FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_YEARMONTHDURATION_EQUAL_VERSION1;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML1.ID_FUNCTION_YEARMONTHDURATION_EQUAL, fd.getId());

+		assertEquals(DataTypes.DT_YEARMONTHDURATION.getId(), fd.getDataTypeArgs().getId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		// test normal equals and non-equals

+		// check separate objects with the same value

+		arguments.add(attrDur1);

+		arguments.add(attrDur2);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		// check not same

+		arguments.clear();

+		arguments.add(attrDur1);

+		arguments.add(attrDifferentDur);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+

+		// test bad args data types?  Not needed?

+		arguments.clear();

+		arguments.add(stringAttr1);

+		arguments.add(intAttr1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+

+	}

+	

+	

+

+	

+	/**

+	 * dayTimeDuration - Current version

+	 */

+	@Test

+	public void testYearMonthDuration_Equal() {

+		

+		XPathYearMonthDuration dur1 = new XPathYearMonthDuration(1, 3, 5);

+		XPathYearMonthDuration dur2 = new XPathYearMonthDuration(1, 3, 5);

+		XPathYearMonthDuration differentDur = new XPathYearMonthDuration(-1, 4, 7);

+

+		FunctionArgumentAttributeValue attrDur1 = null;

+		FunctionArgumentAttributeValue attrDur2 = null;

+		FunctionArgumentAttributeValue attrDifferentDur = null;		

+		try {

+			attrDur1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(dur1));

+			attrDur2 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(dur2));

+			attrDifferentDur = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(differentDur));	

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+

+		FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_YEARMONTHDURATION_EQUAL;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_YEARMONTHDURATION_EQUAL, fd.getId());

+		assertEquals(DataTypes.DT_YEARMONTHDURATION.getId(), fd.getDataTypeArgs().getId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		// test normal equals and non-equals

+		// check separate objects with the same value

+		arguments.add(attrDur1);

+		arguments.add(attrDur2);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		// check not same

+		arguments.clear();

+		arguments.add(attrDur1);

+		arguments.add(attrDifferentDur);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+

+		// test bad args data types?  Not needed?

+		arguments.clear();

+		arguments.add(stringAttr1);

+		arguments.add(intAttr1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+

+	}

+	

+	

+	/**

+	 * URI

+	 */

+	@Test

+	public void testAnyURI_Equal() {

+

+		URI uri1 = null;

+		URI uri2 = null;

+		URI uriNotThere = null;

+		try {

+			uri1 = new URI("http://someplace.com/gothere");

+			uri2 = new URI("http://someplace.com/gothere");

+			uriNotThere = new URI("http://someplace.com/notGoingThere");

+		} catch (Exception e) {

+			fail(e.toString());

+		}

+

+		FunctionArgumentAttributeValue attrUri1 = null;

+		FunctionArgumentAttributeValue attrUri2 = null;

+		FunctionArgumentAttributeValue attrUriNotThere = null;	

+		try {

+			attrUri1 = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(uri1));

+			attrUri2 = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(uri2));

+			attrUriNotThere = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(uriNotThere));	

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+

+		FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_ANYURI_EQUAL;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_ANYURI_EQUAL, fd.getId());

+		assertEquals(DataTypes.DT_ANYURI.getId(), fd.getDataTypeArgs().getId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		// test normal equals and non-equals

+		// check separate objects with the same value

+		arguments.add(attrUri1);

+		arguments.add(attrUri2);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		// check not same

+		arguments.clear();

+		arguments.add(attrUri1);

+		arguments.add(attrUriNotThere);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+

+		// test bad args data types?  Not needed?

+		arguments.clear();

+		arguments.add(stringAttr1);

+		arguments.add(intAttr1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+

+	}

+	

+	

+	/**

+	 * X500Name

+	 */

+	@Test

+	public void testX500Name_Equal() {

+

+		X500Principal name1 = new X500Principal("CN=Duke, OU=JavaSoft, O=Sun Microsystems, C=US");

+		X500Principal name2 = new X500Principal("CN=Duke, OU=JavaSoft, O=Sun Microsystems, C=US");

+		X500Principal name3 = new X500Principal("CN=NotDuke, OU=NotThere, O=Oracle, C=US");

+

+

+		FunctionArgumentAttributeValue attrName1 = null;

+		FunctionArgumentAttributeValue attrName1a = null;

+		FunctionArgumentAttributeValue attrNotSameName = null;		

+		try {

+			attrName1 = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(name1));

+			attrName1a = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(name2));

+			attrNotSameName = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(name3));	

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+

+		FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_X500NAME_EQUAL;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_X500NAME_EQUAL, fd.getId());

+		assertEquals(DataTypes.DT_X500NAME.getId(), fd.getDataTypeArgs().getId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		// test normal equals and non-equals

+		// check separate objects with the same value

+		arguments.add(attrName1);

+		arguments.add(attrName1a);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		// check not same

+		arguments.clear();

+		arguments.add(attrName1);

+		arguments.add(attrNotSameName);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+

+		// test bad args data types?  Not needed?

+		arguments.clear();

+		arguments.add(stringAttr1);

+		arguments.add(intAttr1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+

+	}

+	

+	

+	

+	/**

+	 * RFC822Name

+	 */

+	@Test

+	public void testRfc822Name_Equal() {

+

+		RFC822Name name1 = null;

+		RFC822Name name1a = null;

+		RFC822Name differentLocalName = null;

+		RFC822Name differentDomainName = null;

+		RFC822Name localCaseName = null;

+		RFC822Name domainCaseName = null;

+		@SuppressWarnings("unused")

+		RFC822Name noAtName = null;

+		

+		try {

+			name1 = RFC822Name.newInstance("localPart@DomainPart");

+			name1a = RFC822Name.newInstance("localPart@DomainPart");

+			differentLocalName = RFC822Name.newInstance("differentlocalPart@DomainPart");

+			differentDomainName = RFC822Name.newInstance("localPart@differentDomainPart");

+			localCaseName = RFC822Name.newInstance("LOCALPart@DomainPart");

+			domainCaseName = RFC822Name.newInstance("localPart@DOMAINPart");

+

+

+		} catch (Exception e) {

+			fail(e.toString());

+		}

+		

+		// should not be able to create a name without an @.  If you try, newInstance returns null

+		Exception exSeen = null;

+		try {

+			noAtName = RFC822Name.newInstance("nameWithoutAnAtSign");

+		} catch (Exception e) {

+			exSeen = e;

+		}

+		assertNotNull(exSeen);

+		

+

+		FunctionArgumentAttributeValue attrName1 = null;

+		FunctionArgumentAttributeValue attrName1a = null;

+		FunctionArgumentAttributeValue attrDifferentLocalName = null;		

+		FunctionArgumentAttributeValue attrDifferentDomainName = null;		

+		FunctionArgumentAttributeValue attrLocalCaseName = null;

+		FunctionArgumentAttributeValue attrDomainCaseName = null;

+		try {

+			attrName1 = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue(name1));

+			attrName1a = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue(name1a));

+			attrDifferentLocalName = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue(differentLocalName));		

+			attrDifferentDomainName = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue(differentDomainName));		

+			attrLocalCaseName = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue(localCaseName));

+			attrDomainCaseName = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue(domainCaseName));

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+

+		FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_RFC822NAME_EQUAL;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_RFC822NAME_EQUAL, fd.getId());

+		assertEquals(DataTypeRFC822Name.newInstance().getId(), fd.getDataTypeArgs().getId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		// test normal equals and non-equals

+		// check separate objects with the same value

+		arguments.add(attrName1);

+		arguments.add(attrName1a);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		// check not same Local

+		arguments.clear();

+		arguments.add(attrName1);

+		arguments.add(attrDifferentLocalName);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// check not same Domain

+		arguments.clear();

+		arguments.add(attrName1);

+		arguments.add(attrDifferentDomainName);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// test case-sensitivity in local part

+		arguments.clear();

+		arguments.add(attrName1);

+		arguments.add(attrLocalCaseName);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// test non-case-sensitivity in Domain part

+		arguments.clear();

+		arguments.add(attrName1);

+		arguments.add(attrDomainCaseName);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// test bad args data types?  Not needed?

+		arguments.clear();

+		arguments.add(stringAttr1);

+		arguments.add(intAttr1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+

+	}

+	

+	

+	/**

+	 * Hex Binary

+	 */

+	@Test

+	public void testHexBinary_Equal() {

+		HexBinary binary = null;

+		HexBinary sameBinary = null;

+		HexBinary differentBinary = null;

+		try {

+			binary = HexBinary.newInstance("e04fd020ea3a6910a2d808002b30309d");

+			sameBinary = HexBinary.newInstance("e04fd020ea3a6910a2d808002b30309d");

+			differentBinary = HexBinary.newInstance("f123a890ee3d");

+		} catch (Exception e) {

+			fail(e.toString());

+		}

+

+		FunctionArgumentAttributeValue attrBinary = null;

+		FunctionArgumentAttributeValue attrSameBinary = null;

+		FunctionArgumentAttributeValue attrDifferentBinary = null;;		

+		try {

+			attrBinary = new FunctionArgumentAttributeValue(DataTypes.DT_HEXBINARY.createAttributeValue(binary));

+			attrSameBinary = new FunctionArgumentAttributeValue(DataTypes.DT_HEXBINARY.createAttributeValue(sameBinary));

+			attrDifferentBinary = new FunctionArgumentAttributeValue(DataTypes.DT_HEXBINARY.createAttributeValue(differentBinary));		

+

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+

+		FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_HEXBINARY_EQUAL;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_HEXBINARY_EQUAL, fd.getId());

+		assertEquals(DataTypes.DT_HEXBINARY.getId(), fd.getDataTypeArgs().getId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		// test normal equals and non-equals

+		// check separate objects with the same value

+		arguments.add(attrBinary);

+		arguments.add(attrSameBinary);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		// check not same

+		arguments.clear();

+		arguments.add(attrBinary);

+		arguments.add(attrDifferentBinary);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+

+		// test bad args data types?  Not needed?

+		arguments.clear();

+		arguments.add(stringAttr1);

+		arguments.add(intAttr1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+

+	}

+	

+	

+	/**

+	 * Base64 Binary

+	 */

+	@Test

+	public void testBase64Binary_Equal() {

+		Base64Binary binary = null;

+		Base64Binary sameBinary = null;

+		Base64Binary differentBinary = null;

+		try {

+			binary = Base64Binary.newInstance("TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz");

+			sameBinary = Base64Binary.newInstance("TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz");

+			differentBinary = Base64Binary.newInstance("f123a890ee3d");

+		} catch (Exception e) {

+			fail(e.toString());

+		}

+

+		FunctionArgumentAttributeValue attrBinary = null;

+		FunctionArgumentAttributeValue attrSameBinary = null;

+		FunctionArgumentAttributeValue attrDifferentBinary = null;		

+		try {

+			attrBinary = new FunctionArgumentAttributeValue(DataTypes.DT_BASE64BINARY.createAttributeValue(binary));

+			attrSameBinary = new FunctionArgumentAttributeValue(DataTypes.DT_BASE64BINARY.createAttributeValue(sameBinary));

+			attrDifferentBinary = new FunctionArgumentAttributeValue(DataTypes.DT_BASE64BINARY.createAttributeValue(differentBinary));		

+

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+

+		FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_BASE64BINARY_EQUAL;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_BASE64BINARY_EQUAL, fd.getId());

+		assertEquals(DataTypes.DT_BASE64BINARY.getId(), fd.getDataTypeArgs().getId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		// test normal equals and non-equals

+		// check separate objects with the same value

+		arguments.add(attrBinary);

+		arguments.add(attrSameBinary);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		// check not same

+		arguments.clear();

+		arguments.add(attrBinary);

+		arguments.add(attrDifferentBinary);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+

+		// test bad args data types?  Not needed?

+		arguments.clear();

+		arguments.add(stringAttr1);

+		arguments.add(intAttr1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+

+	}

+}

diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBagTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBagTest.java
new file mode 100755
index 0000000..e2b9efc
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBagTest.java
@@ -0,0 +1,2173 @@
+package com.att.research.xacmlatt.pdp.std.functions;

+

+import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.assertFalse;

+import static org.junit.Assert.assertNull;

+import static org.junit.Assert.assertTrue;

+import static org.junit.Assert.fail;

+

+import java.util.ArrayList;

+import java.util.List;

+

+import org.junit.Test;

+

+import com.att.research.xacml.api.AttributeValue;

+import com.att.research.xacml.api.XACML3;

+import com.att.research.xacml.std.datatypes.DataTypes;

+import com.att.research.xacmlatt.pdp.policy.Bag;

+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgumentBag;

+import com.att.research.xacmlatt.pdp.std.StdFunctions;

+

+/**

+ * Test of PDP Functions (See XACML core spec section A.3)

+ * 

+ * TO RUN - use jUnit

+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test

+ * 

+ * @author glenngriffin

+ *

+ */

+public class FunctionDefinitionHigherOrderBagTest {

+

+

+	/*

+	 * variables useful in the following tests

+	 */

+	List<FunctionArgument> arguments = new ArrayList<FunctionArgument>();

+	

+	

+	

+	//

+	// ANY-OF tests

+	//

+	

+	

+	@Test

+	public void testAny_of() {

+		String a = "a";

+		String b = "b";

+		String c = "c";

+		String d = "d";

+		String e = "e";

+		String f = "f";

+		String g = "g";

+		String h = "h";

+		String j = "j";

+

+

+		Bag bagabcdefg = null;

+		Bag bagbdfhj = null;

+		Bag bagace = null;

+		Bag bagb = null;

+		Bag bagaaacccef = null;

+		Bag bagInt = null;

+		Bag bagStringInt = null;

+		Bag bagEmpty = null;

+		Bag bagStringBooleansTrue = null;

+		Bag bagStringBooleansFalse = null;

+		

+		

+		// primitive attrs

+		FunctionArgumentAttributeValue attra = null;

+		FunctionArgumentAttributeValue attrb = null;

+		FunctionArgumentAttributeValue attrh = null;

+	

+		

+		// predicates passed as arguments

+		FunctionArgumentAttributeValue attrPredicateStringEqual = null;

+		FunctionArgumentAttributeValue attrPredicateStringIntersection = null;

+		FunctionArgumentAttributeValue attrPredicateBooleanFromString = null;

+

+		try {

+			

+			// Create Bag contents

+			bagabcdefg = new Bag();

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g));

+			bagbdfhj = new Bag();

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j));

+			bagace = new Bag();

+				bagace.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagace.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagace.add(DataTypes.DT_STRING.createAttributeValue(e));

+			bagb = new Bag();

+				bagb.add(DataTypes.DT_STRING.createAttributeValue(b));

+			bagaaacccef = new Bag();

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(e));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(f));

+			bagInt = new Bag();

+				bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));

+			bagStringInt = new Bag();

+				bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));

+			bagEmpty = new Bag();

+			bagStringBooleansTrue = new Bag();

+				bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("false"));

+				bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("false"));

+				bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true"));

+			bagStringBooleansFalse = new Bag();

+				bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false"));

+				bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false"));

+			

+			

+			// create primitive attrs

+			attra = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(a));

+			attrb = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(b));

+			attrh = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(h));

+

+			

+			// predicates passed as function arguments

+			attrPredicateStringEqual = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_EQUAL));

+			attrPredicateStringIntersection = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_INTERSECTION));

+			attrPredicateBooleanFromString = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_BOOLEAN_FROM_STRING));

+

+		} catch (Exception ex) {

+			fail("creating attribute e="+ ex);

+		}

+		

+		// make into attributes

+		FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg);

+		FunctionArgumentBag attrBagbdfhj = new FunctionArgumentBag(bagbdfhj);

+		FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace);

+		FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt);

+		FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty);

+		FunctionArgumentBag attrBagStringBooleansTrue = new FunctionArgumentBag(bagStringBooleansTrue);

+		FunctionArgumentBag attrBagStringBooleansFalse = new FunctionArgumentBag(bagStringBooleansFalse);

+

+		FunctionDefinitionHigherOrderBag<?,?> fd = (FunctionDefinitionHigherOrderBag<?,?>) StdFunctions.FD_ANY_OF;

+

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_ANY_OF, fd.getId());

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		

+		// normal match

+		arguments.clear();

+		arguments.add(attrPredicateStringEqual);

+		arguments.add(attra);

+		arguments.add(attrBagabcdefg);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// bag in first position - match

+		arguments.clear();

+		arguments.add(attrPredicateStringEqual);

+		arguments.add(attrBagabcdefg);

+		arguments.add(attra);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// normal no-match

+		arguments.clear();

+		arguments.add(attrPredicateStringEqual);

+		arguments.add(attra);

+		arguments.add(attrBagbdfhj);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// multiple primitives 

+		arguments.clear();

+		arguments.add(attrPredicateStringEqual);

+		arguments.add(attrh);

+		arguments.add(attrb);

+		arguments.add(attrBagace);

+		arguments.add(attra);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:any-of Predicate error: function:string-equal Expected 2 arguments, got 4", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		

+		// no primitives - predicate function expects 2	

+		arguments.clear();

+		arguments.add(attrPredicateStringEqual);

+		arguments.add(attrBagace);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:any-of Predicate error: function:string-equal Expected 2 arguments, got 1", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// no primitives - predicate expects only 1 arg

+		arguments.clear();

+		arguments.add(attrPredicateBooleanFromString);

+		arguments.add(attrBagStringBooleansTrue);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		arguments.clear();

+		arguments.add(attrPredicateBooleanFromString);

+		arguments.add(attrBagStringBooleansFalse);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// bag is empty

+		arguments.clear();

+		arguments.add(attrPredicateStringEqual);

+		arguments.add(attrh);

+		arguments.add(attrBagEmpty);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+

+		// no bag

+		arguments.clear();

+		arguments.add(attrPredicateStringEqual);

+		arguments.add(attrh);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:any-of Did not get any Bag argument; must have at least 1", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// extra bag

+		arguments.clear();

+		arguments.add(attrPredicateStringEqual);

+		arguments.add(attrh);

+		arguments.add(attrBagStringBooleansTrue);

+		arguments.add(attrh);

+		arguments.add(attrBagStringBooleansTrue);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:any-of must have only 1 bag; found one at index 2 and another at 4", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+	

+		// bad predicate

+		arguments.clear();

+		arguments.add(attrh);

+		arguments.add(attrBagStringInt);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:any-of First argument expected URI, got http://www.w3.org/2001/XMLSchema#string", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// non-boolean predicate

+		arguments.clear();

+		arguments.add(attrPredicateStringIntersection);

+		arguments.add(attrh);

+		arguments.add(attrBagStringInt);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:any-of Predicate Function must return boolean, but 'urn:oasis:names:tc:xacml:1.0:function:string-intersection' returns 'string", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// predicate after first arg

+		arguments.clear();

+		arguments.add(attrPredicateStringEqual);

+		arguments.add(attrPredicateStringIntersection);

+		arguments.add(attrBagStringInt);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:any-of Predicate error: function:string-equal Expected data type 'string' saw 'anyURI' at arg index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// bags of different types

+		arguments.clear();

+		arguments.add(attrPredicateStringEqual);

+		arguments.add(attrh);

+		arguments.add(attrBagStringInt);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		

+		// first null

+		arguments.clear();

+		arguments.add(null);

+		arguments.add(attrBagabcdefg);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:any-of Predicate Function (first argument) was null", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// second null

+		arguments.clear();

+		arguments.add(attrPredicateStringEqual);

+		arguments.add(attrBagabcdefg);

+		arguments.add(null);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:any-of Got null argument at index 2", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+

+	}

+	

+

+	

+	

+	

+	@Test

+	public void testAll_of() {

+		String a = "a";

+		String b = "b";

+		String c = "c";

+		String d = "d";

+		String e = "e";

+		String f = "f";

+		String g = "g";

+		String h = "h";

+		String j = "j";

+		

+		String w = "w";

+

+

+		Bag bagabcdefg = null;

+		Bag bagbdfhj = null;

+		Bag bagace = null;

+		Bag bagb = null;

+		Bag bagaaacccef = null;

+		Bag bagInt = null;

+		Bag bagStringInt = null;

+		Bag bagEmpty = null;

+		Bag bagStringBooleansFalse = null;

+		Bag bagStringBooleansTrue = null;

+		

+		

+		// primitive attrs

+		FunctionArgumentAttributeValue attra = null;

+		FunctionArgumentAttributeValue attrh = null;

+		FunctionArgumentAttributeValue attrw = null;

+

+

+		

+		// predicates passed as arguments

+		FunctionArgumentAttributeValue attrPredicateStringEqual = null;

+		FunctionArgumentAttributeValue attrPredicateStringIntersection = null;

+		FunctionArgumentAttributeValue attrPredicateStringGreaterThan = null;

+		FunctionArgumentAttributeValue attrPredicateBooleanFromString = null;

+

+		try {

+			

+			// Create Bag contents

+			bagabcdefg = new Bag();

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g));

+			bagbdfhj = new Bag();

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j));

+			bagace = new Bag();

+				bagace.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagace.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagace.add(DataTypes.DT_STRING.createAttributeValue(e));

+			bagb = new Bag();

+				bagb.add(DataTypes.DT_STRING.createAttributeValue(b));

+			bagaaacccef = new Bag();

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(e));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(f));

+			bagInt = new Bag();

+				bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));

+			bagStringInt = new Bag();

+				bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));

+			bagEmpty = new Bag();

+			bagStringBooleansTrue = new Bag();

+				bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true"));

+				bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true"));

+				bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true"));

+			bagStringBooleansFalse = new Bag();

+				bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false"));

+				bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false"));

+			

+			

+			

+			// create primitive attrs

+			attra = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(a));

+			attrh = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(h));

+			attrw = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(w));

+

+			

+			// predicates passed as function arguments

+			attrPredicateStringEqual = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_EQUAL));

+			attrPredicateStringIntersection = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_INTERSECTION));

+			attrPredicateStringGreaterThan = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_GREATER_THAN));

+			attrPredicateBooleanFromString = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_BOOLEAN_FROM_STRING));

+

+		} catch (Exception ex) {

+			fail("creating attribute e="+ ex);

+		}

+		

+		// make into attributes

+		FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg);

+		FunctionArgumentBag attrBagbdfhj = new FunctionArgumentBag(bagbdfhj);

+		FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace);

+		FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt);

+		FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty);

+		FunctionArgumentBag attrBagStringBooleansTrue = new FunctionArgumentBag(bagStringBooleansTrue);

+		FunctionArgumentBag attrBagStringBooleansFalse = new FunctionArgumentBag(bagStringBooleansFalse);

+		

+		FunctionDefinitionHigherOrderBag<?,?> fd = (FunctionDefinitionHigherOrderBag<?,?>) StdFunctions.FD_ALL_OF;

+

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_ALL_OF, fd.getId());

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		

+		// normal match

+		arguments.clear();

+		arguments.add(attrPredicateStringGreaterThan);

+		arguments.add(attrw);

+		arguments.add(attrBagace);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// normal no-match

+		arguments.clear();

+		arguments.add(attrPredicateStringGreaterThan);

+		arguments.add(attra);

+		arguments.add(attrBagbdfhj);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// no primitives - predicate function expects 2	

+		arguments.clear();

+		arguments.add(attrPredicateStringEqual);

+		arguments.add(attrBagace);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:all-of Predicate error: function:string-equal Expected 2 arguments, got 1", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// no primitives - predicate expects only 1 arg

+		arguments.clear();

+		arguments.add(attrPredicateBooleanFromString);

+		arguments.add(attrBagStringBooleansTrue);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		arguments.clear();

+		arguments.add(attrPredicateBooleanFromString);

+		arguments.add(attrBagStringBooleansFalse);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// bag is empty

+		arguments.clear();

+		arguments.add(attrPredicateStringGreaterThan);

+		arguments.add(attrh);

+		arguments.add(attrBagEmpty);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		// no bag

+		arguments.clear();

+		arguments.add(attrPredicateStringGreaterThan);

+		arguments.add(attrh);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:all-of Did not get any Bag argument; must have at least 1", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// extra bag

+		arguments.clear();

+		arguments.add(attrPredicateStringEqual);

+		arguments.add(attrh);

+		arguments.add(attrBagStringBooleansTrue);

+		arguments.add(attrh);

+		arguments.add(attrBagStringBooleansTrue);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:all-of must have only 1 bag; found one at index 2 and another at 4", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+	

+		// bad predicate

+		arguments.clear();

+		arguments.add(attrh);

+		arguments.add(attrBagStringInt);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:all-of First argument expected URI, got http://www.w3.org/2001/XMLSchema#string", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// non-boolean predicate

+		arguments.clear();

+		arguments.add(attrPredicateStringIntersection);

+		arguments.add(attrh);

+		arguments.add(attrBagStringInt);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:all-of Predicate Function must return boolean, but 'urn:oasis:names:tc:xacml:1.0:function:string-intersection' returns 'string", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// predicate after first arg

+		arguments.clear();

+		arguments.add(attrPredicateStringGreaterThan);

+		arguments.add(attrPredicateStringIntersection);

+		arguments.add(attrBagStringInt);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:all-of Predicate error: function:string-greater-than Expected data type 'string' saw 'anyURI' at arg index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// bags of different types

+		arguments.clear();

+		arguments.add(attrPredicateStringGreaterThan);

+		arguments.add(attrh);

+		arguments.add(attrBagStringInt);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		

+		// first null

+		arguments.clear();

+		arguments.add(null);

+		arguments.add(attrBagabcdefg);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:all-of Predicate Function (first argument) was null", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// second null

+		arguments.clear();

+		arguments.add(attrPredicateStringGreaterThan);

+		arguments.add(attrBagabcdefg);

+		arguments.add(null);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:all-of Got null argument at index 2", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+

+	}

+	

+	

+	

+

+	

+	

+	

+	

+	

+	

+	

+	

+	

+	@Test

+	public void testAny_of_any() {

+		String a = "a";

+		String b = "b";

+		String c = "c";

+		String d = "d";

+		String e = "e";

+		String f = "f";

+		String g = "g";

+		String h = "h";

+		String j = "j";

+		

+		String w = "w";

+

+

+		Bag bagabcdefg = null;

+		Bag bagbdfhj = null;

+		Bag bagace = null;

+		Bag bagb = null;

+		Bag bagaaacccef = null;

+		Bag bagInt = null;

+		Bag bagStringInt = null;

+		Bag bagEmpty = null;

+		Bag bagStringBooleansFalse = null;

+		Bag bagStringBooleansTrue = null;

+		Bag bagBooleansFalse = null;

+		Bag bagBooleansTrue = null;

+		

+		

+		// primitive attrs

+		FunctionArgumentAttributeValue attra = null;

+		FunctionArgumentAttributeValue attrh = null;

+		FunctionArgumentAttributeValue attrw = null;

+

+		

+		FunctionArgumentAttributeValue attrInt4 = null;

+

+		

+		// predicates passed as arguments

+		FunctionArgumentAttributeValue attrPredicateStringEqual = null;

+		FunctionArgumentAttributeValue attrPredicateStringIntersection = null;

+		FunctionArgumentAttributeValue attrPredicateStringGreaterThan = null;

+		FunctionArgumentAttributeValue attrPredicateBooleanFromString = null;

+		FunctionArgumentAttributeValue attrPredicateNof = null;

+

+		try {

+			

+			// Create Bag contents

+			bagabcdefg = new Bag();

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g));

+			bagbdfhj = new Bag();

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j));

+			bagace = new Bag();

+				bagace.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagace.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagace.add(DataTypes.DT_STRING.createAttributeValue(e));

+			bagb = new Bag();

+				bagb.add(DataTypes.DT_STRING.createAttributeValue(b));

+			bagaaacccef = new Bag();

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(e));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(f));

+			bagInt = new Bag();

+				bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));

+			bagStringInt = new Bag();

+				bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));

+			bagEmpty = new Bag();

+			bagStringBooleansTrue = new Bag();

+				bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true"));

+				bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("false"));

+				bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true"));

+			bagStringBooleansFalse = new Bag();

+				bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false"));

+				bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false"));

+			bagBooleansTrue = new Bag();

+				bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(false));

+				bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(false));

+				bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(true));

+			bagBooleansFalse = new Bag();

+				bagBooleansFalse.add(DataTypes.DT_BOOLEAN.createAttributeValue(false));

+				bagBooleansFalse.add(DataTypes.DT_BOOLEAN.createAttributeValue(false));

+			

+			

+			// create primitive attrs

+			attra = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(a));

+			attrh = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(h));

+			attrw = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(w));

+

+			attrInt4 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(4));

+

+			

+			// predicates passed as function arguments

+			attrPredicateStringEqual = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_EQUAL));

+			attrPredicateStringIntersection = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_INTERSECTION));

+			attrPredicateStringGreaterThan = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_GREATER_THAN));

+			attrPredicateBooleanFromString = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_BOOLEAN_FROM_STRING));

+			attrPredicateNof = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_N_OF));

+

+		} catch (Exception ex) {

+			fail("creating attribute e="+ ex);

+		}

+		

+		// make into attributes

+		FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg);

+		FunctionArgumentBag attrBagbdfhj = new FunctionArgumentBag(bagbdfhj);

+		FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace);

+		FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt);

+		FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty);

+		FunctionArgumentBag attrBagStringBooleansTrue = new FunctionArgumentBag(bagStringBooleansTrue);

+		FunctionArgumentBag attrBagStringBooleansFalse = new FunctionArgumentBag(bagStringBooleansFalse);

+		FunctionArgumentBag attrBagBooleansTrue = new FunctionArgumentBag(bagBooleansTrue);

+		FunctionArgumentBag attrBagBooleansFalse = new FunctionArgumentBag(bagBooleansFalse);

+		

+		FunctionDefinitionHigherOrderBag<?,?> fd = (FunctionDefinitionHigherOrderBag<?,?>) StdFunctions.FD_ANY_OF_ANY;

+

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_ANY_OF_ANY, fd.getId());

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		

+		// normal match

+		arguments.clear();

+		arguments.add(attrPredicateStringGreaterThan);

+		arguments.add(attrw);

+		arguments.add(attrBagace);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// normal no-match

+		arguments.clear();

+		arguments.add(attrPredicateStringGreaterThan);

+		arguments.add(attra);

+		arguments.add(attrBagbdfhj);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// no primitives - predicate function expects 2	

+		arguments.clear();

+		arguments.add(attrPredicateStringEqual);

+		arguments.add(attrBagace);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:any-of-any Predicate error: function:string-equal Expected 2 arguments, got 1", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		arguments.clear();

+		arguments.add(attrPredicateStringEqual);

+		arguments.add(attrBagace);

+		arguments.add(attrBagace);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// no primitives - predicate expects only 1 arg

+		arguments.clear();

+		arguments.add(attrPredicateBooleanFromString);

+		arguments.add(attrBagStringBooleansTrue);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		arguments.clear();

+		arguments.add(attrPredicateBooleanFromString);

+		arguments.add(attrBagStringBooleansFalse);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// n-of with lots of bags - success

+		arguments.clear();

+		arguments.add(attrPredicateNof);

+		arguments.add(attrInt4);

+		arguments.add(attrBagBooleansTrue);

+		arguments.add(attrBagBooleansTrue);

+		arguments.add(attrBagBooleansTrue);

+		arguments.add(attrBagBooleansTrue);

+		arguments.add(attrBagBooleansTrue);

+		arguments.add(attrBagBooleansTrue);

+		arguments.add(attrBagBooleansTrue);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// n-of with lots of bags - fail

+		arguments.clear();

+		arguments.add(attrPredicateNof);

+		arguments.add(attrInt4);

+		arguments.add(attrBagBooleansFalse);

+		arguments.add(attrBagBooleansFalse);

+		arguments.add(attrBagBooleansTrue);

+		arguments.add(attrBagBooleansTrue);

+		arguments.add(attrBagBooleansFalse);

+		arguments.add(attrBagBooleansFalse);

+		arguments.add(attrBagBooleansFalse);

+		arguments.add(attrBagBooleansFalse);

+		arguments.add(attrBagBooleansFalse);

+		arguments.add(attrBagBooleansFalse);

+		arguments.add(attrBagBooleansFalse);

+		arguments.add(attrBagBooleansFalse);

+		arguments.add(attrBagBooleansFalse);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		

+		// bag is empty

+		arguments.clear();

+		arguments.add(attrPredicateStringGreaterThan);

+		arguments.add(attrh);

+		arguments.add(attrBagEmpty);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:any-of-any Bag is empty at index 2", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+

+		// no bag

+		arguments.clear();

+		arguments.add(attrPredicateStringGreaterThan);

+		arguments.add(attrh);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:any-of-any Predicate error: function:string-greater-than Expected 2 arguments, got 1", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		arguments.clear();

+		arguments.add(attrPredicateStringGreaterThan);

+		arguments.add(attrh);

+		arguments.add(attrh);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+	

+		// bad predicate

+		arguments.clear();

+		arguments.add(attrh);

+		arguments.add(attrBagStringInt);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:any-of-any First argument expected URI, got http://www.w3.org/2001/XMLSchema#string", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// non-boolean predicate

+		arguments.clear();

+		arguments.add(attrPredicateStringIntersection);

+		arguments.add(attrh);

+		arguments.add(attrBagStringInt);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:any-of-any Predicate Function must return boolean, but 'urn:oasis:names:tc:xacml:1.0:function:string-intersection' returns 'string", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// predicate after first arg

+		arguments.clear();

+		arguments.add(attrPredicateStringGreaterThan);

+		arguments.add(attrPredicateStringIntersection);

+		arguments.add(attrBagStringInt);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:any-of-any Predicate error: function:string-greater-than Expected data type 'string' saw 'anyURI' at arg index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// bags of different types

+		arguments.clear();

+		arguments.add(attrPredicateStringGreaterThan);

+		arguments.add(attrh);

+		arguments.add(attrBagStringInt);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// first null

+		arguments.clear();

+		arguments.add(null);

+		arguments.add(attrBagabcdefg);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:any-of-any Predicate Function (first argument) was null", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// second null

+		arguments.clear();

+		arguments.add(attrPredicateStringGreaterThan);

+		arguments.add(attrBagabcdefg);

+		arguments.add(null);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:any-of-any Got null argument at index 2", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+

+	}

+	

+	

+	

+	

+	

+	

+	

+	

+	

+	

+	

+	

+	

+	

+	

+	@Test

+	public void testAll_of_any() {

+		String a = "a";

+		String b = "b";

+		String c = "c";

+		String d = "d";

+		String e = "e";

+		String f = "f";

+		String g = "g";

+		String h = "h";

+		String j = "j";

+		

+		String w = "w";

+		String x = "x";

+

+

+		Bag bagabcdefg = null;

+		Bag bagbdfhj = null;

+		Bag bagace = null;

+		Bag bagb = null;

+		Bag bagaaacccef = null;

+		Bag bagawx = null;

+		Bag bagInt = null;

+		Bag bagStringInt = null;

+		Bag bagEmpty = null;

+		Bag bagStringBooleansFalse = null;

+		Bag bagStringBooleansTrue = null;

+		Bag bagBooleansFalse = null;

+		Bag bagBooleansTrue = null;

+		

+		

+		// primitive attrs

+		FunctionArgumentAttributeValue attra = null;

+		FunctionArgumentAttributeValue attrh = null;

+

+		

+

+		

+		// predicates passed as arguments

+		FunctionArgumentAttributeValue attrPredicateStringEqual = null;

+		FunctionArgumentAttributeValue attrPredicateStringIntersection = null;

+		FunctionArgumentAttributeValue attrPredicateStringLessThan = null;

+		FunctionArgumentAttributeValue attrPredicateStringGreaterThan = null;

+		FunctionArgumentAttributeValue attrPredicateBooleanFromString = null;

+

+		try {

+			

+			// Create Bag contents

+			bagabcdefg = new Bag();

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g));

+			bagbdfhj = new Bag();

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j));

+			bagace = new Bag();

+				bagace.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagace.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagace.add(DataTypes.DT_STRING.createAttributeValue(e));

+			bagb = new Bag();

+				bagb.add(DataTypes.DT_STRING.createAttributeValue(b));

+			bagaaacccef = new Bag();

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(e));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(f));

+			bagawx = new Bag();

+				bagawx.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagawx.add(DataTypes.DT_STRING.createAttributeValue(w));

+				bagawx.add(DataTypes.DT_STRING.createAttributeValue(x));

+			bagInt = new Bag();

+				bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));

+			bagStringInt = new Bag();

+				bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));

+			bagEmpty = new Bag();

+			bagStringBooleansTrue = new Bag();

+				bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true"));

+				bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("false"));

+				bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true"));

+			bagStringBooleansFalse = new Bag();

+				bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false"));

+				bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false"));

+			bagBooleansTrue = new Bag();

+				bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(false));

+				bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(false));

+				bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(true));

+			bagBooleansFalse = new Bag();

+				bagBooleansFalse.add(DataTypes.DT_BOOLEAN.createAttributeValue(false));

+				bagBooleansFalse.add(DataTypes.DT_BOOLEAN.createAttributeValue(false));

+			

+			

+			// create primitive attrs

+			attra = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(a));

+			attrh = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(h));

+

+

+			

+			// predicates passed as function arguments

+			attrPredicateStringEqual = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_EQUAL));

+			attrPredicateStringIntersection = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_INTERSECTION));

+			attrPredicateStringLessThan = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_LESS_THAN));

+			attrPredicateStringGreaterThan = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_GREATER_THAN));

+			attrPredicateBooleanFromString = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_BOOLEAN_FROM_STRING));

+

+		} catch (Exception ex) {

+			fail("creating attribute e="+ ex);

+		}

+		

+		// make into attributes

+		FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg);

+		FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace);

+		FunctionArgumentBag attrBagawx = new FunctionArgumentBag(bagawx);

+		FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt);

+		FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty);

+		FunctionArgumentBag attrBagStringBooleansTrue = new FunctionArgumentBag(bagStringBooleansTrue);

+		

+		FunctionDefinitionHigherOrderBag<?,?> fd = (FunctionDefinitionHigherOrderBag<?,?>) StdFunctions.FD_ALL_OF_ANY;

+

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_ALL_OF_ANY, fd.getId());

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		

+		// normal match

+		arguments.clear();

+		arguments.add(attrPredicateStringLessThan);

+		arguments.add(attrBagabcdefg);

+		arguments.add(attrBagawx);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// normal no-match

+		arguments.clear();

+		arguments.add(attrPredicateStringGreaterThan);

+		arguments.add(attrBagace);

+		arguments.add(attrBagawx);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// primitive instead of bag

+		arguments.clear();

+		arguments.add(attrPredicateStringEqual);

+		arguments.add(attra);

+		arguments.add(attrBagace);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:all-of-any 2nd argument must be bag, got 'string'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		arguments.clear();

+		arguments.add(attrPredicateStringEqual);

+		arguments.add(attrBagace);

+		arguments.add(attra);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:all-of-any 3rd argument must be bag, got 'string'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// no primitives - predicate expects only 1 arg

+		arguments.clear();

+		arguments.add(attrPredicateBooleanFromString);

+		arguments.add(attrBagStringBooleansTrue);

+		arguments.add(attrBagStringBooleansTrue);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:all-of-any Predicate error: function:boolean-from-string Expected 1 arguments, got 2", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+

+		

+		// bag is empty

+		arguments.clear();

+		arguments.add(attrPredicateStringGreaterThan);

+		arguments.add(attrBagace);

+		arguments.add(attrBagEmpty);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		arguments.clear();

+		arguments.add(attrPredicateStringGreaterThan);

+		arguments.add(attrBagEmpty);

+		arguments.add(attrBagace);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		// no bag

+		arguments.clear();

+		arguments.add(attrPredicateStringGreaterThan);

+		arguments.add(attrh);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:all-of-any Expected 3 arguments, got 2", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+	

+		// bad predicate

+		arguments.clear();

+		arguments.add(attrh);

+		arguments.add(attrBagStringInt);

+		arguments.add(attrBagStringInt);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:all-of-any First argument expected URI, got http://www.w3.org/2001/XMLSchema#string", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// non-boolean predicate

+		arguments.clear();

+		arguments.add(attrPredicateStringIntersection);

+		arguments.add(attrBagStringInt);

+		arguments.add(attrBagStringInt);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:all-of-any Predicate Function must return boolean, but 'urn:oasis:names:tc:xacml:1.0:function:string-intersection' returns 'string", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// predicate after first arg

+		arguments.clear();

+		arguments.add(attrPredicateStringGreaterThan);

+		arguments.add(attrPredicateStringIntersection);

+		arguments.add(attrBagStringInt);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:all-of-any 2nd argument must be bag, got 'anyURI'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// bags of different types

+		arguments.clear();

+		arguments.add(attrPredicateStringGreaterThan);

+		arguments.add(attrBagace);

+		arguments.add(attrBagStringInt);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:all-of-any Predicate error: function:string-greater-than Expected data type 'string' saw 'integer' at arg index 1", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// no args

+		arguments.clear();

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:all-of-any Expected at least 2 arguments, got 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// one arg

+		arguments.clear();

+		arguments.add(attrBagabcdefg);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:all-of-any Expected at least 2 arguments, got 1", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+

+		// too many args

+		arguments.clear();

+		arguments.add(attrBagabcdefg);

+		arguments.add(attrBagabcdefg);

+		arguments.add(attrBagabcdefg);

+		arguments.add(attrBagabcdefg);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:all-of-any Expected 3 arguments, got 4", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		

+		// first null

+		arguments.clear();

+		arguments.add(null);

+		arguments.add(attrBagabcdefg);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:all-of-any Expected 3 arguments, got 2", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// second null

+		arguments.clear();

+		arguments.add(attrPredicateStringGreaterThan);

+		arguments.add(attrBagabcdefg);

+		arguments.add(null);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:all-of-any 3rd argument must be bag, got 'null'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+

+	}

+	

+	

+	

+	

+	

+	

+	

+	

+	

+	

+	

+

+	@Test

+	public void testAny_of_all() {

+		String a = "a";

+		String b = "b";

+		String c = "c";

+		String d = "d";

+		String e = "e";

+		String f = "f";

+		String g = "g";

+		String h = "h";

+		String j = "j";

+		

+		String w = "w";

+		String x = "x";

+

+

+		Bag bagabcdefg = null;

+		Bag bagbdfhj = null;

+		Bag bagace = null;

+		Bag bagb = null;

+		Bag bagaaacccef = null;

+		Bag bagewx = null;

+		Bag bagInt = null;

+		Bag bagStringInt = null;

+		Bag bagEmpty = null;

+		Bag bagStringBooleansFalse = null;

+		Bag bagStringBooleansTrue = null;

+		Bag bagBooleansFalse = null;

+		Bag bagBooleansTrue = null;

+		

+		

+		// primitive attrs

+		FunctionArgumentAttributeValue attra = null;

+		FunctionArgumentAttributeValue attrh = null;

+

+		

+

+		

+		// predicates passed as arguments

+		FunctionArgumentAttributeValue attrPredicateStringEqual = null;

+		FunctionArgumentAttributeValue attrPredicateStringIntersection = null;

+		FunctionArgumentAttributeValue attrPredicateStringGreaterThanOrEqual = null;

+		FunctionArgumentAttributeValue attrPredicateStringGreaterThan = null;

+		FunctionArgumentAttributeValue attrPredicateBooleanFromString = null;

+

+		try {

+			

+			// Create Bag contents

+			bagabcdefg = new Bag();

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g));

+			bagbdfhj = new Bag();

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j));

+			bagace = new Bag();

+				bagace.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagace.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagace.add(DataTypes.DT_STRING.createAttributeValue(e));

+			bagb = new Bag();

+				bagb.add(DataTypes.DT_STRING.createAttributeValue(b));

+			bagaaacccef = new Bag();

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(e));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(f));

+			bagewx = new Bag();

+				bagewx.add(DataTypes.DT_STRING.createAttributeValue(e));

+				bagewx.add(DataTypes.DT_STRING.createAttributeValue(w));

+				bagewx.add(DataTypes.DT_STRING.createAttributeValue(x));

+			bagInt = new Bag();

+				bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));

+			bagStringInt = new Bag();

+				bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));

+			bagEmpty = new Bag();

+			bagStringBooleansTrue = new Bag();

+				bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true"));

+				bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("false"));

+				bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true"));

+			bagStringBooleansFalse = new Bag();

+				bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false"));

+				bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false"));

+			bagBooleansTrue = new Bag();

+				bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(false));

+				bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(false));

+				bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(true));

+			bagBooleansFalse = new Bag();

+				bagBooleansFalse.add(DataTypes.DT_BOOLEAN.createAttributeValue(false));

+				bagBooleansFalse.add(DataTypes.DT_BOOLEAN.createAttributeValue(false));

+			

+			

+			// create primitive attrs

+			attra = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(a));

+			attrh = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(h));

+

+

+			

+			// predicates passed as function arguments

+			attrPredicateStringEqual = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_EQUAL));

+			attrPredicateStringIntersection = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_INTERSECTION));

+			attrPredicateStringGreaterThanOrEqual = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_GREATER_THAN_OR_EQUAL));

+			attrPredicateStringGreaterThan = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_GREATER_THAN));

+			attrPredicateBooleanFromString = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_BOOLEAN_FROM_STRING));

+

+		} catch (Exception ex) {

+			fail("creating attribute e="+ ex);

+		}

+		

+		// make into attributes

+		FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg);

+		FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace);

+		FunctionArgumentBag attrBagewx = new FunctionArgumentBag(bagewx);

+		FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt);

+		FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty);

+		FunctionArgumentBag attrBagStringBooleansTrue = new FunctionArgumentBag(bagStringBooleansTrue);

+		

+		FunctionDefinitionHigherOrderBag<?,?> fd = (FunctionDefinitionHigherOrderBag<?,?>) StdFunctions.FD_ANY_OF_ALL;

+

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_ANY_OF_ALL, fd.getId());

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		

+		// normal match

+		arguments.clear();

+		arguments.add(attrPredicateStringGreaterThanOrEqual);

+		arguments.add(attrBagewx);

+		arguments.add(attrBagace);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// normal no-match

+		arguments.clear();

+		arguments.add(attrPredicateStringGreaterThan);

+		arguments.add(attrBagace);

+		arguments.add(attrBagewx);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// primitive instead of bag

+		arguments.clear();

+		arguments.add(attrPredicateStringEqual);

+		arguments.add(attra);

+		arguments.add(attrBagace);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:any-of-all 2nd argument must be bag, got 'string'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		arguments.clear();

+		arguments.add(attrPredicateStringEqual);

+		arguments.add(attrBagace);

+		arguments.add(attra);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:any-of-all 3rd argument must be bag, got 'string'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// no primitives - predicate expects only 1 arg

+		arguments.clear();

+		arguments.add(attrPredicateBooleanFromString);

+		arguments.add(attrBagStringBooleansTrue);

+		arguments.add(attrBagStringBooleansTrue);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:any-of-all Predicate error: function:boolean-from-string Expected 1 arguments, got 2", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// bag is empty

+		arguments.clear();

+		arguments.add(attrPredicateStringGreaterThan);

+		arguments.add(attrBagace);

+		arguments.add(attrBagEmpty);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		arguments.clear();

+		arguments.add(attrPredicateStringGreaterThan);

+		arguments.add(attrBagEmpty);

+		arguments.add(attrBagace);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+

+		// no bag

+		arguments.clear();

+		arguments.add(attrPredicateStringGreaterThan);

+		arguments.add(attrh);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:any-of-all Expected 3 arguments, got 2", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+	

+		// bad predicate

+		arguments.clear();

+		arguments.add(attrh);

+		arguments.add(attrBagStringInt);

+		arguments.add(attrBagStringInt);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:any-of-all First argument expected URI, got http://www.w3.org/2001/XMLSchema#string", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// non-boolean predicate

+		arguments.clear();

+		arguments.add(attrPredicateStringIntersection);

+		arguments.add(attrBagStringInt);

+		arguments.add(attrBagStringInt);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:any-of-all Predicate Function must return boolean, but 'urn:oasis:names:tc:xacml:1.0:function:string-intersection' returns 'string", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// predicate after first arg

+		arguments.clear();

+		arguments.add(attrPredicateStringGreaterThan);

+		arguments.add(attrPredicateStringIntersection);

+		arguments.add(attrBagStringInt);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:any-of-all 2nd argument must be bag, got 'anyURI'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// bags of different types

+		arguments.clear();

+		arguments.add(attrPredicateStringGreaterThan);

+		arguments.add(attrBagace);

+		arguments.add(attrBagStringInt);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:any-of-all Predicate error: function:string-greater-than Expected data type 'string' saw 'integer' at arg index 1", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// no args

+		arguments.clear();

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:any-of-all Expected at least 2 arguments, got 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// one arg

+		arguments.clear();

+		arguments.add(attrBagabcdefg);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:any-of-all Expected at least 2 arguments, got 1", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+

+		// too many args

+		arguments.clear();

+		arguments.add(attrBagabcdefg);

+		arguments.add(attrBagabcdefg);

+		arguments.add(attrBagabcdefg);

+		arguments.add(attrBagabcdefg);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:any-of-all Expected 3 arguments, got 4", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		

+		// first null

+		arguments.clear();

+		arguments.add(null);

+		arguments.add(attrBagabcdefg);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:any-of-all Expected 3 arguments, got 2", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// second null

+		arguments.clear();

+		arguments.add(attrPredicateStringGreaterThan);

+		arguments.add(attrBagabcdefg);

+		arguments.add(null);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:any-of-all 3rd argument must be bag, got 'null'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+

+	}

+	

+	

+	

+	

+	

+	

+	@Test

+	public void testAll_of_all() {

+		String a = "a";

+		String b = "b";

+		String c = "c";

+		String d = "d";

+		String e = "e";

+		String f = "f";

+		String g = "g";

+		String h = "h";

+		String j = "j";

+		

+		String w = "w";

+		String x = "x";

+

+

+		Bag bagabcdefg = null;

+		Bag bagbdfhj = null;

+		Bag bagace = null;

+		Bag bagb = null;

+		Bag bagaaacccef = null;

+		Bag bagawx = null;

+		Bag bagwx = null;

+		Bag bagInt = null;

+		Bag bagStringInt = null;

+		Bag bagEmpty = null;

+		Bag bagStringBooleansFalse = null;

+		Bag bagStringBooleansTrue = null;

+		Bag bagBooleansFalse = null;

+		Bag bagBooleansTrue = null;

+		

+		

+		// primitive attrs

+		FunctionArgumentAttributeValue attra = null;

+		FunctionArgumentAttributeValue attrh = null;

+

+		

+

+		

+		// predicates passed as arguments

+		FunctionArgumentAttributeValue attrPredicateStringEqual = null;

+		FunctionArgumentAttributeValue attrPredicateStringIntersection = null;

+		FunctionArgumentAttributeValue attrPredicateStringGreaterThan = null;

+		FunctionArgumentAttributeValue attrPredicateBooleanFromString = null;

+

+		try {

+			

+			// Create Bag contents

+			bagabcdefg = new Bag();

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g));

+			bagbdfhj = new Bag();

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j));

+			bagace = new Bag();

+				bagace.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagace.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagace.add(DataTypes.DT_STRING.createAttributeValue(e));

+			bagb = new Bag();

+				bagb.add(DataTypes.DT_STRING.createAttributeValue(b));

+			bagaaacccef = new Bag();

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(e));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(f));

+			bagawx = new Bag();

+				bagawx.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagawx.add(DataTypes.DT_STRING.createAttributeValue(w));

+				bagawx.add(DataTypes.DT_STRING.createAttributeValue(x));

+			bagwx = new Bag();

+				bagwx.add(DataTypes.DT_STRING.createAttributeValue(w));

+				bagwx.add(DataTypes.DT_STRING.createAttributeValue(x));

+			bagInt = new Bag();

+				bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));

+			bagStringInt = new Bag();

+				bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));

+			bagEmpty = new Bag();

+			bagStringBooleansTrue = new Bag();

+				bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true"));

+				bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("false"));

+				bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true"));

+			bagStringBooleansFalse = new Bag();

+				bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false"));

+				bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false"));

+			bagBooleansTrue = new Bag();

+				bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(false));

+				bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(false));

+				bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(true));

+			bagBooleansFalse = new Bag();

+				bagBooleansFalse.add(DataTypes.DT_BOOLEAN.createAttributeValue(false));

+				bagBooleansFalse.add(DataTypes.DT_BOOLEAN.createAttributeValue(false));

+			

+			

+			// create primitive attrs

+			attra = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(a));

+			attrh = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(h));

+

+

+			

+			// predicates passed as function arguments

+			attrPredicateStringEqual = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_EQUAL));

+			attrPredicateStringIntersection = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_INTERSECTION));

+			attrPredicateStringGreaterThan = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_GREATER_THAN));

+			attrPredicateBooleanFromString = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_BOOLEAN_FROM_STRING));

+

+		} catch (Exception ex) {

+			fail("creating attribute e="+ ex);

+		}

+		

+		// make into attributes

+		FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg);

+		FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace);

+		FunctionArgumentBag attrBagawx = new FunctionArgumentBag(bagawx);

+		FunctionArgumentBag attrBagwx = new FunctionArgumentBag(bagwx);

+		FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt);

+		FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty);

+		FunctionArgumentBag attrBagStringBooleansTrue = new FunctionArgumentBag(bagStringBooleansTrue);

+		

+		FunctionDefinitionHigherOrderBag<?,?> fd = (FunctionDefinitionHigherOrderBag<?,?>) StdFunctions.FD_ALL_OF_ALL;

+

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_ALL_OF_ALL, fd.getId());

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		

+		// normal match

+		arguments.clear();

+		arguments.add(attrPredicateStringGreaterThan);

+		arguments.add(attrBagwx);

+		arguments.add(attrBagace);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// normal no-match

+		arguments.clear();

+		arguments.add(attrPredicateStringGreaterThan);

+		arguments.add(attrBagawx);

+		arguments.add(attrBagace);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		arguments.clear();

+		arguments.add(attrPredicateStringGreaterThan);

+		arguments.add(attrBagace);

+		arguments.add(attrBagwx);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// primitive instead of bag

+		arguments.clear();

+		arguments.add(attrPredicateStringEqual);

+		arguments.add(attra);

+		arguments.add(attrBagace);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:all-of-all 2nd argument must be bag, got 'string'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		arguments.clear();

+		arguments.add(attrPredicateStringEqual);

+		arguments.add(attrBagace);

+		arguments.add(attra);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:all-of-all 3rd argument must be bag, got 'string'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// no primitives - predicate expects only 1 arg

+		arguments.clear();

+		arguments.add(attrPredicateBooleanFromString);

+		arguments.add(attrBagStringBooleansTrue);

+		arguments.add(attrBagStringBooleansTrue);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:all-of-all Predicate error: function:boolean-from-string Expected 1 arguments, got 2", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// bag is empty

+		arguments.clear();

+		arguments.add(attrPredicateStringGreaterThan);

+		arguments.add(attrBagace);

+		arguments.add(attrBagEmpty);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		arguments.clear();

+		arguments.add(attrPredicateStringGreaterThan);

+		arguments.add(attrBagEmpty);

+		arguments.add(attrBagace);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		// no bag

+		arguments.clear();

+		arguments.add(attrPredicateStringGreaterThan);

+		arguments.add(attrh);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:all-of-all Expected 3 arguments, got 2", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+	

+		// bad predicate

+		arguments.clear();

+		arguments.add(attrh);

+		arguments.add(attrBagStringInt);

+		arguments.add(attrBagStringInt);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:all-of-all First argument expected URI, got http://www.w3.org/2001/XMLSchema#string", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// non-boolean predicate

+		arguments.clear();

+		arguments.add(attrPredicateStringIntersection);

+		arguments.add(attrBagStringInt);

+		arguments.add(attrBagStringInt);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:all-of-all Predicate Function must return boolean, but 'urn:oasis:names:tc:xacml:1.0:function:string-intersection' returns 'string", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// predicate after first arg

+		arguments.clear();

+		arguments.add(attrPredicateStringGreaterThan);

+		arguments.add(attrPredicateStringIntersection);

+		arguments.add(attrBagStringInt);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:all-of-all 2nd argument must be bag, got 'anyURI'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// bags of different types

+		arguments.clear();

+		arguments.add(attrPredicateStringGreaterThan);

+		arguments.add(attrBagwx);

+		arguments.add(attrBagStringInt);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:all-of-all Predicate error: function:string-greater-than Expected data type 'string' saw 'integer' at arg index 1", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// no args

+		arguments.clear();

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:all-of-all Expected at least 2 arguments, got 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// one arg

+		arguments.clear();

+		arguments.add(attrBagabcdefg);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:all-of-all Expected at least 2 arguments, got 1", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+

+		// too many args

+		arguments.clear();

+		arguments.add(attrBagabcdefg);

+		arguments.add(attrBagabcdefg);

+		arguments.add(attrBagabcdefg);

+		arguments.add(attrBagabcdefg);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:all-of-all Expected 3 arguments, got 4", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		

+		// first null

+		arguments.clear();

+		arguments.add(null);

+		arguments.add(attrBagabcdefg);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:all-of-all Expected 3 arguments, got 2", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// second null

+		arguments.clear();

+		arguments.add(attrPredicateStringGreaterThan);

+		arguments.add(attrBagabcdefg);

+		arguments.add(null);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:all-of-all 3rd argument must be bag, got 'null'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+

+	}

+	

+	

+	

+	

+	

+	

+	

+	

+	

+	

+	@Test

+	public void testMap() {

+		String a = "a";

+		String b = "b";

+		String c = "c";

+		String d = "d";

+		String e = "e";

+		String f = "f";

+		String g = "g";

+		String h = "h";

+		String j = "j";

+

+

+		Bag bagabcdefg = null;

+		Bag bagbdfhj = null;

+		Bag bagace = null;

+		Bag bagb = null;

+		Bag bagaaacccef = null;

+		Bag bagInt = null;

+		Bag bagStringInt = null;

+		Bag bagEmpty = null;

+		Bag bagStringBooleansFalse = null;

+		Bag bagStringBooleansTrue = null;

+		Bag bagInt123 = null;

+		Bag bagInt789 = null;

+		

+		

+		// primitive attrs

+		FunctionArgumentAttributeValue attrh = null;

+		FunctionArgumentAttributeValue attrInt7 = null;

+

+

+		

+		// predicates passed as arguments

+		FunctionArgumentAttributeValue attrPredicateStringNormalizeToLowerCase = null;

+		FunctionArgumentAttributeValue attrPredicateIntegerEqual = null;

+		FunctionArgumentAttributeValue attrPredicateIntegerAdd = null;

+

+		try {

+			

+			// Create Bag contents

+			bagabcdefg = new Bag();

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g));

+			bagbdfhj = new Bag();

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j));

+			bagace = new Bag();

+				bagace.add(DataTypes.DT_STRING.createAttributeValue("A"));

+				bagace.add(DataTypes.DT_STRING.createAttributeValue("C"));

+				bagace.add(DataTypes.DT_STRING.createAttributeValue("E"));

+			bagb = new Bag();

+				bagb.add(DataTypes.DT_STRING.createAttributeValue(b));

+			bagaaacccef = new Bag();

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(e));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(f));

+			bagInt = new Bag();

+				bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));

+			bagStringInt = new Bag();

+				bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a));

+				

+				bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));

+			bagEmpty = new Bag();

+			bagStringBooleansTrue = new Bag();

+				bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true"));

+				bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true"));

+				bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true"));

+			bagStringBooleansFalse = new Bag();

+				bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false"));

+				bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false"));

+			bagInt123 = new Bag();

+				bagInt123.add(DataTypes.DT_INTEGER.createAttributeValue(1));

+				bagInt123.add(DataTypes.DT_INTEGER.createAttributeValue(2));

+				bagInt123.add(DataTypes.DT_INTEGER.createAttributeValue(3));

+			bagInt789 = new Bag();

+				bagInt789.add(DataTypes.DT_INTEGER.createAttributeValue(7));

+				bagInt789.add(DataTypes.DT_INTEGER.createAttributeValue(8));

+				bagInt789.add(DataTypes.DT_INTEGER.createAttributeValue(9));

+			

+			

+			

+			// create primitive attrs

+			attrh = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(h));

+			attrInt7 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(7));

+

+			

+			// predicates passed as function arguments

+			attrPredicateStringNormalizeToLowerCase = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_NORMALIZE_TO_LOWER_CASE));

+			attrPredicateIntegerEqual = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_INTEGER_EQUAL));

+			attrPredicateIntegerAdd = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_INTEGER_ADD));

+

+		} catch (Exception ex) {

+			fail("creating attribute e="+ ex);

+		}

+		

+		// make into attributes

+		FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg);

+		FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace);

+		FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt);

+		FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty);

+		FunctionArgumentBag attrBagStringBooleansTrue = new FunctionArgumentBag(bagStringBooleansTrue);

+		FunctionArgumentBag attrBagInt789 = new FunctionArgumentBag(bagInt789);

+	

+		FunctionDefinitionHigherOrderBag<?,?> fd = (FunctionDefinitionHigherOrderBag<?,?>) StdFunctions.FD_MAP;

+

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_MAP, fd.getId());

+		assertNull( fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertTrue(fd.returnsBag());

+		

+		// normal match

+		arguments.clear();

+		arguments.add(attrPredicateStringNormalizeToLowerCase);

+		arguments.add(attrBagace);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertTrue(res.isBag());

+		Bag bag = res.getBag();

+		assertEquals(3, bag.size());

+		List<AttributeValue<?>> bagAttributes = bag.getAttributeValueList();

+		try {

+			assertTrue(bagAttributes.contains(DataTypes.DT_STRING.createAttributeValue("a")));

+			assertFalse(bagAttributes.contains(DataTypes.DT_STRING.createAttributeValue("A")));

+			assertTrue(bagAttributes.contains(DataTypes.DT_STRING.createAttributeValue("c")));

+			assertFalse(bagAttributes.contains(DataTypes.DT_STRING.createAttributeValue("C")));

+			assertTrue(bagAttributes.contains(DataTypes.DT_STRING.createAttributeValue("e")));

+			assertFalse(bagAttributes.contains(DataTypes.DT_STRING.createAttributeValue("E")));

+		} catch (Exception ex) {

+			fail("checking result e="+ex);

+		}

+		

+		// 2-input predicate

+		arguments.clear();

+		arguments.add(attrPredicateIntegerAdd);

+		arguments.add(attrInt7);

+		arguments.add(attrBagInt789);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertTrue(res.isBag());

+		bag = res.getBag();

+		assertEquals(3, bag.size());

+		bagAttributes = bag.getAttributeValueList();

+		try {

+			assertTrue(bagAttributes.contains(DataTypes.DT_INTEGER.createAttributeValue("14")));

+			assertTrue(bagAttributes.contains(DataTypes.DT_INTEGER.createAttributeValue("15")));

+			assertTrue(bagAttributes.contains(DataTypes.DT_INTEGER.createAttributeValue("16")));

+		} catch (Exception ex) {

+			fail("checking result e="+ex);

+		}

+		

+		

+		// predicate returns booleans

+		arguments.clear();

+		arguments.add(attrPredicateIntegerEqual);

+		arguments.add(attrInt7);

+		arguments.add(attrBagInt789);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertTrue(res.isBag());

+		bag = res.getBag();

+		assertEquals(3, bag.size());

+		bagAttributes = bag.getAttributeValueList();

+		try {

+			assertEquals(bagAttributes.get(0), (DataTypes.DT_BOOLEAN.createAttributeValue(true)));

+			assertEquals(bagAttributes.get(1), (DataTypes.DT_BOOLEAN.createAttributeValue(false)));

+			assertEquals(bagAttributes.get(2), (DataTypes.DT_BOOLEAN.createAttributeValue(false)));

+		} catch (Exception ex) {

+			fail("checking result e="+ex);

+		}

+		

+		// predicate returns bag

+

+		

+	

+		// no primitives - predicate function expects 2	

+		arguments.clear();

+		arguments.add(attrPredicateIntegerAdd);

+		arguments.add(attrBagace);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:map Predicate error: function:integer-add Expected 2 arguments, got 1", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// bag is empty

+		arguments.clear();

+		arguments.add(attrPredicateStringNormalizeToLowerCase);

+		arguments.add(attrh);

+		arguments.add(attrBagEmpty);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertTrue(res.isBag());

+		bag = res.getBag();

+		assertEquals(0, bag.size());;

+

+		// no bag

+		arguments.clear();

+		arguments.add(attrPredicateStringNormalizeToLowerCase);

+		arguments.add(attrh);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:map Did not get any Bag argument; must have at least 1", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// extra bag

+		arguments.clear();

+		arguments.add(attrPredicateStringNormalizeToLowerCase);

+		arguments.add(attrh);

+		arguments.add(attrBagStringBooleansTrue);

+		arguments.add(attrh);

+		arguments.add(attrBagStringBooleansTrue);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:map must have only 1 bag; found one at index 2 and another at 4", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+	

+		// bad predicate

+		arguments.clear();

+		arguments.add(attrh);

+		arguments.add(attrBagStringInt);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:map First argument expected URI, got http://www.w3.org/2001/XMLSchema#string", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// predicate gets unexpected number of args

+		arguments.clear();

+		arguments.add(attrPredicateStringNormalizeToLowerCase);

+		arguments.add(attrh);

+		arguments.add(attrBagStringInt);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:map Predicate error: function:string-normalize-to-lower-case Expected 1 arguments, got 2", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// predicate gets bad primitive type

+		arguments.clear();

+		arguments.add(attrPredicateStringNormalizeToLowerCase);

+		arguments.add(attrPredicateStringNormalizeToLowerCase);

+		arguments.add(attrBagStringInt);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:map Predicate error: function:string-normalize-to-lower-case Expected 1 arguments, got 2", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// bags of different types

+		arguments.clear();

+		arguments.add(attrPredicateStringNormalizeToLowerCase);

+		arguments.add(attrh);

+		arguments.add(attrBagStringInt);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		

+		// first null

+		arguments.clear();

+		arguments.add(null);

+		arguments.add(attrBagabcdefg);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:map Predicate Function (first argument) was null", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// second null

+		arguments.clear();

+		arguments.add(attrPredicateStringNormalizeToLowerCase);

+		arguments.add(attrBagabcdefg);

+		arguments.add(null);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:map Got null argument at index 2", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+

+	}

+	

+	

+	

+

+}

diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHomogeneousSimpleTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHomogeneousSimpleTest.java
new file mode 100755
index 0000000..e281212
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHomogeneousSimpleTest.java
@@ -0,0 +1,140 @@
+/*

+ *                        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.std.functions;

+

+import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.assertFalse;

+import static org.junit.Assert.assertTrue;

+import static org.junit.Assert.fail;

+

+import java.util.ArrayList;

+import java.util.List;

+

+import org.junit.Test;

+

+import com.att.research.xacml.api.Status;

+import com.att.research.xacml.api.XACML3;

+import com.att.research.xacml.std.datatypes.DataTypes;

+import com.att.research.xacmlatt.pdp.policy.Bag;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgumentBag;

+

+/**

+ * FunctionDefinitionHomogeneousSimple is an abstract class, so we have to test it by creating a sub-class.

+ * The constructor is tested by default when an instance of the sub-class is created for other tests.

+ * 

+ * Each of these functions needs to be tested for each type of function to be sure the values are correct,

+ * so this is just a simple test to see that the mechanism works.

+ * 

+ * TO RUN - use jUnit

+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test

+ * 

+ * @author glenngriffin

+ *

+ */

+public class FunctionDefinitionHomogeneousSimpleTest {

+

+

+

+	@Test

+	public void testGetDataTypeArgs() {

+		

+		// test a simple instance using the Equality class

+		FunctionDefinitionEquality<String> fd   = new FunctionDefinitionEquality<String>(XACML3.ID_FUNCTION_STRING_EQUAL, DataTypes.DT_STRING);

+		assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId());

+	}

+

+	@Test

+	public void testGetNumArgs() {

+		// test a simple instance using the Equality class

+		FunctionDefinitionEquality<String> fd   = new FunctionDefinitionEquality<String>(XACML3.ID_FUNCTION_STRING_EQUAL, DataTypes.DT_STRING);

+		assertEquals(new Integer(2), fd.getNumArgs());

+	}

+

+	@Test

+	public void testValidateArguments() {

+		// create some arguments to use later

+		FunctionArgumentAttributeValue stringAttr1 = null;

+		FunctionArgumentAttributeValue stringAttr2 = null;

+		FunctionArgumentAttributeValue stringAttr3 = null;

+		FunctionArgumentAttributeValue intAttr = null;

+		try {

+			stringAttr1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("abc"));

+			stringAttr2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("def"));

+			stringAttr3 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("ghi"));

+			intAttr = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1));

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+		

+		FunctionDefinitionEquality<String> fd   = new FunctionDefinitionEquality<String>(XACML3.ID_FUNCTION_STRING_EQUAL, DataTypes.DT_STRING);

+		List<String> convertedValues = new ArrayList<String>();

+		List<FunctionArgument> listFunctionArguments = new ArrayList<FunctionArgument>();

+		

+		// test correct # of args, both of them strings

+		listFunctionArguments.add(stringAttr1);

+		listFunctionArguments.add(stringAttr2);

+		Status status = fd.validateArguments(listFunctionArguments, convertedValues);

+		assertTrue(status.isOk());

+		assertEquals(convertedValues.size(),2);

+		

+		// test too few args

+		listFunctionArguments.remove(1);

+		status = fd.validateArguments(listFunctionArguments, convertedValues);

+		assertFalse(status.isOk());

+		assertEquals("Expected 2 arguments, got 1", status.getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", status.getStatusCode().getStatusCodeValue().stringValue());

+		

+		// test too many args

+		listFunctionArguments.add(stringAttr2);

+		listFunctionArguments.add(stringAttr3);

+		status = fd.validateArguments(listFunctionArguments, convertedValues);

+		assertFalse(status.isOk());

+		assertEquals("Expected 2 arguments, got 3", status.getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", status.getStatusCode().getStatusCodeValue().stringValue());

+		

+		// test with null arg

+		listFunctionArguments.clear();

+		listFunctionArguments.add(null);

+		listFunctionArguments.add(stringAttr1);

+		status = fd.validateArguments(listFunctionArguments, convertedValues);

+		assertFalse(status.isOk());

+		assertEquals("Got null argument at arg index 0", status.getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", status.getStatusCode().getStatusCodeValue().stringValue());

+

+		// test function that takes 0 args

+//TODO test with func that specifies 0 args? ASSUME for now that there are no such functions since a function needs to operate on something

+//		fail("need to test function with 0 args and various inputs - see validateArguments code");

+		

+

+		// test with one is a bag

+		listFunctionArguments.clear();

+		listFunctionArguments.add(stringAttr1);

+		Bag bag = new Bag();

+		FunctionArgument bagArg = new FunctionArgumentBag(bag);

+		listFunctionArguments.add(bagArg);

+		status = fd.validateArguments(listFunctionArguments, convertedValues);

+		assertFalse(status.isOk());

+		assertEquals("Expected a simple value, saw a bag at arg index 1", status.getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", status.getStatusCode().getStatusCodeValue().stringValue());

+		

+		// test with string and int

+		listFunctionArguments.clear();

+		listFunctionArguments.add(stringAttr1);

+		listFunctionArguments.add(intAttr);

+		status = fd.validateArguments(listFunctionArguments, convertedValues);

+		assertFalse(status.isOk());

+		assertEquals("Expected data type 'string' saw 'integer' at arg index 1", status.getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", status.getStatusCode().getStatusCodeValue().stringValue());

+	}

+

+}

diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogicalTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogicalTest.java
new file mode 100755
index 0000000..9db4610
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogicalTest.java
@@ -0,0 +1,402 @@
+package com.att.research.xacmlatt.pdp.std.functions;

+

+import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.assertFalse;

+import static org.junit.Assert.assertTrue;

+import static org.junit.Assert.fail;

+

+import java.util.ArrayList;

+import java.util.List;

+

+import org.junit.Test;

+

+import com.att.research.xacml.api.XACML3;

+import com.att.research.xacml.std.datatypes.DataTypes;

+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue;

+import com.att.research.xacmlatt.pdp.std.StdFunctions;

+

+/**

+ * Test of PDP Functions (See XACML core spec section A.3)

+ * 

+ * TO RUN - use jUnit

+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test

+ * 

+ * @author glenngriffin

+ *

+ */

+public class FunctionDefinitionLogicalTest {

+

+	/*

+	 * variables useful in the following tests

+	 */

+	List<FunctionArgument> arguments = new ArrayList<FunctionArgument>();

+	

+	// use the same args for each test

+	FunctionArgumentAttributeValue attrT = null;

+	FunctionArgumentAttributeValue attrF = null;

+	public FunctionDefinitionLogicalTest () {

+		try {

+			attrT = new FunctionArgumentAttributeValue(DataTypes.DT_BOOLEAN.createAttributeValue(true));

+			attrF = new FunctionArgumentAttributeValue(DataTypes.DT_BOOLEAN.createAttributeValue(false));

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+	}

+	

+	

+	@Test

+	public void testOR() {

+		FunctionArgumentAttributeValue attr5 = null;

+		try {

+			attr5 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(5));

+

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+		

+		FunctionDefinitionLogical fd = (FunctionDefinitionLogical) StdFunctions.FD_OR;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_OR, fd.getId());

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		

+		

+		// test normal 

+		arguments.add(attrT);

+		arguments.add(attrF);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertEquals(new Boolean(true), resValue);

+		

+		arguments.clear();

+		arguments.add(attrF);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(new Boolean(false), resValue);

+		

+		//	test no args

+		arguments.clear();

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(new Boolean(false), resValue);

+		

+		// first true, second error

+		arguments.clear();

+		arguments.add(attrT);

+		arguments.add(null);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(new Boolean(true), resValue);

+		

+		// first false, second error

+		arguments.clear();

+		arguments.add(attrF);

+		arguments.add(null);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:or Got null argument", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// multiple false

+		arguments.clear();

+		arguments.add(attrF);

+		arguments.add(attrF);

+		arguments.add(attrF);

+		arguments.add(attrF);

+		arguments.add(attrF);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(new Boolean(false), resValue);

+		

+		// non-boolean

+		arguments.clear();

+		arguments.add(attrF);

+		arguments.add(attr5);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:or Expected data type 'boolean' saw 'integer'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// first arg error

+		arguments.clear();

+		arguments.add(null);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:or Got null argument", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+	}

+

+	

+	@Test

+	public void testAND() {

+		FunctionArgumentAttributeValue attr5 = null;

+		try {

+			attr5 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(5));

+

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+		

+		

+		FunctionDefinitionLogical fd = (FunctionDefinitionLogical) StdFunctions.FD_AND;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_AND, fd.getId());

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		

+		

+		// test normal 

+		arguments.add(attrT);

+		arguments.add(attrF);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertEquals(new Boolean(false), resValue);

+		

+		arguments.clear();

+		arguments.add(attrF);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(new Boolean(false), resValue);

+		

+		//	test no args

+		arguments.clear();

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(new Boolean(true), resValue);

+		

+		// first true, second error

+		arguments.clear();

+		arguments.add(attrT);

+		arguments.add(null);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:and Got null argument", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// first false, second error

+		arguments.clear();

+		arguments.add(attrF);

+		arguments.add(null);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(new Boolean(false), resValue);

+		

+		// multiple true

+		arguments.clear();

+		arguments.add(attrT);

+		arguments.add(attrT);

+		arguments.add(attrT);

+		arguments.add(attrT);

+		arguments.add(attrT);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(new Boolean(true), resValue);

+		

+		// non-boolean

+		arguments.clear();

+		arguments.add(attrT);

+		arguments.add(attr5);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals("function:and Expected data type 'boolean' saw 'integer'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// first arg error

+		arguments.clear();

+		arguments.add(null);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals("function:and Got null argument", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+	}

+	

+	

+	

+	

+	@Test

+	public void testN_of() {

+		FunctionArgumentAttributeValue attr0 = null;

+		FunctionArgumentAttributeValue attr2 = null;

+		try {

+			attr0 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(0));

+			attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(2));

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+		

+		

+		FunctionDefinitionLogical fd = (FunctionDefinitionLogical) StdFunctions.FD_N_OF;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_N_OF, fd.getId());

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		

+		

+		// test normal 

+		arguments.add(attr2);

+		arguments.add(attrT);

+		arguments.add(attrF);

+		arguments.add(attrT);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertEquals(new Boolean(true), resValue);

+		

+		// normal fail

+		arguments.clear();

+		arguments.add(attr2);

+		arguments.add(attrT);

+		arguments.add(attrF);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(new Boolean(false), resValue);

+		

+		

+		// null count

+		arguments.clear();

+		arguments.add(null);

+		arguments.add(attrT);

+		arguments.add(attrF);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(new Boolean(true), resValue);

+		

+		// 0 count

+		arguments.clear();

+		arguments.add(attr0);

+		arguments.add(attrT);

+		arguments.add(attrF);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(new Boolean(true), resValue);

+		

+		// bad object type for count

+		arguments.clear();

+		arguments.add(attrT);

+		arguments.add(attrT);

+		arguments.add(attrF);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:n-of For input string: \"true\"", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// count larger than list

+		arguments.clear();

+		arguments.add(attr2);

+		arguments.add(attrT);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:n-of Expected 2 arguments but only 1 arguments in list after the count", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// aborts after find ok

+		arguments.clear();

+		arguments.add(attr2);

+		arguments.add(attrT);

+		arguments.add(attrT);

+		arguments.add(null);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(new Boolean(true), resValue);

+		

+		// error before find ok

+		arguments.clear();

+		arguments.add(attr2);

+		arguments.add(null);

+		arguments.add(attrT);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:n-of Got null argument", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		

+		// non-boolean in list

+		arguments.clear();

+		arguments.add(attr2);

+		arguments.add(attrT);

+		arguments.add(attr0);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:n-of Expected data type 'boolean' saw 'integer'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+				

+	}

+	

+	

+	@Test

+	public void testNot() {

+		

+		FunctionDefinitionLogical fd = (FunctionDefinitionLogical) StdFunctions.FD_NOT;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_NOT, fd.getId());

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		

+		

+		// test normal 

+		arguments.clear();

+		arguments.add(attrT);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertEquals(new Boolean(false), resValue);

+		

+		arguments.clear();

+		arguments.add(attrF);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(new Boolean(true), resValue);

+		

+		

+		// test null/0 args

+		arguments.clear();

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:not Expected 1 argument, got 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// test 2 args

+		arguments.clear();

+		arguments.add(attrT);

+		arguments.add(attrF);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:not Expected 1 argument, got 2", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+	}

+}

diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionNumberTypeConversionTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionNumberTypeConversionTest.java
new file mode 100755
index 0000000..add8069
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionNumberTypeConversionTest.java
@@ -0,0 +1,99 @@
+package com.att.research.xacmlatt.pdp.std.functions;

+

+import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.assertFalse;

+import static org.junit.Assert.assertTrue;

+import static org.junit.Assert.fail;

+

+import java.math.BigInteger;

+import java.util.ArrayList;

+import java.util.List;

+

+import org.junit.Test;

+

+import com.att.research.xacml.api.XACML3;

+import com.att.research.xacml.std.datatypes.DataTypes;

+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue;

+import com.att.research.xacmlatt.pdp.std.StdFunctions;

+

+/**

+ * Tests for various classes containing only one function.

+ * 

+ * TO RUN - use jUnit

+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test

+ * 

+ * @author glenngriffin

+ *

+ */

+public class FunctionDefinitionNumberTypeConversionTest {

+	

+	/*

+	 * variables useful in the following tests

+	 */

+	List<FunctionArgument> arguments = new ArrayList<FunctionArgument>();

+	

+	@Test

+	public void testDouble_to_integer() {

+		FunctionArgumentAttributeValue attr1 = null;

+		try {

+			attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(5.432));

+

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+		

+		FunctionDefinitionNumberTypeConversion<?, ?> fd = (FunctionDefinitionNumberTypeConversion<?, ?>) StdFunctions.FD_DOUBLE_TO_INTEGER;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_DOUBLE_TO_INTEGER, fd.getId());

+		assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(1), fd.getNumArgs());

+		

+		

+		// test normal add

+		arguments.add(attr1);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		BigInteger resValue = (BigInteger)res.getValue().getValue();

+		assertEquals(BigInteger.valueOf(5), resValue);

+	}

+

+	

+	@Test

+	public void testInteger_to_double() {

+		FunctionArgumentAttributeValue attr1 = null;

+		try {

+			attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(5));

+

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+		

+		FunctionDefinitionNumberTypeConversion<?, ?> fd = (FunctionDefinitionNumberTypeConversion<?, ?>) StdFunctions.FD_INTEGER_TO_DOUBLE;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_INTEGER_TO_DOUBLE, fd.getId());

+		assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(1), fd.getNumArgs());

+		

+		

+		// test normal add

+		arguments.add(attr1);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Double resValue = (Double)res.getValue().getValue();

+		assertEquals(new Double(5.0), resValue);

+	}

+	

+	

+}

diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRegexpMatchTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRegexpMatchTest.java
new file mode 100755
index 0000000..1381076
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRegexpMatchTest.java
@@ -0,0 +1,491 @@
+package com.att.research.xacmlatt.pdp.std.functions;

+

+import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.assertFalse;

+import static org.junit.Assert.assertTrue;

+import static org.junit.Assert.fail;

+

+import java.net.URI;

+import java.util.ArrayList;

+import java.util.List;

+

+import javax.security.auth.x500.X500Principal;

+

+import org.junit.Test;

+

+import com.att.research.xacml.api.XACML3;

+import com.att.research.xacml.std.datatypes.DataTypes;

+import com.att.research.xacml.std.datatypes.IPAddress;

+import com.att.research.xacml.std.datatypes.RFC2396DomainName;

+import com.att.research.xacml.std.datatypes.RFC822Name;

+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue;

+import com.att.research.xacmlatt.pdp.std.StdFunctions;

+

+/**

+ * Test of PDP Functions (See XACML core spec section A.3)

+ * 

+ * TO RUN - use jUnit

+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test

+ * 

+ * @author glenngriffin

+ *

+ */

+public class FunctionDefinitionRegexpMatchTest {

+

+

+	/*

+	 * variables useful in the following tests

+	 */

+	List<FunctionArgument> arguments = new ArrayList<FunctionArgument>();

+	

+	

+	@Test

+	public void testString() {

+		String v1 = new String("abc");

+		String v2 = new String("def");

+

+		

+		FunctionArgumentAttributeValue attrV1 = null;

+		FunctionArgumentAttributeValue attrV2 = null;

+		FunctionArgumentAttributeValue attrNull = null;

+		FunctionArgumentAttributeValue attrInteger = null;

+		try {

+			attrV1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v1));

+			attrV2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v2));

+			attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(null));

+			attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234));

+		} catch (Exception e) {

+			fail("creating attributes e="+ e);

+		}

+		

+		FunctionDefinitionRegexpMatch<?> fd = (FunctionDefinitionRegexpMatch<?>) StdFunctions.FD_STRING_REGEXP_MATCH;

+

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_STRING_REGEXP_MATCH, fd.getId());

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+

+		

+		// match

+		arguments.clear();

+		arguments.add(attrV1);

+		arguments.add(attrV1);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertEquals(true, resValue);

+		

+		// no match

+		arguments.clear();

+		arguments.add(attrV1);

+		arguments.add(attrV2);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(false, resValue);

+		

+		// null regex

+		arguments.clear();

+		arguments.add(null);

+		arguments.add(attrV2);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-regexp-match Got null argument", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+	

+		

+		arguments.clear();

+		arguments.add(attrNull);

+		arguments.add(attrV2);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-regexp-match Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+			

+		// null object to match

+		arguments.clear();

+		arguments.add(attrV1);

+		arguments.add(null);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-regexp-match Got null argument", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		arguments.clear();

+		arguments.add(attrV1);

+		arguments.add(attrNull);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-regexp-match Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+

+		

+		// regex not string

+		arguments.clear();

+		arguments.add(attrInteger);

+		arguments.add(attrV2);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-regexp-match Expected data type 'string' saw 'integer'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+

+		// object to match not correct type

+		arguments.clear();

+		arguments.add(attrV1);

+		arguments.add(attrInteger);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-regexp-match Expected data type 'string' saw 'integer'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+	}

+	

+	@Test

+	public void testAnyURI() {

+		String regexp = new String("abc");

+		URI uri1 = null;

+		URI uri2 = null;

+		try {

+			uri1 = new URI("abc");

+			uri2 = new URI("def");

+		} catch (Exception e) {

+			fail("Unable to create URIs, e="+e);

+		}

+

+		

+		FunctionArgumentAttributeValue attrRegexp = null;

+		FunctionArgumentAttributeValue attrUri1 = null;

+		FunctionArgumentAttributeValue attrUri2 = null;

+		FunctionArgumentAttributeValue attrInteger = null;

+		try {

+			attrRegexp = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(regexp));

+			attrUri1 = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(uri1));

+			attrUri2 = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(uri2));

+			attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234));

+		} catch (Exception e) {

+			fail("creating attributes e="+ e);

+		}

+		

+		FunctionDefinitionRegexpMatch<?> fd = (FunctionDefinitionRegexpMatch<?>) StdFunctions.FD_ANYURI_REGEXP_MATCH;

+

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_ANYURI_REGEXP_MATCH, fd.getId());

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+

+		

+		// match

+		arguments.clear();

+		arguments.add(attrRegexp);

+		arguments.add(attrUri1);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertEquals(true, resValue);

+		

+		// no match

+		arguments.clear();

+		arguments.add(attrRegexp);

+		arguments.add(attrUri2);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(false, resValue);

+		

+		// object to match not correct type

+		arguments.clear();

+		arguments.add(attrRegexp);

+		arguments.add(attrInteger);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:anyURI-regexp-match Expected data type 'anyURI' saw 'integer'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+	}

+	

+	

+	@Test

+	public void testIpAddress() {

+		String regexp = new String(".*123.*");

+		IPAddress addr1 = null;

+		IPAddress addr2 = null;

+		try {

+			addr1 = IPAddress.newInstance("199.123.45.67");

+			addr2 = IPAddress.newInstance("12.34.67.87");

+		} catch (Exception e) {

+			fail("Unable to create IPAddresses, e="+e);

+		}

+

+		

+		FunctionArgumentAttributeValue attrRegexp = null;

+		FunctionArgumentAttributeValue attrAddr1 = null;

+		FunctionArgumentAttributeValue attrAddr2 = null;

+		FunctionArgumentAttributeValue attrInteger = null;

+		try {

+			attrRegexp = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(regexp));

+			attrAddr1 = new FunctionArgumentAttributeValue(DataTypes.DT_IPADDRESS.createAttributeValue(addr1));

+			attrAddr2 = new FunctionArgumentAttributeValue(DataTypes.DT_IPADDRESS.createAttributeValue(addr2));

+			attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234));

+		} catch (Exception e) {

+			fail("creating attributes e="+ e);

+		}

+		

+		FunctionDefinitionRegexpMatch<?> fd = (FunctionDefinitionRegexpMatch<?>) StdFunctions.FD_IPADDRESS_REGEXP_MATCH;

+

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_IPADDRESS_REGEXP_MATCH, fd.getId());

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+

+		

+		// match

+		arguments.clear();

+		arguments.add(attrRegexp);

+		arguments.add(attrAddr1);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertEquals(true, resValue);

+		

+		// no match

+		arguments.clear();

+		arguments.add(attrRegexp);

+		arguments.add(attrAddr2);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(false, resValue);

+		

+		// object to match not correct type

+		arguments.clear();

+		arguments.add(attrRegexp);

+		arguments.add(attrInteger);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:ipAddress-regexp-match Expected data type 'ipAddress' saw 'integer'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+	}

+	

+	

+	@Test

+	public void testDnsName() {

+		String regexp = new String("abc");

+		RFC2396DomainName addr1 = null;

+		RFC2396DomainName addr2 = null;

+		try {

+			addr1 = RFC2396DomainName.newInstance("abc");

+			addr2 = RFC2396DomainName.newInstance("def");

+		} catch (Exception e) {

+			fail("Unable to create DNSNames, e="+e);

+		}

+

+		

+		FunctionArgumentAttributeValue attrRegexp = null;

+		FunctionArgumentAttributeValue attrAddr1 = null;

+		FunctionArgumentAttributeValue attrAddr2 = null;

+		FunctionArgumentAttributeValue attrInteger = null;

+		try {

+			attrRegexp = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(regexp));

+			attrAddr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DNSNAME.createAttributeValue(addr1));

+			attrAddr2 = new FunctionArgumentAttributeValue(DataTypes.DT_DNSNAME.createAttributeValue(addr2));

+			attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234));

+		} catch (Exception e) {

+			fail("creating attributes e="+ e);

+		}

+		

+		FunctionDefinitionRegexpMatch<?> fd = (FunctionDefinitionRegexpMatch<?>) StdFunctions.FD_DNSNAME_REGEXP_MATCH;

+

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_DNSNAME_REGEXP_MATCH, fd.getId());

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+

+		

+		// match

+		arguments.clear();

+		arguments.add(attrRegexp);

+		arguments.add(attrAddr1);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertEquals(true, resValue);

+		

+		// no match

+		arguments.clear();

+		arguments.add(attrRegexp);

+		arguments.add(attrAddr2);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(false, resValue);

+		

+		// object to match not correct type

+		arguments.clear();

+		arguments.add(attrRegexp);

+		arguments.add(attrInteger);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dnsName-regexp-match Expected data type 'dnsName' saw 'integer'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+	}

+	

+	

+	@Test

+	public void testRfc822Name() {

+		String regexp = new String(".*abc.*");

+		RFC822Name addr1 = null;

+		RFC822Name addr2 = null;

+		try {

+			addr1 = RFC822Name.newInstance("abc@somewhere");

+			addr2 = RFC822Name.newInstance("def@somewhere");

+		} catch (Exception e) {

+			fail("Unable to create RFC822Names, e="+e);

+		}

+

+		

+		FunctionArgumentAttributeValue attrRegexp = null;

+		FunctionArgumentAttributeValue attrAddr1 = null;

+		FunctionArgumentAttributeValue attrAddr2 = null;

+		FunctionArgumentAttributeValue attrInteger = null;

+		try {

+			attrRegexp = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(regexp));

+			attrAddr1 = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue(addr1));

+			attrAddr2 = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue(addr2));

+			attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234));

+		} catch (Exception e) {

+			fail("creating attributes e="+ e);

+		}

+		

+		FunctionDefinitionRegexpMatch<?> fd = (FunctionDefinitionRegexpMatch<?>) StdFunctions.FD_RFC822NAME_REGEXP_MATCH;

+

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_RFC822NAME_REGEXP_MATCH, fd.getId());

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+

+		

+		// match

+		arguments.clear();

+		arguments.add(attrRegexp);

+		arguments.add(attrAddr1);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertEquals(true, resValue);

+		

+		// no match

+		arguments.clear();

+		arguments.add(attrRegexp);

+		arguments.add(attrAddr2);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(false, resValue);

+		

+		// object to match not correct type

+		arguments.clear();

+		arguments.add(attrRegexp);

+		arguments.add(attrInteger);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:rfc822Name-regexp-match Expected data type 'rfc822Name' saw 'integer'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+	}

+	

+	

+	@Test

+	public void testX500Name() {

+		String regexp = new String(".*Duke.*");

+		X500Principal addr1 = null;

+		X500Principal addr2 = null;

+		try {

+			addr1 = new X500Principal("CN=Duke, OU=JavaSoft, O=Sun Microsystems, C=US");

+			addr2 = new X500Principal("CN=Policy Engine, OU=Research, O=ATT, C=US");

+		} catch (Exception e) {

+			fail("Unable to create X500Name, e="+e);

+		}

+

+		

+		FunctionArgumentAttributeValue attrRegexp = null;

+		FunctionArgumentAttributeValue attrAddr1 = null;

+		FunctionArgumentAttributeValue attrAddr2 = null;

+		FunctionArgumentAttributeValue attrInteger = null;

+		try {

+			attrRegexp = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(regexp));

+			attrAddr1 = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(addr1));

+			attrAddr2 = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(addr2));

+			attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234));

+		} catch (Exception e) {

+			fail("creating attributes e="+ e);

+		}

+		

+		FunctionDefinitionRegexpMatch<?> fd = (FunctionDefinitionRegexpMatch<?>) StdFunctions.FD_X500NAME_REGEXP_MATCH;

+

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_X500NAME_REGEXP_MATCH, fd.getId());

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+

+		

+		// match

+		arguments.clear();

+		arguments.add(attrRegexp);

+		arguments.add(attrAddr1);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertEquals(true, resValue);

+		

+		// no match

+		arguments.clear();

+		arguments.add(attrRegexp);

+		arguments.add(attrAddr2);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(false, resValue);

+		

+		// object to match not correct type

+		arguments.clear();

+		arguments.add(attrRegexp);

+		arguments.add(attrInteger);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:x500Name-regexp-match Expected data type 'x500Name' saw 'integer'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+	}

+	

+	

+	

+

+}

diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSetTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSetTest.java
new file mode 100755
index 0000000..0331386
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSetTest.java
@@ -0,0 +1,1883 @@
+package com.att.research.xacmlatt.pdp.std.functions;

+

+import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.assertFalse;

+import static org.junit.Assert.assertNotNull;

+import static org.junit.Assert.assertTrue;

+import static org.junit.Assert.fail;

+

+import java.math.BigInteger;

+import java.util.ArrayList;

+import java.util.Iterator;

+import java.util.List;

+

+import org.junit.Test;

+

+import com.att.research.xacml.api.AttributeValue;

+import com.att.research.xacml.api.XACML3;

+import com.att.research.xacml.std.datatypes.DataTypes;

+import com.att.research.xacmlatt.pdp.policy.Bag;

+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgumentBag;

+import com.att.research.xacmlatt.pdp.std.StdFunctions;

+

+/**

+ * Test of PDP Functions (See XACML core spec section A.3)

+ * 

+ * TO RUN - use jUnit

+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test

+ * 

+ * @author glenngriffin

+ *

+ */

+public class FunctionDefinitionSetTest {

+

+

+	/*

+	 * variables useful in the following tests

+	 */

+	List<FunctionArgument> arguments = new ArrayList<FunctionArgument>();

+	

+	

+	

+	//

+	// INTERSECTION tests

+	//

+	

+	

+	@Test

+	public void testString_intersection() {

+		String a = "a";

+		String b = "b";

+		String c = "c";

+		String d = "d";

+		String e = "e";

+		String f = "f";

+		String g = "g";

+		String h = "h";

+		String j = "j";

+

+

+		Bag bagabcdefg = null;

+		Bag bagbdfhj = null;

+		Bag bagace = null;

+		Bag bagb = null;

+		Bag bagaaacccef = null;

+		Bag bagInt = null;

+		Bag bagStringInt = null;

+		Bag bagEmpty = null;

+		

+		FunctionArgumentAttributeValue attrBadType = null;

+		

+		try {

+			bagabcdefg = new Bag();

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g));

+			bagbdfhj = new Bag();

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j));

+			bagace = new Bag();

+				bagace.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagace.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagace.add(DataTypes.DT_STRING.createAttributeValue(e));

+			bagb = new Bag();

+				bagb.add(DataTypes.DT_STRING.createAttributeValue(b));

+			bagaaacccef = new Bag();

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(e));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(f));

+			bagInt = new Bag();

+				bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));

+			bagStringInt = new Bag();

+				bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));

+			bagEmpty = new Bag();

+				

+			attrBadType = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.1));

+		} catch (Exception ex) {

+			fail("creating attribute e="+ ex);

+		}

+		

+		// make into attributes

+		FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg);

+		FunctionArgumentBag attrBagbdfhj = new FunctionArgumentBag(bagbdfhj);

+		FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace);

+		FunctionArgumentBag attrBagb = new FunctionArgumentBag(bagb);

+		FunctionArgumentBag attrBagaaacccef = new FunctionArgumentBag(bagaaacccef);

+		FunctionArgumentBag attrBagInt = new FunctionArgumentBag(bagInt);

+		FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt);

+		FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty);

+

+		FunctionDefinitionSet<?,?> fd = (FunctionDefinitionSet<?,?>) StdFunctions.FD_STRING_INTERSECTION;

+

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_STRING_INTERSECTION, fd.getId());

+		assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertTrue(fd.returnsBag());

+		

+		// normal intersection (everything in both bags, no duplicates)

+		arguments.clear();

+		arguments.add(attrBagabcdefg);

+		arguments.add(attrBagabcdefg);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Bag bag = res.getBag();

+		assertNotNull(bag);

+		Iterator<AttributeValue<?>> it = bag.getAttributeValues();

+		assertEquals(7, bag.size());

+		AttributeValue<?> attrValueObject = it.next();

+		assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId());

+		assertEquals(a, attrValueObject.getValue() );

+		

+		// several but not all intersection

+		arguments.clear();

+		arguments.add(attrBagabcdefg);

+		arguments.add(attrBagbdfhj);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		it = bag.getAttributeValues();

+		assertEquals(3, bag.size());

+		attrValueObject = it.next();

+		assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId());

+		assertEquals(b, attrValueObject.getValue() );

+		

+		// no intersection

+		arguments.clear();

+		arguments.add(attrBagace);

+		arguments.add(attrBagbdfhj);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		it = bag.getAttributeValues();

+		assertEquals(0, bag.size());

+		

+		// one intersection

+		arguments.clear();

+		arguments.add(attrBagabcdefg);

+		arguments.add(attrBagb);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		it = bag.getAttributeValues();

+		assertEquals(1, bag.size());

+		attrValueObject = it.next();

+		assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId());

+		assertEquals(b, attrValueObject.getValue() );

+		

+		// bag one has duplicates that do not intersect

+		arguments.clear();

+		arguments.add(attrBagaaacccef);

+		arguments.add(attrBagbdfhj);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		it = bag.getAttributeValues();

+		assertEquals(1, bag.size());

+		attrValueObject = it.next();

+		assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId());

+		assertEquals(f, attrValueObject.getValue() );

+		

+		// bag one has duplicates that do intersect

+		arguments.clear();

+		arguments.add(attrBagaaacccef);

+		arguments.add(attrBagace);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		it = bag.getAttributeValues();

+		assertEquals(3, bag.size());

+		attrValueObject = it.next();

+		assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId());

+		assertEquals(a, attrValueObject.getValue() );

+		attrValueObject = it.next();

+		assertEquals(c, attrValueObject.getValue() );

+		attrValueObject = it.next();

+		assertEquals(e, attrValueObject.getValue() );

+		

+		// bag 2 has duplicates that do not intersect

+		arguments.clear();

+		arguments.add(attrBagbdfhj);

+		arguments.add(attrBagaaacccef);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		it = bag.getAttributeValues();

+		assertEquals(1, bag.size());

+		attrValueObject = it.next();

+		assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId());

+		assertEquals(f, attrValueObject.getValue() );

+		

+		// bag 2 has duplicates that intersect

+		arguments.clear();

+		arguments.add(attrBagace);

+		arguments.add(attrBagaaacccef);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		it = bag.getAttributeValues();

+		assertEquals(3, bag.size());

+		attrValueObject = it.next();

+		assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId());

+		assertEquals(a, attrValueObject.getValue() );

+		attrValueObject = it.next();

+		assertEquals(c, attrValueObject.getValue() );

+		attrValueObject = it.next();

+		assertEquals(e, attrValueObject.getValue() );

+		

+		// first bag is empty

+		arguments.clear();

+		arguments.add(attrBagEmpty);

+		arguments.add(attrBagaaacccef);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		it = bag.getAttributeValues();

+		assertEquals(0, bag.size());

+		

+		// second bag is empty

+		arguments.clear();

+		arguments.add(attrBagace);

+		arguments.add(attrBagEmpty);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		it = bag.getAttributeValues();

+		assertEquals(0, bag.size());

+		

+		// bags of different types

+		arguments.clear();

+		arguments.add(attrBagace);

+		arguments.add(attrBagStringInt);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		it = bag.getAttributeValues();

+		assertEquals(1, bag.size());

+		attrValueObject = it.next();

+		assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId());

+		assertEquals(a, attrValueObject.getValue() );

+

+		arguments.clear();

+		arguments.add(attrBagace);

+		arguments.add(attrBagInt);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		it = bag.getAttributeValues();

+		assertEquals(0, bag.size());

+		

+		// first not a bag

+		arguments.clear();

+		arguments.add(attrBadType);

+		arguments.add(attrBagabcdefg);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-intersection Expected a bag, saw a simple value", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// second not a bag

+		arguments.clear();

+		arguments.add(attrBagabcdefg);

+		arguments.add(attrBadType);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-intersection Expected a bag, saw a simple value", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		

+		// first null

+		arguments.clear();

+		arguments.add(null);

+		arguments.add(attrBagabcdefg);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-intersection Got null argument", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// second null

+		arguments.clear();

+		arguments.add(attrBagabcdefg);

+		arguments.add(null);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-intersection Got null argument", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// too few args

+		arguments.clear();

+		arguments.add(attrBagabcdefg);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-intersection Expected 2 arguments, got 1", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		arguments.clear();

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-intersection Expected 2 arguments, got 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// too many args

+		arguments.clear();

+		arguments.add(attrBagabcdefg);

+		arguments.add(attrBagabcdefg);

+		arguments.add(attrBagabcdefg);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-intersection Expected 2 arguments, got 3", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+	

+	}

+	

+

+	

+	@Test

+	public void testInteger_intersection() {

+		BigInteger a = new BigInteger("1");

+		BigInteger b = new BigInteger("2");

+		BigInteger c = new BigInteger("3");

+		BigInteger d = new BigInteger("4");

+		BigInteger e = new BigInteger("5");

+		BigInteger f = new BigInteger("6");

+		BigInteger g = new BigInteger("7");

+		BigInteger h = new BigInteger("8");

+		BigInteger j = new BigInteger("9");

+

+

+		Bag bagabcdefg = null;

+		Bag bagbdfhj = null;

+		Bag bagace = null;

+		Bag bagb = null;

+		Bag bagaaacccef = null;

+		Bag bagInt = null;

+		Bag bagStringInt = null;

+		Bag bagEmpty = null;

+		

+		FunctionArgumentAttributeValue attrBadType = null;

+		

+		try {

+			bagabcdefg = new Bag();

+				bagabcdefg.add(DataTypes.DT_INTEGER.createAttributeValue(a));

+				bagabcdefg.add(DataTypes.DT_INTEGER.createAttributeValue(b));

+				bagabcdefg.add(DataTypes.DT_INTEGER.createAttributeValue(c));

+				bagabcdefg.add(DataTypes.DT_INTEGER.createAttributeValue(d));

+				bagabcdefg.add(DataTypes.DT_INTEGER.createAttributeValue(e));

+				bagabcdefg.add(DataTypes.DT_INTEGER.createAttributeValue(f));

+				bagabcdefg.add(DataTypes.DT_INTEGER.createAttributeValue(g));

+			bagbdfhj = new Bag();

+				bagbdfhj.add(DataTypes.DT_INTEGER.createAttributeValue(b));

+				bagbdfhj.add(DataTypes.DT_INTEGER.createAttributeValue(d));

+				bagbdfhj.add(DataTypes.DT_INTEGER.createAttributeValue(f));

+				bagbdfhj.add(DataTypes.DT_INTEGER.createAttributeValue(h));

+				bagbdfhj.add(DataTypes.DT_INTEGER.createAttributeValue(j));

+			bagace = new Bag();

+				bagace.add(DataTypes.DT_INTEGER.createAttributeValue(a));

+				bagace.add(DataTypes.DT_INTEGER.createAttributeValue(c));

+				bagace.add(DataTypes.DT_INTEGER.createAttributeValue(e));

+			bagb = new Bag();

+				bagb.add(DataTypes.DT_INTEGER.createAttributeValue(b));

+			bagaaacccef = new Bag();

+				bagaaacccef.add(DataTypes.DT_INTEGER.createAttributeValue(a));

+				bagaaacccef.add(DataTypes.DT_INTEGER.createAttributeValue(a));

+				bagaaacccef.add(DataTypes.DT_INTEGER.createAttributeValue(a));

+				bagaaacccef.add(DataTypes.DT_INTEGER.createAttributeValue(c));

+				bagaaacccef.add(DataTypes.DT_INTEGER.createAttributeValue(c));

+				bagaaacccef.add(DataTypes.DT_INTEGER.createAttributeValue(c));

+				bagaaacccef.add(DataTypes.DT_INTEGER.createAttributeValue(e));

+				bagaaacccef.add(DataTypes.DT_INTEGER.createAttributeValue(f));

+			bagInt = new Bag();

+				bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));

+			bagStringInt = new Bag();

+				bagStringInt.add(DataTypes.DT_STRING.createAttributeValue("abc"));

+				bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(1));

+			bagEmpty = new Bag();

+				

+			attrBadType = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.1));

+		} catch (Exception ex) {

+			fail("creating attribute e="+ ex);

+		}

+		

+		// make into attributes

+		FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg);

+		FunctionArgumentBag attrBagbdfhj = new FunctionArgumentBag(bagbdfhj);

+		FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace);

+		FunctionArgumentBag attrBagb = new FunctionArgumentBag(bagb);

+		FunctionArgumentBag attrBagaaacccef = new FunctionArgumentBag(bagaaacccef);

+		FunctionArgumentBag attrBagInt = new FunctionArgumentBag(bagInt);

+		FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt);

+		FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty);

+

+		FunctionDefinitionSet<?,?> fd = (FunctionDefinitionSet<?,?>) StdFunctions.FD_INTEGER_INTERSECTION;

+

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_INTEGER_INTERSECTION, fd.getId());

+		assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertTrue(fd.returnsBag());

+		

+		// normal intersection (everything in both bags, no duplicates)

+		arguments.clear();

+		arguments.add(attrBagabcdefg);

+		arguments.add(attrBagabcdefg);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Bag bag = res.getBag();

+		assertNotNull(bag);

+		Iterator<AttributeValue<?>> it = bag.getAttributeValues();

+		assertEquals(7, bag.size());

+		AttributeValue<?> attrValueObject = it.next();

+		assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId());

+		assertEquals(a, attrValueObject.getValue() );

+		

+		// several but not all intersection

+		arguments.clear();

+		arguments.add(attrBagabcdefg);

+		arguments.add(attrBagbdfhj);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		it = bag.getAttributeValues();

+		assertEquals(3, bag.size());

+		attrValueObject = it.next();

+		assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId());

+		assertEquals(b, attrValueObject.getValue() );

+		

+		// no intersection

+		arguments.clear();

+		arguments.add(attrBagace);

+		arguments.add(attrBagbdfhj);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		it = bag.getAttributeValues();

+		assertEquals(0, bag.size());

+		

+		// one intersection

+		arguments.clear();

+		arguments.add(attrBagabcdefg);

+		arguments.add(attrBagb);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		it = bag.getAttributeValues();

+		assertEquals(1, bag.size());

+		attrValueObject = it.next();

+		assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId());

+		assertEquals(b, attrValueObject.getValue() );

+		

+		// bag one has duplicates that do not intersect

+		arguments.clear();

+		arguments.add(attrBagaaacccef);

+		arguments.add(attrBagbdfhj);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		it = bag.getAttributeValues();

+		assertEquals(1, bag.size());

+		attrValueObject = it.next();

+		assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId());

+		assertEquals(f, attrValueObject.getValue() );

+		

+		// bag one has duplicates that do intersect

+		arguments.clear();

+		arguments.add(attrBagaaacccef);

+		arguments.add(attrBagace);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		it = bag.getAttributeValues();

+		assertEquals(3, bag.size());

+		attrValueObject = it.next();

+		assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId());

+		assertEquals(a, attrValueObject.getValue() );

+		attrValueObject = it.next();

+		assertEquals(c, attrValueObject.getValue() );

+		attrValueObject = it.next();

+		assertEquals(e, attrValueObject.getValue() );

+		

+		// bag 2 has duplicates that do not intersect

+		arguments.clear();

+		arguments.add(attrBagbdfhj);

+		arguments.add(attrBagaaacccef);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		it = bag.getAttributeValues();

+		assertEquals(1, bag.size());

+		attrValueObject = it.next();

+		assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId());

+		assertEquals(f, attrValueObject.getValue() );

+		

+		// bag 2 has duplicates that intersect

+		arguments.clear();

+		arguments.add(attrBagace);

+		arguments.add(attrBagaaacccef);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		it = bag.getAttributeValues();

+		assertEquals(3, bag.size());

+		attrValueObject = it.next();

+		assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId());

+		assertEquals(a, attrValueObject.getValue() );

+		attrValueObject = it.next();

+		assertEquals(c, attrValueObject.getValue() );

+		attrValueObject = it.next();

+		assertEquals(e, attrValueObject.getValue() );

+		

+		// first bag is empty

+		arguments.clear();

+		arguments.add(attrBagEmpty);

+		arguments.add(attrBagaaacccef);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		it = bag.getAttributeValues();

+		assertEquals(0, bag.size());

+		

+		// second bag is empty

+		arguments.clear();

+		arguments.add(attrBagbdfhj);

+		arguments.add(attrBagEmpty);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		it = bag.getAttributeValues();

+		assertEquals(0, bag.size());

+		

+		// bags of different types

+		arguments.clear();

+		arguments.add(attrBagace);

+		arguments.add(attrBagStringInt);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		it = bag.getAttributeValues();

+		assertEquals(1, bag.size());

+		attrValueObject = it.next();

+		assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId());

+		assertEquals(a, attrValueObject.getValue() );

+

+		arguments.clear();

+		arguments.add(attrBagace);

+		arguments.add(attrBagInt);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		it = bag.getAttributeValues();

+		assertEquals(1, bag.size());

+		attrValueObject = it.next();

+		assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId());

+		assertEquals(a, attrValueObject.getValue() );

+

+		

+		// first not a bag

+		arguments.clear();

+		arguments.add(attrBadType);

+		arguments.add(attrBagabcdefg);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:integer-intersection Expected a bag, saw a simple value", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// second not a bag

+		arguments.clear();

+		arguments.add(attrBagabcdefg);

+		arguments.add(attrBadType);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:integer-intersection Expected a bag, saw a simple value", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		

+		// first null

+		arguments.clear();

+		arguments.add(null);

+		arguments.add(attrBagabcdefg);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:integer-intersection Got null argument", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// second null

+		arguments.clear();

+		arguments.add(attrBagabcdefg);

+		arguments.add(null);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:integer-intersection Got null argument", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// too few args

+		arguments.clear();

+		arguments.add(attrBagabcdefg);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:integer-intersection Expected 2 arguments, got 1", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		arguments.clear();

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:integer-intersection Expected 2 arguments, got 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// too many args

+		arguments.clear();

+		arguments.add(attrBagabcdefg);

+		arguments.add(attrBagabcdefg);

+		arguments.add(attrBagabcdefg);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:integer-intersection Expected 2 arguments, got 3", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+

+	}

+	

+	

+	

+	

+	

+	

+	

+	

+	

+	

+	

+	

+	

+	//

+	// AT_LEAST_ONE_MEMBER_OF tests

+	//

+	

+	@Test

+	public void testString_at_least_one_member_of() {

+		String a = "a";

+		String b = "b";

+		String c = "c";

+		String d = "d";

+		String e = "e";

+		String f = "f";

+		String g = "g";

+		String h = "h";

+		String j = "j";

+

+

+		Bag bagabcdefg = null;

+		Bag bagbdfhj = null;

+		Bag bagace = null;

+		Bag bagb = null;

+		Bag bagaaaccce = null;

+		Bag bagInt = null;

+		Bag bagStringInt = null;

+		Bag bagEmpty = null;

+		

+		FunctionArgumentAttributeValue attrBadType = null;

+		

+		try {

+			bagabcdefg = new Bag();

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g));

+			bagbdfhj = new Bag();

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j));

+			bagace = new Bag();

+				bagace.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagace.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagace.add(DataTypes.DT_STRING.createAttributeValue(e));

+			bagb = new Bag();

+				bagb.add(DataTypes.DT_STRING.createAttributeValue(b));

+			bagaaaccce = new Bag();

+				bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(e));

+			bagInt = new Bag();

+				bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));

+			bagStringInt = new Bag();

+				bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));

+			bagEmpty = new Bag();

+				

+			attrBadType = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.1));

+		} catch (Exception ex) {

+			fail("creating attribute e="+ ex);

+		}

+		

+		// make into attributes

+		FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg);

+		FunctionArgumentBag attrBagbdfhj = new FunctionArgumentBag(bagbdfhj);

+		FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace);

+		FunctionArgumentBag attrBagb = new FunctionArgumentBag(bagb);

+		FunctionArgumentBag attrBagaaaccce = new FunctionArgumentBag(bagaaaccce);

+		FunctionArgumentBag attrBagInt = new FunctionArgumentBag(bagInt);

+		FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt);

+		FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty);

+

+		FunctionDefinitionSet<?,?> fd = (FunctionDefinitionSet<?,?>) StdFunctions.FD_STRING_AT_LEAST_ONE_MEMBER_OF;

+

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_STRING_AT_LEAST_ONE_MEMBER_OF, fd.getId());

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		

+		// normal intersection (everything in both bags, no duplicates)

+		arguments.clear();

+		arguments.add(attrBagabcdefg);

+		arguments.add(attrBagabcdefg);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		

+		// several but not all intersection

+		arguments.clear();

+		arguments.add(attrBagabcdefg);

+		arguments.add(attrBagbdfhj);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// no intersection

+		arguments.clear();

+		arguments.add(attrBagace);

+		arguments.add(attrBagbdfhj);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// one intersection

+		arguments.clear();

+		arguments.add(attrBagabcdefg);

+		arguments.add(attrBagb);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// bag one has duplicates that do not intersect

+		arguments.clear();

+		arguments.add(attrBagaaaccce);

+		arguments.add(attrBagbdfhj);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// bag one has duplicates that do intersect

+		arguments.clear();

+		arguments.add(attrBagaaaccce);

+		arguments.add(attrBagace);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// bag 2 has duplicates that do not intersect

+		arguments.clear();

+		arguments.add(attrBagbdfhj);

+		arguments.add(attrBagaaaccce);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// bag 2 has duplicates that intersect

+		arguments.clear();

+		arguments.add(attrBagace);

+		arguments.add(attrBagaaaccce);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// 2 empty bags

+		arguments.clear();

+		arguments.add(attrBagEmpty);

+		arguments.add(attrBagEmpty);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// first non-empty, 2nd empty

+		arguments.clear();

+		arguments.add(attrBagaaaccce);

+		arguments.add(attrBagEmpty);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// first empty, 2nd not empty

+		arguments.clear();

+		arguments.add(attrBagEmpty);

+		arguments.add(attrBagaaaccce);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// bags of different types

+		arguments.clear();

+		arguments.add(attrBagace);

+		arguments.add(attrBagStringInt);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		arguments.clear();

+		arguments.add(attrBagace);

+		arguments.add(attrBagInt);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		arguments.clear();

+		arguments.add(attrBagace);

+		arguments.add(attrBagStringInt);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// first not a bag

+		arguments.clear();

+		arguments.add(attrBadType);

+		arguments.add(attrBagabcdefg);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-at-least-one-member-of Expected a bag, saw a simple value", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// second not a bag

+		arguments.clear();

+		arguments.add(attrBagabcdefg);

+		arguments.add(attrBadType);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-at-least-one-member-of Expected a bag, saw a simple value", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		

+		// first null

+		arguments.clear();

+		arguments.add(null);

+		arguments.add(attrBagabcdefg);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-at-least-one-member-of Got null argument", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// second null

+		arguments.clear();

+		arguments.add(attrBagabcdefg);

+		arguments.add(null);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-at-least-one-member-of Got null argument", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// too few args

+		arguments.clear();

+		arguments.add(attrBagabcdefg);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-at-least-one-member-of Expected 2 arguments, got 1", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		arguments.clear();

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-at-least-one-member-of Expected 2 arguments, got 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// too many args

+		arguments.clear();

+		arguments.add(attrBagabcdefg);

+		arguments.add(attrBagabcdefg);

+		arguments.add(attrBagabcdefg);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-at-least-one-member-of Expected 2 arguments, got 3", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+	

+	}

+	

+

+	

+	

+	

+	

+	

+	

+	

+	

+	

+	

+	

+	//

+	// UNION tests

+	//

+	

+	

+	

+	

+	

+	@Test

+	public void testString_union() {

+		String a = "a";

+		String b = "b";

+		String c = "c";

+		String d = "d";

+		String e = "e";

+		String f = "f";

+		String g = "g";

+		String h = "h";

+		String j = "j";

+

+

+		Bag bagabcdefg = null;

+		Bag bagbdfhj = null;

+		Bag bagace = null;

+		Bag bagaaacccef = null;

+		Bag bagInt = null;

+		Bag bagStringInt = null;

+		Bag bagEmpty = null;

+		

+		FunctionArgumentAttributeValue attrBadType = null;

+		

+		try {

+			bagabcdefg = new Bag();

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g));

+			bagbdfhj = new Bag();

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j));

+			bagace = new Bag();

+				bagace.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagace.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagace.add(DataTypes.DT_STRING.createAttributeValue(e));

+			bagaaacccef = new Bag();

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(e));

+				bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(f));

+			bagInt = new Bag();

+				bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));

+			bagStringInt = new Bag();

+				bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));

+			bagEmpty = new Bag();

+				

+			attrBadType = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.1));

+		} catch (Exception ex) {

+			fail("creating attribute e="+ ex);

+		}

+		

+		// make into attributes

+		FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg);

+		FunctionArgumentBag attrBagbdfhj = new FunctionArgumentBag(bagbdfhj);

+		FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace);

+		FunctionArgumentBag attrBagaaacccef = new FunctionArgumentBag(bagaaacccef);

+		FunctionArgumentBag attrBagInt = new FunctionArgumentBag(bagInt);

+		FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt);

+		FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty);

+

+		FunctionDefinitionSet<?,?> fd = (FunctionDefinitionSet<?,?>) StdFunctions.FD_STRING_UNION;

+

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_STRING_UNION, fd.getId());

+		assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertTrue(fd.returnsBag());

+		

+		// normal intersection (everything in both bags, no duplicates)

+		arguments.clear();

+		arguments.add(attrBagabcdefg);

+		arguments.add(attrBagabcdefg);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Bag bag = res.getBag();

+		assertNotNull(bag);

+		Iterator<AttributeValue<?>> it = bag.getAttributeValues();

+		assertEquals(7, bag.size());

+		AttributeValue<?> attrValueObject = it.next();

+		assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId());

+		assertEquals(a, attrValueObject.getValue() );

+		

+		// several but not all union

+		arguments.clear();

+		arguments.add(attrBagace);

+		arguments.add(attrBagbdfhj);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		it = bag.getAttributeValues();

+		assertEquals(8, bag.size());

+		attrValueObject = it.next();

+		assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId());

+		assertEquals(a, attrValueObject.getValue() );

+		

+		// bag one has duplicates that do not match first bag

+		arguments.clear();

+		arguments.add(attrBagaaacccef);

+		arguments.add(attrBagbdfhj);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		it = bag.getAttributeValues();

+		assertEquals(8, bag.size());

+		attrValueObject = it.next();

+		assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId());

+		assertEquals(a, attrValueObject.getValue() );

+		

+		// bag one has duplicates that do match first bag

+		arguments.clear();

+		arguments.add(attrBagaaacccef);

+		arguments.add(attrBagace);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		it = bag.getAttributeValues();

+		assertEquals(4, bag.size());

+		attrValueObject = it.next();

+		assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId());

+		assertEquals(a, attrValueObject.getValue() );

+		attrValueObject = it.next();

+		assertEquals(c, attrValueObject.getValue() );

+		attrValueObject = it.next();

+		assertEquals(e, attrValueObject.getValue() );

+		

+		// bag 2 has duplicates that do not match first bag

+		arguments.clear();

+		arguments.add(attrBagbdfhj);

+		arguments.add(attrBagaaacccef);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		it = bag.getAttributeValues();

+		assertEquals(8, bag.size());

+		attrValueObject = it.next();

+		assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId());

+		assertEquals(b, attrValueObject.getValue() );

+		

+		// bag 2 has duplicates that do match first bag

+		arguments.clear();

+		arguments.add(attrBagace);

+		arguments.add(attrBagaaacccef);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		it = bag.getAttributeValues();

+		assertEquals(4, bag.size());

+		attrValueObject = it.next();

+		assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId());

+		assertEquals(a, attrValueObject.getValue() );

+		attrValueObject = it.next();

+		assertEquals(c, attrValueObject.getValue() );

+		attrValueObject = it.next();

+		assertEquals(e, attrValueObject.getValue() );

+		

+		// two empty bags

+		arguments.clear();

+		arguments.add(attrBagEmpty);

+		arguments.add(attrBagEmpty);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		it = bag.getAttributeValues();

+		assertEquals(0, bag.size());

+		

+		// first bag empty, 2nd not empty

+		arguments.clear();

+		arguments.add(attrBagEmpty);

+		arguments.add(attrBagaaacccef);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		it = bag.getAttributeValues();

+		assertEquals(4, bag.size());

+		

+		// first bag not empty, 2nd empty

+		arguments.clear();

+		arguments.add(attrBagaaacccef);

+		arguments.add(attrBagEmpty);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		it = bag.getAttributeValues();

+		assertEquals(4, bag.size());

+		

+		// bags of different types

+		arguments.clear();

+		arguments.add(attrBagace);

+		arguments.add(attrBagStringInt);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		it = bag.getAttributeValues();

+		assertEquals(4, bag.size());

+		attrValueObject = it.next();

+		assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId());

+		assertEquals(a, attrValueObject.getValue() );

+

+		arguments.clear();

+		arguments.add(attrBagace);

+		arguments.add(attrBagInt);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		bag = res.getBag();

+		assertNotNull(bag);

+		it = bag.getAttributeValues();

+		assertEquals(4, bag.size());

+		attrValueObject = it.next();

+		assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId());

+		assertEquals(a, attrValueObject.getValue() );

+		

+		// first not a bag

+		arguments.clear();

+		arguments.add(attrBadType);

+		arguments.add(attrBagabcdefg);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-union Expected a bag, saw a simple value", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// second not a bag

+		arguments.clear();

+		arguments.add(attrBagabcdefg);

+		arguments.add(attrBadType);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-union Expected a bag, saw a simple value", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		

+		// first null

+		arguments.clear();

+		arguments.add(null);

+		arguments.add(attrBagabcdefg);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-union Got null argument", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// second null

+		arguments.clear();

+		arguments.add(attrBagabcdefg);

+		arguments.add(null);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-union Got null argument", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// too few args

+		arguments.clear();

+		arguments.add(attrBagabcdefg);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-union Expected 2 arguments, got 1", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		arguments.clear();

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-union Expected 2 arguments, got 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// too many args

+		arguments.clear();

+		arguments.add(attrBagabcdefg);

+		arguments.add(attrBagabcdefg);

+		arguments.add(attrBagabcdefg);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-union Expected 2 arguments, got 3", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+

+	}

+	

+	

+	

+	

+	

+	

+	

+	

+	

+	

+	//

+	// SUBSET tests

+	//

+	

+	@Test

+	public void testString_subset() {

+		String a = "a";

+		String b = "b";

+		String c = "c";

+		String d = "d";

+		String e = "e";

+		String f = "f";

+		String g = "g";

+		String h = "h";

+		String j = "j";

+

+

+		Bag bagabcdefg = null;

+		Bag bagbdfhj = null;

+		Bag bagace = null;

+		Bag bagb = null;

+		Bag bagaaaccce = null;

+		Bag bagInt = null;

+		Bag bagStringInt = null;

+		Bag bagEmpty = null;

+		

+		FunctionArgumentAttributeValue attrBadType = null;

+		

+		try {

+			bagabcdefg = new Bag();

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g));

+			bagbdfhj = new Bag();

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j));

+			bagace = new Bag();

+				bagace.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagace.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagace.add(DataTypes.DT_STRING.createAttributeValue(e));

+			bagb = new Bag();

+				bagb.add(DataTypes.DT_STRING.createAttributeValue(b));

+			bagaaaccce = new Bag();

+				bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(e));

+			bagInt = new Bag();

+				bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));

+			bagStringInt = new Bag();

+				bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(b));

+				bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));

+			bagEmpty = new Bag();

+				

+			attrBadType = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.1));

+		} catch (Exception ex) {

+			fail("creating attribute e="+ ex);

+		}

+		

+		// make into attributes

+		FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg);

+		FunctionArgumentBag attrBagbdfhj = new FunctionArgumentBag(bagbdfhj);

+		FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace);

+		FunctionArgumentBag attrBagb = new FunctionArgumentBag(bagb);

+		FunctionArgumentBag attrBagaaaccce = new FunctionArgumentBag(bagaaaccce);

+		FunctionArgumentBag attrBagInt = new FunctionArgumentBag(bagInt);

+		FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt);

+		FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty);

+

+		FunctionDefinitionSet<?,?> fd = (FunctionDefinitionSet<?,?>) StdFunctions.FD_STRING_SUBSET;

+

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_STRING_SUBSET, fd.getId());

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		

+		// normal intersection (everything in both bags, no duplicates)

+		arguments.clear();

+		arguments.add(attrBagabcdefg);

+		arguments.add(attrBagabcdefg);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		

+		// not subset

+		arguments.clear();

+		arguments.add(attrBagabcdefg);

+		arguments.add(attrBagbdfhj);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// subset

+		arguments.clear();

+		arguments.add(attrBagace);

+		arguments.add(attrBagabcdefg);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		

+		// no intersection

+		arguments.clear();

+		arguments.add(attrBagace);

+		arguments.add(attrBagbdfhj);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// Not

+		arguments.clear();

+		arguments.add(attrBagabcdefg);

+		arguments.add(attrBagb);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// Subset

+		arguments.clear();

+		arguments.add(attrBagb);

+		arguments.add(attrBagabcdefg);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// bag one has duplicates that do not intersect

+		arguments.clear();

+		arguments.add(attrBagaaaccce);

+		arguments.add(attrBagbdfhj);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// bag one has duplicates that do intersect

+		arguments.clear();

+		arguments.add(attrBagaaaccce);

+		arguments.add(attrBagace);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// bag 2 has duplicates that do not intersect

+		arguments.clear();

+		arguments.add(attrBagbdfhj);

+		arguments.add(attrBagaaaccce);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// bag 2 has duplicates that intersect

+		arguments.clear();

+		arguments.add(attrBagace);

+		arguments.add(attrBagaaaccce);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// 2 empty bags

+		arguments.clear();

+		arguments.add(attrBagEmpty);

+		arguments.add(attrBagEmpty);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// first non-empty, 2nd empty

+		arguments.clear();

+		arguments.add(attrBagaaaccce);

+		arguments.add(attrBagEmpty);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// first empty, 2nd not empty

+		arguments.clear();

+		arguments.add(attrBagEmpty);

+		arguments.add(attrBagaaaccce);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// bags of different types

+		arguments.clear();

+		arguments.add(attrBagace);

+		arguments.add(attrBagStringInt);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		arguments.clear();

+		arguments.add(attrBagb);

+		arguments.add(attrBagStringInt);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		arguments.clear();

+		arguments.add(attrBagace);

+		arguments.add(attrBagInt);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// first not a bag

+		arguments.clear();

+		arguments.add(attrBadType);

+		arguments.add(attrBagabcdefg);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-subset Expected a bag, saw a simple value", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// second not a bag

+		arguments.clear();

+		arguments.add(attrBagabcdefg);

+		arguments.add(attrBadType);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-subset Expected a bag, saw a simple value", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		

+		// first null

+		arguments.clear();

+		arguments.add(null);

+		arguments.add(attrBagabcdefg);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-subset Got null argument", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// second null

+		arguments.clear();

+		arguments.add(attrBagabcdefg);

+		arguments.add(null);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-subset Got null argument", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// too few args

+		arguments.clear();

+		arguments.add(attrBagabcdefg);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-subset Expected 2 arguments, got 1", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		arguments.clear();

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-subset Expected 2 arguments, got 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// too many args

+		arguments.clear();

+		arguments.add(attrBagabcdefg);

+		arguments.add(attrBagabcdefg);

+		arguments.add(attrBagabcdefg);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-subset Expected 2 arguments, got 3", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+	

+	}

+	

+

+	

+	

+	

+	

+	

+	

+	

+	

+	

+	//

+	// SET_EQUALS tests

+	//

+	

+	@Test

+	public void testString_set_equals() {

+		String a = "a";

+		String b = "b";

+		String c = "c";

+		String d = "d";

+		String e = "e";

+		String f = "f";

+		String g = "g";

+		String h = "h";

+		String j = "j";

+

+

+		Bag bagabcdefg = null;

+		Bag bagbdfhj = null;

+		Bag bagace = null;

+		Bag bagb = null;

+		Bag bagaaaccce = null;

+		Bag bagInt = null;

+		Bag bagStringInt = null;

+		Bag bagEmpty = null;

+		

+		FunctionArgumentAttributeValue attrBadType = null;

+		

+		try {

+			bagabcdefg = new Bag();

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f));

+				bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g));

+			bagbdfhj = new Bag();

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h));

+				bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j));

+			bagace = new Bag();

+				bagace.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagace.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagace.add(DataTypes.DT_STRING.createAttributeValue(e));

+			bagb = new Bag();

+				bagb.add(DataTypes.DT_STRING.createAttributeValue(b));

+			bagaaaccce = new Bag();

+				bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(c));

+				bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(e));

+			bagInt = new Bag();

+				bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));

+			bagStringInt = new Bag();

+				bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a));

+				bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));

+			bagEmpty = new Bag();

+				

+			attrBadType = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.1));

+		} catch (Exception ex) {

+			fail("creating attribute e="+ ex);

+		}

+		

+		// make into attributes

+		FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg);

+		FunctionArgumentBag attrBagbdfhj = new FunctionArgumentBag(bagbdfhj);

+		FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace);

+		FunctionArgumentBag attrBagb = new FunctionArgumentBag(bagb);

+		FunctionArgumentBag attrBagaaaccce = new FunctionArgumentBag(bagaaaccce);

+		FunctionArgumentBag attrBagInt = new FunctionArgumentBag(bagInt);

+		FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt);

+		FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty);

+

+		FunctionDefinitionSet<?,?> fd = (FunctionDefinitionSet<?,?>) StdFunctions.FD_STRING_SET_EQUALS;

+

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_STRING_SET_EQUALS, fd.getId());

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		

+		// normal intersection (everything in both bags, no duplicates)

+		arguments.clear();

+		arguments.add(attrBagabcdefg);

+		arguments.add(attrBagabcdefg);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		

+		// several but not all intersection

+		arguments.clear();

+		arguments.add(attrBagabcdefg);

+		arguments.add(attrBagbdfhj);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// no intersection

+		arguments.clear();

+		arguments.add(attrBagace);

+		arguments.add(attrBagbdfhj);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// one intersection

+		arguments.clear();

+		arguments.add(attrBagabcdefg);

+		arguments.add(attrBagb);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// bag one has duplicates that do not intersect

+		arguments.clear();

+		arguments.add(attrBagaaaccce);

+		arguments.add(attrBagbdfhj);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// bag one has duplicates that do intersect

+		arguments.clear();

+		arguments.add(attrBagaaaccce);

+		arguments.add(attrBagace);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// bag 2 has duplicates that do not intersect

+		arguments.clear();

+		arguments.add(attrBagbdfhj);

+		arguments.add(attrBagaaaccce);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// bag 2 has duplicates that intersect

+		arguments.clear();

+		arguments.add(attrBagace);

+		arguments.add(attrBagaaaccce);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// 2 empty bags

+		arguments.clear();

+		arguments.add(attrBagEmpty);

+		arguments.add(attrBagEmpty);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// first non-empty, 2nd empty

+		arguments.clear();

+		arguments.add(attrBagaaaccce);

+		arguments.add(attrBagEmpty);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// first empty, 2nd not empty

+		arguments.clear();

+		arguments.add(attrBagEmpty);

+		arguments.add(attrBagaaaccce);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// bags of different types

+		arguments.clear();

+		arguments.add(attrBagace);

+		arguments.add(attrBagStringInt);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+

+		arguments.clear();

+		arguments.add(attrBagace);

+		arguments.add(attrBagInt);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// first not a bag

+		arguments.clear();

+		arguments.add(attrBadType);

+		arguments.add(attrBagabcdefg);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-set-equals Expected a bag, saw a simple value", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// second not a bag

+		arguments.clear();

+		arguments.add(attrBagabcdefg);

+		arguments.add(attrBadType);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-set-equals Expected a bag, saw a simple value", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		

+		// first null

+		arguments.clear();

+		arguments.add(null);

+		arguments.add(attrBagabcdefg);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-set-equals Got null argument", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// second null

+		arguments.clear();

+		arguments.add(attrBagabcdefg);

+		arguments.add(null);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-set-equals Got null argument", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// too few args

+		arguments.clear();

+		arguments.add(attrBagabcdefg);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-set-equals Expected 2 arguments, got 1", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		arguments.clear();

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-set-equals Expected 2 arguments, got 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// too many args

+		arguments.clear();

+		arguments.add(attrBagabcdefg);

+		arguments.add(attrBagabcdefg);

+		arguments.add(attrBagabcdefg);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-set-equals Expected 2 arguments, got 3", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+	

+	}

+	

+	

+	

+	

+	

+	

+	

+	

+	

+	

+	//

+	//

+	//  REST OF DATA TYPES OMITTED 

+	//	because they "should" all work the same

+	//

+	//

+	

+	

+	

+

+}

diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSpecialMatchTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSpecialMatchTest.java
new file mode 100755
index 0000000..f5c786f
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSpecialMatchTest.java
@@ -0,0 +1,467 @@
+package com.att.research.xacmlatt.pdp.std.functions;

+

+import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.assertFalse;

+import static org.junit.Assert.assertTrue;

+import static org.junit.Assert.fail;

+

+import java.util.ArrayList;

+import java.util.List;

+

+import javax.security.auth.x500.X500Principal;

+

+import org.junit.Test;

+

+import com.att.research.xacml.api.XACML3;

+import com.att.research.xacml.std.datatypes.DataTypes;

+import com.att.research.xacmlatt.pdp.policy.Bag;

+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgumentBag;

+import com.att.research.xacmlatt.pdp.std.StdFunctions;

+

+/**

+ * Test of PDP Functions (See XACML core spec section A.3)

+ * 

+ * TO RUN - use jUnit

+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test

+ * 

+ * @author glenngriffin

+ *

+ */

+public class FunctionDefinitionSpecialMatchTest {

+	

+	/*

+	 * variables useful in the following tests

+	 */

+	List<FunctionArgument> arguments = new ArrayList<FunctionArgument>();

+	

+	@Test

+	public void testX500NameMatch() {

+		// assume that the contents of the name components are not significant and we can treat them as simple blocks of "<name>=<value>"

+		String A = "cn=Some person";

+		String B = "O=Medico Corp";

+		String C = "C=US";

+		String D = "DNQUALIFIER=d string";

+		String E = "SURNAME=some name";

+		String F = "INITIALS=inits";

+		

+		

+		X500Principal abc = new X500Principal(A + "," + B + "," + C);

+		X500Principal dabc = new X500Principal(D + "," + A + "," + B + "," + C);

+		X500Principal abcd = new X500Principal(A + "," + B + "," + C + "," + D);

+		X500Principal adbc = new X500Principal(A + "," + D + "," + B + "," + C);

+		X500Principal dcab = new X500Principal(D + "," + C + "," +  A + "," + B) ;

+		X500Principal def = new X500Principal(D + "," + E + "," +  F) ;

+

+		

+		FunctionArgumentAttributeValue attrABC = null;

+		FunctionArgumentAttributeValue attrDABC = null;

+		FunctionArgumentAttributeValue attrABCD = null;

+		FunctionArgumentAttributeValue attrADBC = null;

+		FunctionArgumentAttributeValue attrDCAB = null;

+		FunctionArgumentAttributeValue attrDEF = null;

+		

+		FunctionArgumentAttributeValue attrBad = null;

+		FunctionArgumentBag attrBag = new FunctionArgumentBag(new Bag());

+

+		

+		try {

+			attrABC = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(abc));

+			attrDABC = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(dabc));

+			attrABCD = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(abcd));

+			attrADBC = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(adbc));

+			attrDCAB = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(dcab));

+			attrDEF = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(def));

+

+			attrBad = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+		

+		FunctionDefinitionX500NameMatch fd = (FunctionDefinitionX500NameMatch) StdFunctions.FD_X500NAME_MATCH;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_X500NAME_MATCH, fd.getId());

+		assertEquals(DataTypes.DT_X500NAME.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		

+		// test normal, first exact match for second

+		arguments.clear();

+		arguments.add(attrABC);

+		arguments.add(attrABC);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		// test first is end of second

+		arguments.clear();

+		arguments.add(attrABC);

+		arguments.add(attrDABC);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		// first exact match for sub-section but not end of second

+		arguments.clear();

+		arguments.add(attrABC);

+		arguments.add(attrABCD);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// components of first match components in second but not contiguous

+		arguments.clear();

+		arguments.add(attrABC);

+		arguments.add(attrADBC);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// components of first match components in second but not in order

+		arguments.clear();

+		arguments.add(attrABC);

+		arguments.add(attrDCAB);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// first does not match second at all

+		arguments.clear();

+		arguments.add(attrABC);

+		arguments.add(attrDEF);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// first arg larger than 2nd arg

+		arguments.clear();

+		arguments.add(attrABCD);

+		arguments.add(attrABC);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// bad arg types

+		arguments.clear();

+		arguments.add(attrABC);

+		arguments.add(attrBad);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:x500Name-match Expected data type 'x500Name' saw 'integer' at arg index 1", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// too many args

+		arguments.clear();

+		arguments.add(attrABC);

+		arguments.add(attrABC);

+		arguments.add(attrABC);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:x500Name-match Expected 2 arguments, got 3", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// too few args

+		arguments.clear();

+		arguments.add(attrABC);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:x500Name-match Expected 2 arguments, got 1", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		arguments.clear();

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:x500Name-match Expected 2 arguments, got 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// one arg is bag

+		arguments.clear();

+		arguments.add(attrABC);

+		arguments.add(attrBag);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:x500Name-match Expected a simple value, saw a bag at arg index 1", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// null arg

+		arguments.clear();

+		arguments.add(null);

+		arguments.add(attrBag);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:x500Name-match Got null argument at arg index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+	}

+

+	

+	@Test

+	public void testRfc822NameMatch() {

+

+		

+		

+		

+		FunctionArgumentAttributeValue attrStringabcxyz = null;

+		FunctionArgumentAttributeValue attrStringABCxyz = null;

+		FunctionArgumentAttributeValue attrStringabcXYZ = null;

+		FunctionArgumentAttributeValue attrStringcx = null;

+		FunctionArgumentAttributeValue attrStringwholedomainpart = null;

+		FunctionArgumentAttributeValue attrStringWholeDomainPart = null;

+		FunctionArgumentAttributeValue attrStringWholeDomain = null;

+		FunctionArgumentAttributeValue attrStringdomainpart = null;

+		FunctionArgumentAttributeValue attrStringDomainPart = null;

+		FunctionArgumentAttributeValue attrStringdotWholeDomain = null;

+		FunctionArgumentAttributeValue attrStringdomain = null;

+		

+		FunctionArgumentAttributeValue attrStringNoMatch = null;

+		FunctionArgumentAttributeValue attrStringMultipleAt = null;

+		FunctionArgumentAttributeValue attrStringMissingLocal = null;

+		FunctionArgumentAttributeValue attrStringMissingDomain = null;

+

+		

+		FunctionArgumentAttributeValue attrRfcabcxyz = null;

+		FunctionArgumentAttributeValue attrRfcwholedomainpart = null;

+		FunctionArgumentAttributeValue attrRfcWholeDomainPart = null;

+

+		FunctionArgumentBag attrBag = new FunctionArgumentBag(new Bag());

+

+		try {

+			attrStringabcxyz = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("abc@xyz"));

+			attrStringABCxyz = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("ABC@xyz"));

+			attrStringabcXYZ = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("abc@XYZ"));

+			attrStringcx = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("c@x"));

+			attrStringwholedomainpart = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("whole.domain.part"));

+			attrStringWholeDomainPart = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("Whole.Domain.Part"));

+			attrStringWholeDomain = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("Whole.Domain"));

+			attrStringdomainpart = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(".domain.part"));

+			attrStringDomainPart = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(".Domain.Part"));

+			attrStringdotWholeDomain = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(".Whole.Domain"));

+			attrStringdomain = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(".domain."));

+			

+			attrStringNoMatch = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("no match to any legal name"));

+			attrStringMultipleAt = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("name@with@multipleAts"));

+			attrStringMissingLocal = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("@multipleAts"));

+			attrStringMissingDomain = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("localpart@"));

+		

+			attrRfcabcxyz = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue("abc@xyz"));

+			attrRfcwholedomainpart = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue("abc@whole.domain.part"));

+			attrRfcWholeDomainPart = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue("abc@Whole.Domain.Part"));

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+		

+		FunctionDefinitionRFC822NameMatch fd = (FunctionDefinitionRFC822NameMatch) StdFunctions.FD_RFC822NAME_MATCH;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_RFC822NAME_MATCH, fd.getId());

+		assertEquals(DataTypes.DT_RFC822NAME.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		

+		

+		// string identical to name - exact match on whole search term

+		arguments.clear();

+		arguments.add(attrStringabcxyz);

+		arguments.add(attrRfcabcxyz);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.getStatus().isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// no match local case different

+		arguments.clear();

+		arguments.add(attrStringABCxyz);

+		arguments.add(attrRfcabcxyz);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.getStatus().isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// match domain case different

+		arguments.clear();

+		arguments.add(attrStringabcXYZ);

+		arguments.add(attrRfcabcxyz);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.getStatus().isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+

+		// partial local + partial domain

+		arguments.clear();

+		arguments.add(attrStringcx);

+		arguments.add(attrRfcabcxyz);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.getStatus().isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// whole domain

+		arguments.clear();

+		arguments.add(attrStringwholedomainpart);

+		arguments.add(attrRfcwholedomainpart);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.getStatus().isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// whole domain different case

+		arguments.clear();

+		arguments.add(attrStringWholeDomainPart);

+		arguments.add(attrRfcwholedomainpart);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.getStatus().isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		arguments.clear();

+		arguments.add(attrStringwholedomainpart);

+		arguments.add(attrRfcWholeDomainPart);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.getStatus().isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// whole domain fail

+		arguments.clear();

+		arguments.add(attrStringWholeDomain);

+		arguments.add(attrRfcWholeDomainPart);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.getStatus().isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// partial domain match

+		arguments.clear();

+		arguments.add(attrStringDomainPart);

+		arguments.add(attrRfcWholeDomainPart);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.getStatus().isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// partial domain different case

+		arguments.clear();

+		arguments.add(attrStringdomainpart);

+		arguments.add(attrRfcWholeDomainPart);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.getStatus().isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// partial domain fail

+		arguments.clear();

+		arguments.add(attrStringdotWholeDomain);

+		arguments.add(attrRfcWholeDomainPart);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.getStatus().isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		arguments.clear();

+		arguments.add(attrStringdomain);

+		arguments.add(attrRfcWholeDomainPart);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.getStatus().isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// search term contains more than 1 @

+		arguments.clear();

+		arguments.add(attrStringMultipleAt);

+		arguments.add(attrRfcabcxyz);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:rfc822Name-match String contained more than 1 '@' in 'name@with@multipleAts'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// search term missing local part

+		arguments.clear();

+		arguments.add(attrStringMissingLocal);

+		arguments.add(attrRfcabcxyz);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:rfc822Name-match String missing local part in '@multipleAts'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// search term missing domain part

+		arguments.clear();

+		arguments.add(attrStringMissingDomain);

+		arguments.add(attrRfcabcxyz);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:rfc822Name-match String missing domain part in 'localpart@'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// bad arg types

+		arguments.clear();

+		arguments.add(attrRfcabcxyz);

+		arguments.add(attrStringNoMatch);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:rfc822Name-match Expected data type 'string' saw 'rfc822Name' at arg index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// too many args

+		arguments.clear();

+		arguments.add(attrStringNoMatch);

+		arguments.add(attrStringNoMatch);

+		arguments.add(attrStringNoMatch);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:rfc822Name-match Expected 2 arguments, got 3", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// too few args

+		arguments.clear();

+		arguments.add(attrStringNoMatch);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:rfc822Name-match Expected 2 arguments, got 1", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		arguments.clear();

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:rfc822Name-match Expected 2 arguments, got 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// one arg is bag

+		arguments.clear();

+		arguments.add(attrStringNoMatch);

+		arguments.add(attrBag);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:rfc822Name-match Expected a simple value, saw a bag at arg index 1", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// null arg

+		arguments.clear();

+		arguments.add(null);

+		arguments.add(attrStringNoMatch);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:rfc822Name-match Got null argument at arg index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		

+		

+	}

+	

+}

diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringConversionTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringConversionTest.java
new file mode 100755
index 0000000..8800097
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringConversionTest.java
@@ -0,0 +1,2484 @@
+package com.att.research.xacmlatt.pdp.std.functions;

+

+import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.assertFalse;

+import static org.junit.Assert.assertNotEquals;

+import static org.junit.Assert.assertTrue;

+import static org.junit.Assert.fail;

+

+import java.math.BigInteger;

+import java.net.URI;

+import java.net.URISyntaxException;

+import java.text.ParseException;

+import java.util.ArrayList;

+import java.util.List;

+

+import javax.security.auth.x500.X500Principal;

+

+import org.junit.Test;

+

+import com.att.research.xacml.api.XACML3;

+import com.att.research.xacml.std.datatypes.DataTypes;

+import com.att.research.xacml.std.datatypes.IPAddress;

+import com.att.research.xacml.std.datatypes.IPv4Address;

+import com.att.research.xacml.std.datatypes.IPv6Address;

+import com.att.research.xacml.std.datatypes.ISO8601Date;

+import com.att.research.xacml.std.datatypes.ISO8601DateTime;

+import com.att.research.xacml.std.datatypes.ISO8601Time;

+import com.att.research.xacml.std.datatypes.ISO8601TimeZone;

+import com.att.research.xacml.std.datatypes.PortRange;

+import com.att.research.xacml.std.datatypes.RFC2396DomainName;

+import com.att.research.xacml.std.datatypes.RFC822Name;

+import com.att.research.xacml.std.datatypes.XPathDayTimeDuration;

+import com.att.research.xacml.std.datatypes.XPathYearMonthDuration;

+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue;

+import com.att.research.xacmlatt.pdp.std.StdFunctions;

+

+/**

+ * Tests for converting objects to/from Strings.

+ * 

+ * TO RUN - use jUnit

+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test

+ * 

+ * @author glenngriffin

+ *

+ */

+public class FunctionDefinitionStringConversionTest {

+	

+	/*

+	 * variables useful in the following tests

+	 */

+	List<FunctionArgument> arguments = new ArrayList<FunctionArgument>();

+	

+	

+	/**

+	 * Boolean

+	 */

+	@Test

+	public void testBoolean_from_string() {

+		FunctionArgumentAttributeValue attrString1 = null;

+		FunctionArgumentAttributeValue attrStringBadValue = null;

+		FunctionArgumentAttributeValue attrStringBadType = null;

+		try {

+			attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("true"));

+			attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value"));

+			attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));

+

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+		

+		FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_BOOLEAN_FROM_STRING;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_BOOLEAN_FROM_STRING, fd.getId());

+		assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(1), fd.getNumArgs());

+		

+		// test normal

+		arguments.clear();

+		arguments.add(attrString1);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertEquals(new Boolean(true), resValue);

+		

+		// bad value

+		arguments.clear();

+		arguments.add(attrStringBadValue);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:boolean-from-string Cannot convert from \"java.lang.String\" with value \"not valid obj value\" to boolean", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// bad arg type

+		arguments.clear();

+		arguments.add(attrStringBadType);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:boolean-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+	}

+

+	@Test

+	public void testString_from_boolean() {

+		FunctionArgumentAttributeValue attrObj1 = null;

+		FunctionArgumentAttributeValue attrStringBadType = null;

+		String objValueString = "false";

+		try {

+			attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_BOOLEAN.createAttributeValue(objValueString));

+			attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));

+

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+		

+		FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_BOOLEAN;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_STRING_FROM_BOOLEAN, fd.getId());

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(1), fd.getNumArgs());

+		

+		// test normal

+		arguments.clear();

+		arguments.add(attrObj1);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(objValueString, res.getValue().getValue());

+		

+		// bad arg type

+		arguments.clear();

+		arguments.add(attrStringBadType);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-from-boolean Expected data type 'boolean' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+	}

+	

+	

+	

+	

+	/**

+	 * Integer

+	 */

+	@Test

+	public void testInteger_from_string() {

+		FunctionArgumentAttributeValue attrString1 = null;

+		FunctionArgumentAttributeValue attrStringBadValue = null;

+		FunctionArgumentAttributeValue attrStringBadType = null;

+		try {

+			attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123456"));

+			attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value"));

+			attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));

+

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+		

+		FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_INTEGER_FROM_STRING;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_INTEGER_FROM_STRING, fd.getId());

+		assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(1), fd.getNumArgs());

+		

+		// test normal

+		arguments.clear();

+		arguments.add(attrString1);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		BigInteger resValue = (BigInteger)res.getValue().getValue();

+		assertEquals(new BigInteger("123456"), resValue);

+		

+		// bad value

+		arguments.clear();

+		arguments.add(attrStringBadValue);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:integer-from-string For input string: \"n\"", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// bad arg type

+		arguments.clear();

+		arguments.add(attrStringBadType);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:integer-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+	}

+

+	@Test

+	public void testString_from_integer() {

+		FunctionArgumentAttributeValue attrObj1 = null;

+		FunctionArgumentAttributeValue attrStringBadType = null;

+		String objValueString = "1234";

+		try {

+			attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(objValueString));

+			attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(123));

+

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+		

+		FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_INTEGER;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_STRING_FROM_INTEGER, fd.getId());

+		assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(1), fd.getNumArgs());

+		

+		// test normal

+		arguments.clear();

+		arguments.add(attrObj1);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(objValueString, res.getValue().getValue());

+		

+		// bad arg type

+		arguments.clear();

+		arguments.add(attrStringBadType);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-from-integer Expected data type 'integer' saw 'double' at arg index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+	}

+	

+	

+	

+	/**

+	 * Double

+	 */

+	@Test

+	public void testDouble_from_string() {

+		FunctionArgumentAttributeValue attrString1 = null;

+		FunctionArgumentAttributeValue attrStringBadValue = null;

+		FunctionArgumentAttributeValue attrStringBadType = null;

+		try {

+			attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("5.432"));

+			attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value"));

+			attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));

+

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+		

+		FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_DOUBLE_FROM_STRING;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_DOUBLE_FROM_STRING, fd.getId());

+		assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(1), fd.getNumArgs());

+		

+		// test normal

+		arguments.clear();

+		arguments.add(attrString1);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Double resValue = (Double)res.getValue().getValue();

+		assertEquals(new Double(5.432), resValue);

+		

+		// bad value

+		arguments.clear();

+		arguments.add(attrStringBadValue);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:double-from-string For input string: \"not valid obj value\"", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// bad arg type

+		arguments.clear();

+		arguments.add(attrStringBadType);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:double-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+	}

+

+	@Test

+	public void testString_from_double() {

+		FunctionArgumentAttributeValue attrObj1 = null;

+		FunctionArgumentAttributeValue attrObjBig = null;

+		FunctionArgumentAttributeValue attrStringBadType = null;

+		String objValueString = "5.432";

+		String objValueStringBig = "55555555555555555555.123455";

+		try {

+			attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(objValueString));

+			attrObjBig = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(objValueStringBig));

+			attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));

+

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+		

+		FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_DOUBLE;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_STRING_FROM_DOUBLE, fd.getId());

+		assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(1), fd.getNumArgs());

+		

+		// test normal

+		arguments.clear();

+		arguments.add(attrObj1);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(objValueString, res.getValue().getValue());

+		

+		arguments.clear();

+		arguments.add(attrObjBig);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals("5.555555555555556E19", res.getValue().getValue());

+		

+		

+		// bad arg type

+		arguments.clear();

+		arguments.add(attrStringBadType);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-from-double Expected data type 'double' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+	}

+	

+	

+	

+	

+	

+	/**

+	 * Time

+	 */

+	@Test

+	public void testTime_from_string() {

+		FunctionArgumentAttributeValue attrString1 = null;

+		FunctionArgumentAttributeValue attrString2 = null;

+		FunctionArgumentAttributeValue attrString3 = null;

+		FunctionArgumentAttributeValue attrString4 = null;

+		FunctionArgumentAttributeValue attrStringTimeZone = null;

+		FunctionArgumentAttributeValue attrStringBadValue = null;

+		FunctionArgumentAttributeValue attrStringBadType = null;

+		try {

+			attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("05:12:34.323"));

+			attrString2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("5:12:34.323"));

+			attrString3 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("05:12"));

+			attrString4 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("05:12:34"));

+			attrStringTimeZone = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("05:12:34.323+03:00"));

+			attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value"));

+			attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));

+

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+		

+		FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_TIME_FROM_STRING;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_TIME_FROM_STRING, fd.getId());

+		assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_TIME.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(1), fd.getNumArgs());

+		

+		// test normal

+		arguments.clear();

+		arguments.add(attrString1);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		ISO8601Time resValue = (ISO8601Time)res.getValue().getValue();

+		assertEquals(new ISO8601Time(5, 12, 34, 323), resValue);

+		

+		// check missing 0 in front

+		arguments.clear();

+		arguments.add(attrString2);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:time-from-string Invalid hour of day", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// check missing seconds/msecs

+		arguments.clear();

+		arguments.add(attrString3);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:time-from-string Time string too short", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+

+		// check missing just msecs

+		arguments.clear();

+		arguments.add(attrString4);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (ISO8601Time)res.getValue().getValue();

+		assertEquals(new ISO8601Time(5, 12, 34, 0), resValue);

+		

+		// check TimeZone

+		arguments.clear();

+		arguments.add(attrStringTimeZone);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (ISO8601Time)res.getValue().getValue();

+		assertEquals(new ISO8601Time(new ISO8601TimeZone(180), 5, 12, 34, 323), resValue);

+		

+		// bad value

+		arguments.clear();

+		arguments.add(attrStringBadValue);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:time-from-string Invalid hour of day", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// bad arg type

+		arguments.clear();

+		arguments.add(attrStringBadType);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:time-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+	}

+

+	@Test

+	public void testString_from_time() {

+		FunctionArgumentAttributeValue attrObj1 = null;

+		FunctionArgumentAttributeValue attrObj2 = null;

+		FunctionArgumentAttributeValue attrObjTimeZone = null;

+		FunctionArgumentAttributeValue attrStringBadType = null;

+		try {

+			attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue("05:12:34.323"));

+			attrObj2 = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue("05:01:02.323"));

+			attrObjTimeZone = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue("05:12:34.323+03:00"));

+			attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));

+

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+		

+		FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_TIME;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_STRING_FROM_TIME, fd.getId());

+		assertEquals(DataTypes.DT_TIME.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(1), fd.getNumArgs());

+		

+		// test normal

+		arguments.clear();

+		arguments.add(attrObj1);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals("05:12:34.323", res.getValue().getValue());

+		

+		// missing digits in string value?

+		arguments.clear();

+		arguments.add(attrObj2);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals("05:01:02.323", res.getValue().getValue());

+		

+		// include TimeZone

+		arguments.clear();

+		arguments.add(attrObjTimeZone);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals("05:12:34.323+03:00", res.getValue().getValue());

+		

+		// bad arg type

+		arguments.clear();

+		arguments.add(attrStringBadType);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-from-time Expected data type 'time' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+	}

+	

+	

+	

+	

+	

+	/**

+	 * Date

+	 */

+	@Test

+	public void testDate_from_string() {

+		FunctionArgumentAttributeValue attrString1 = null;

+		FunctionArgumentAttributeValue attrString2 = null;

+		FunctionArgumentAttributeValue attrString3 = null;

+		FunctionArgumentAttributeValue attrString4 = null;

+		FunctionArgumentAttributeValue attrString5 = null;

+		FunctionArgumentAttributeValue attrString6 = null;

+		FunctionArgumentAttributeValue attrString7 = null;

+		FunctionArgumentAttributeValue attrString8 = null;

+		FunctionArgumentAttributeValue attrString9 = null;

+		FunctionArgumentAttributeValue attrStringDateZone = null;

+		FunctionArgumentAttributeValue attrStringBadValue = null;

+		FunctionArgumentAttributeValue attrStringBadType = null;

+		try {

+			attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-05-12"));

+			attrString2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("-2013-05-12"));

+			attrString3 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("1232013-05-12"));

+			attrString4 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("-1232013-05-12"));

+			attrString5 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("213-05-12"));

+			attrString6 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-5-12"));

+			attrString7 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-05-2"));

+			attrString8 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-32-12"));

+			attrString9 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-05-45"));

+			attrStringDateZone = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-05-12+03:00"));

+			attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value"));

+			attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));

+

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+		

+		FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_DATE_FROM_STRING;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_DATE_FROM_STRING, fd.getId());

+		assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_DATE.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(1), fd.getNumArgs());

+		

+		// test normal

+		arguments.clear();

+		arguments.add(attrString1);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		ISO8601Date resValue = (ISO8601Date)res.getValue().getValue();

+		assertEquals(new ISO8601Date(2013, 5, 12), resValue);

+		

+		// check negative

+		arguments.clear();

+		arguments.add(attrString2);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (ISO8601Date)res.getValue().getValue();

+		assertEquals(new ISO8601Date(-2013, 5, 12), resValue);

+		

+		// check big

+		arguments.clear();

+		arguments.add(attrString3);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (ISO8601Date)res.getValue().getValue();

+		assertEquals(new ISO8601Date(1232013, 5, 12), resValue);

+		

+		// check big negative

+		arguments.clear();

+		arguments.add(attrString4);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (ISO8601Date)res.getValue().getValue();

+		assertEquals(new ISO8601Date(-1232013, 5, 12), resValue);

+		

+		// bad year

+		arguments.clear();

+		arguments.add(attrString5);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:date-from-string Invalid year (must be at least 4 digits)", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+

+		// bad month

+		arguments.clear();

+		arguments.add(attrString6);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:date-from-string Invalid month", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+

+		// bad day format

+		arguments.clear();

+		arguments.add(attrString7);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:date-from-string Invalid day", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+

+		// month out of range

+		arguments.clear();

+		arguments.add(attrString8);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:date-from-string Invalid month", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+

+		// day out of range

+		arguments.clear();

+		arguments.add(attrString9);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:date-from-string Invalid day", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+

+		

+		// check TimeZone

+		arguments.clear();

+		arguments.add(attrStringDateZone);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (ISO8601Date)res.getValue().getValue();

+		assertEquals(new ISO8601Date(new ISO8601TimeZone(180), 2013, 5, 12), resValue);

+		

+		// bad value

+		arguments.clear();

+		arguments.add(attrStringBadValue);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:date-from-string Invalid year", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// bad arg type

+		arguments.clear();

+		arguments.add(attrStringBadType);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:date-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+	}

+

+	@Test

+	public void testString_from_date() {

+		FunctionArgumentAttributeValue attrObj1 = null;

+		FunctionArgumentAttributeValue attrObj2 = null;

+		FunctionArgumentAttributeValue attrObjDateZone = null;

+		FunctionArgumentAttributeValue attrStringBadType = null;

+		try {

+			attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue("2013-05-12"));

+			attrObj2 = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue("0001-01-01"));

+			attrObjDateZone = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue("2013-05-12+03:00"));

+			attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));

+

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+		

+		FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_DATE;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_STRING_FROM_DATE, fd.getId());

+		assertEquals(DataTypes.DT_DATE.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(1), fd.getNumArgs());

+		

+		// test normal

+		arguments.clear();

+		arguments.add(attrObj1);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals("2013-05-12", res.getValue().getValue());

+		

+		// missing digits in string value?

+		arguments.clear();

+		arguments.add(attrObj2);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals("1-01-01", res.getValue().getValue());

+		

+		// include DateZone

+		arguments.clear();

+		arguments.add(attrObjDateZone);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals("2013-05-12+03:00", res.getValue().getValue());

+		

+		// bad arg type

+		arguments.clear();

+		arguments.add(attrStringBadType);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-from-date Expected data type 'date' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+	}

+	

+	

+	

+	

+	

+

+	/**

+	 * DateTime

+	 */

+	@Test

+	public void testDateTime_from_string() {

+		FunctionArgumentAttributeValue attrString1 = null;

+		FunctionArgumentAttributeValue attrString2 = null;

+		FunctionArgumentAttributeValue attrString3 = null;

+		FunctionArgumentAttributeValue attrString4 = null;

+		FunctionArgumentAttributeValue attrString5 = null;

+		FunctionArgumentAttributeValue attrString6 = null;

+		FunctionArgumentAttributeValue attrString7 = null;

+		FunctionArgumentAttributeValue attrString8 = null;

+		FunctionArgumentAttributeValue attrString9 = null;

+		FunctionArgumentAttributeValue attrStringDateTimeZone = null;

+		FunctionArgumentAttributeValue attrStringBadValue = null;

+		FunctionArgumentAttributeValue attrStringBadType = null;

+		try {

+			attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-05-12T12:14:15.323"));

+			attrString2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("-2013-05-12T12:14:15.323"));

+			attrString3 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("1232013-05-12T12:14:15.323"));

+			attrString4 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("-1232013-05-12T12:14:15.323"));

+			attrString5 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("213-05-12T12:14:15.323"));

+			attrString6 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-5-12T12:14:15.323"));

+			attrString7 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-05-2T12:14:15.323"));

+			attrString8 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-32-12T12:14:15.323"));

+			attrString9 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-05-45T12:14:15.323"));

+			attrStringDateTimeZone = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-05-12T12:14:15.323+03:00"));

+			attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value"));

+			attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));

+

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+		

+		FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_DATETIME_FROM_STRING;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_DATETIME_FROM_STRING, fd.getId());

+		assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(1), fd.getNumArgs());

+		

+		// test normal

+		arguments.clear();

+		arguments.add(attrString1);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		ISO8601DateTime resValue = (ISO8601DateTime)res.getValue().getValue();

+		assertEquals(new ISO8601DateTime(null, new ISO8601Date(2013, 5, 12), new ISO8601Time(12, 14, 15, 323)), resValue);

+		

+		// check negative

+		arguments.clear();

+		arguments.add(attrString2);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (ISO8601DateTime)res.getValue().getValue();

+		assertEquals(new ISO8601DateTime(null, new ISO8601Date(-2013, 5, 12), new ISO8601Time(12, 14, 15, 323)), resValue);

+		

+		

+		// check big

+		arguments.clear();

+		arguments.add(attrString3);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (ISO8601DateTime)res.getValue().getValue();

+		assertEquals(new ISO8601DateTime(null, new ISO8601Date(1232013, 5, 12), new ISO8601Time(12, 14, 15, 323)), resValue);

+		

+		// check big negative

+		arguments.clear();

+		arguments.add(attrString4);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (ISO8601DateTime)res.getValue().getValue();

+		assertEquals(new ISO8601DateTime(null, new ISO8601Date(-1232013, 5, 12), new ISO8601Time(12, 14, 15, 323)), resValue);

+		

+		// bad year

+		arguments.clear();

+		arguments.add(attrString5);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dateTime-from-string Invalid year (must be at least 4 digits)", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+

+		// bad month

+		arguments.clear();

+		arguments.add(attrString6);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dateTime-from-string Invalid month", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+

+		// bad day format

+		arguments.clear();

+		arguments.add(attrString7);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dateTime-from-string Invalid day", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+

+		// month out of range

+		arguments.clear();

+		arguments.add(attrString8);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dateTime-from-string Invalid month", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+

+		// day out of range

+		arguments.clear();

+		arguments.add(attrString9);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dateTime-from-string Invalid day", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+

+		

+		// check TimeZone

+		arguments.clear();

+		arguments.add(attrStringDateTimeZone);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (ISO8601DateTime)res.getValue().getValue();

+		assertEquals(new ISO8601DateTime(new ISO8601TimeZone(180), new ISO8601Date(new ISO8601TimeZone(180), 2013, 5, 12), new ISO8601Time(new ISO8601TimeZone(180),12, 14, 15, 323)), resValue);

+		

+		// bad value

+		arguments.clear();

+		arguments.add(attrStringBadValue);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dateTime-from-string Invalid year", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// bad arg type

+		arguments.clear();

+		arguments.add(attrStringBadType);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dateTime-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+	}

+

+	@Test

+	public void testString_from_dateTime() {

+		FunctionArgumentAttributeValue attrObj1 = null;

+		FunctionArgumentAttributeValue attrObj2 = null;

+		FunctionArgumentAttributeValue attrObjDateTimeZone = null;

+		FunctionArgumentAttributeValue attrStringBadType = null;

+		try {

+			attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue("2013-05-12T12:14:15.323"));

+			attrObj2 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue("0001-01-01T12:14:15.323"));

+			attrObjDateTimeZone = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue("2013-05-12T12:14:15.323+03:00"));

+			attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));

+

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+		

+		FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_DATETIME;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_STRING_FROM_DATETIME, fd.getId());

+		assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(1), fd.getNumArgs());

+		

+		// test normal

+		arguments.clear();

+		arguments.add(attrObj1);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals("2013-05-12T12:14:15.323", res.getValue().getValue());

+		

+		// missing digits in string value?

+		arguments.clear();

+		arguments.add(attrObj2);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals("1-01-01T12:14:15.323", res.getValue().getValue());

+		

+		// include DateTimeZone

+		arguments.clear();

+		arguments.add(attrObjDateTimeZone);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals("2013-05-12T12:14:15.323+03:00", res.getValue().getValue());

+		

+		// bad arg type

+		arguments.clear();

+		arguments.add(attrStringBadType);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-from-dateTime Expected data type 'dateTime' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+	}

+	

+	

+	

+	

+	

+	/**

+	 * URI

+	 */

+	@Test

+	public void testURI_from_string() {

+		FunctionArgumentAttributeValue attrString1 = null;

+		FunctionArgumentAttributeValue attrStringBadValue = null;

+		FunctionArgumentAttributeValue attrStringBadType = null;

+		try {

+			attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("http://someMachine.com/subdir"));

+			attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value"));

+			attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));

+

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+		

+		FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_ANYURI_FROM_STRING;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_ANYURI_FROM_STRING, fd.getId());

+		assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_ANYURI.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(1), fd.getNumArgs());

+		

+		// test normal

+		arguments.clear();

+		arguments.add(attrString1);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		URI resValue = (URI)res.getValue().getValue();

+		try {

+			assertEquals(new URI("http://someMachine.com/subdir"), resValue);

+		} catch (URISyntaxException e) {

+			fail("uri generation e="+e);

+		}

+		

+		// bad value

+		arguments.clear();

+		arguments.add(attrStringBadValue);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:anyURI-from-string Illegal character in path at index 3: not valid obj value", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// bad arg type

+		arguments.clear();

+		arguments.add(attrStringBadType);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:anyURI-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+	}

+

+	@Test

+	public void testString_from_anyURI() {

+		FunctionArgumentAttributeValue attrObj1 = null;

+		FunctionArgumentAttributeValue attrStringBadType = null;

+		String objValueString = "http://aMachine.com:8080/aRef";

+		try {

+			attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(objValueString));

+			attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));

+

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+		

+		FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_ANYURI;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_STRING_FROM_ANYURI, fd.getId());

+		assertEquals(DataTypes.DT_ANYURI.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(1), fd.getNumArgs());

+		

+		// test normal

+		arguments.clear();

+		arguments.add(attrObj1);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(objValueString, res.getValue().getValue());

+		

+		// bad arg type

+		arguments.clear();

+		arguments.add(attrStringBadType);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-from-anyURI Expected data type 'anyURI' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+	}

+	

+	

+	

+	/**

+	 * XPathDayTimeDuration

+	 */

+	@Test

+	public void testXPathDayTimeDuration_from_string() {

+		FunctionArgumentAttributeValue attrString1 = null;

+		FunctionArgumentAttributeValue attrStringNeg1 = null;

+		FunctionArgumentAttributeValue attrStringNeg2 = null;

+		FunctionArgumentAttributeValue attrStringNoDay = null;

+		FunctionArgumentAttributeValue attrStringNoHour = null;

+		FunctionArgumentAttributeValue attrStringNoMin = null;

+		FunctionArgumentAttributeValue attrStringNoSec = null;

+		FunctionArgumentAttributeValue attrStringNoP = null;

+		FunctionArgumentAttributeValue attrStringSecondsDot = null;

+		FunctionArgumentAttributeValue attrStringMissingTOk = null;

+		FunctionArgumentAttributeValue attrStringMissingTBad = null;

+		FunctionArgumentAttributeValue attrStringBadValue = null;

+		FunctionArgumentAttributeValue attrStringBadType = null;

+		try {

+			attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P3DT10H30M23S"));

+			attrStringNeg1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("-P3DT10H30M23S"));

+			attrStringNeg2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P-3DT10H30M23S"));

+			attrStringNoDay = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("PT10H30M23S"));

+			attrStringNoHour = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P3DT30M23S"));

+			attrStringNoMin = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P3DT10H23S"));

+			attrStringNoSec = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P3DT10H30M"));

+			attrStringNoP = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("3DT10H30M"));

+			attrStringSecondsDot = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P3DT10H30M23.456S"));

+			attrStringMissingTOk = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P3D"));

+			attrStringMissingTBad = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P3D10H30M23S"));

+

+			attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value"));

+			attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));

+

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+		

+		FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_DAYTIMEDURATION_FROM_STRING;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_DAYTIMEDURATION_FROM_STRING, fd.getId());

+		assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_DAYTIMEDURATION.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(1), fd.getNumArgs());

+		

+		// test normal

+		arguments.clear();

+		arguments.add(attrString1);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		XPathDayTimeDuration resValue = (XPathDayTimeDuration)res.getValue().getValue();

+		assertEquals(new XPathDayTimeDuration(1, 3, 10, 30, 23), resValue);

+		

+		

+		//		negative values in front is allowed

+		arguments.clear();

+		arguments.add(attrStringNeg1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (XPathDayTimeDuration)res.getValue().getValue();

+		assertEquals(new XPathDayTimeDuration(-1, 3, 10, 30, 23), resValue);

+		

+		// negative in middle of string not ok

+		arguments.clear();

+		arguments.add(attrStringNeg2);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dayTimeDuration-from-string Invalid chunk \"P-3DT10H30M23S\" at position 1", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		

+		//	omit parts that are 0

+		arguments.clear();

+		arguments.add(attrStringNoDay);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (XPathDayTimeDuration)res.getValue().getValue();

+		assertEquals(new XPathDayTimeDuration(1, 0, 10, 30, 23), resValue);

+		

+		arguments.clear();

+		arguments.add(attrStringNoHour);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (XPathDayTimeDuration)res.getValue().getValue();

+		assertEquals(new XPathDayTimeDuration(1, 3, 0, 30, 23), resValue);

+		

+		arguments.clear();

+		arguments.add(attrStringNoMin);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (XPathDayTimeDuration)res.getValue().getValue();

+		assertEquals(new XPathDayTimeDuration(1, 3, 10, 0, 23), resValue);

+		

+		arguments.clear();

+		arguments.add(attrStringNoSec);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (XPathDayTimeDuration)res.getValue().getValue();

+		assertEquals(new XPathDayTimeDuration(1, 3, 10, 30, 0), resValue);

+		

+		//		P must always be present

+		arguments.clear();

+		arguments.add(attrStringNoP);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dayTimeDuration-from-string Invalid ISO8601 duration string \"3DT10H30M\" at position 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		//		seconds may contain decimal

+		arguments.clear();

+		arguments.add(attrStringSecondsDot);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (XPathDayTimeDuration)res.getValue().getValue();

+		assertEquals(new XPathDayTimeDuration(1, 3, 10, 30, 23.456), resValue);

+		

+		//		T must be absent iff all time items are absent

+		arguments.clear();

+		arguments.add(attrStringMissingTOk);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (XPathDayTimeDuration)res.getValue().getValue();

+		assertEquals(new XPathDayTimeDuration(1, 3, 0, 0, 0), resValue);

+		

+		// negative in middle of string not ok

+		arguments.clear();

+		arguments.add(attrStringMissingTBad);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dayTimeDuration-from-string Invalid ISO8601 duration string \"P3D10H30M23S\" at position 6: out of order component", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		

+		// bad value

+		arguments.clear();

+		arguments.add(attrStringBadValue);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dayTimeDuration-from-string Invalid ISO8601 duration string \"not valid obj value\" at position 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// bad arg type

+		arguments.clear();

+		arguments.add(attrStringBadType);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dayTimeDuration-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+	}

+

+	@Test

+	public void testString_from_dayTimeDuration() {

+		FunctionArgumentAttributeValue attrObj1 = null;

+		FunctionArgumentAttributeValue attrStringBadType = null;

+		String objValueString = "P3DT10H30M23S";

+		try {

+			attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(objValueString));

+			attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));

+

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+		

+		FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_DAYTIMEDURATION;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_STRING_FROM_DAYTIMEDURATION, fd.getId());

+		assertEquals(DataTypes.DT_DAYTIMEDURATION.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(1), fd.getNumArgs());

+		

+		// test normal

+		arguments.clear();

+		arguments.add(attrObj1);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(objValueString, res.getValue().getValue());

+		

+		// bad arg type

+		arguments.clear();

+		arguments.add(attrStringBadType);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-from-dayTimeDuration Expected data type 'dayTimeDuration' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+	}

+	

+	

+	

+	

+	

+	

+	

+	

+	

+	/**

+	 * XPathYearMonthDuration

+	 */

+	@Test

+	public void testXPathYearMonthDuration_from_string() {

+		FunctionArgumentAttributeValue attrString1 = null;

+		FunctionArgumentAttributeValue attrStringNeg1 = null;

+		FunctionArgumentAttributeValue attrStringNeg2 = null;

+		FunctionArgumentAttributeValue attrStringNoYear1 = null;

+		FunctionArgumentAttributeValue attrStringNoYear2 = null;

+		FunctionArgumentAttributeValue attrStringNoMonth1 = null;

+		FunctionArgumentAttributeValue attrStringNoMonth2 = null;

+		FunctionArgumentAttributeValue attrStringNoValue = null;

+		FunctionArgumentAttributeValue attrStringNoP = null;

+		FunctionArgumentAttributeValue attrStringBigMonths = null;

+		FunctionArgumentAttributeValue attrStringMissingTOk = null;

+		FunctionArgumentAttributeValue attrStringMissingTBad = null;

+		FunctionArgumentAttributeValue attrStringZeroMonths = null;

+		FunctionArgumentAttributeValue attrStringBadValue = null;

+		FunctionArgumentAttributeValue attrStringBadType = null;

+		try {

+			attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P1Y2M"));

+			attrStringNeg1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("-P1Y2M"));

+			attrStringNeg2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P-1Y2M"));

+			attrStringNoYear1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P2M"));

+			attrStringNoYear2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("PY2M"));

+			attrStringNoMonth1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P1Y"));

+			attrStringNoMonth2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P1YM"));

+			attrStringNoValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P"));

+			attrStringNoP = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("1Y2M"));

+			attrStringBigMonths = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P1Y12M"));

+			attrStringMissingTOk = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P3D"));

+			attrStringMissingTBad = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P3D10H30M23S"));

+			attrStringZeroMonths = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P0M"));

+

+			attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value"));

+			attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));

+

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+		

+		FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_YEARMONTHDURATION_FROM_STRING;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_YEARMONTHDURATION_FROM_STRING, fd.getId());

+		assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_YEARMONTHDURATION.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(1), fd.getNumArgs());

+		

+		// test normal

+		arguments.clear();

+		arguments.add(attrString1);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		XPathYearMonthDuration resValue = (XPathYearMonthDuration)res.getValue().getValue();

+		assertEquals(new XPathYearMonthDuration(1,1, 2), resValue);

+		

+		

+		//		negative values in front is allowed

+		arguments.clear();

+		arguments.add(attrStringNeg1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (XPathYearMonthDuration)res.getValue().getValue();

+		assertEquals(new XPathYearMonthDuration(-1, 1, 2), resValue);

+		

+		// negative in middle of string not ok

+		arguments.clear();

+		arguments.add(attrStringNeg2);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:yearMonthDuration-from-string Invalid chunk \"P-1Y2M\" at position 1", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		

+		//	omit parts that are 0

+		arguments.clear();

+		arguments.add(attrStringNoYear1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (XPathYearMonthDuration)res.getValue().getValue();

+		assertEquals(new XPathYearMonthDuration(1, 0, 2), resValue);

+		

+		arguments.clear();

+		arguments.add(attrStringNoYear2);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:yearMonthDuration-from-string Invalid chunk \"PY2M\" at position 1", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		

+		arguments.clear();

+		arguments.add(attrStringNoMonth1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (XPathYearMonthDuration)res.getValue().getValue();

+		assertEquals(new XPathYearMonthDuration(1, 1, 0), resValue);

+		

+		arguments.clear();

+		arguments.add(attrStringNoMonth2);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:yearMonthDuration-from-string Invalid chunk \"P1YM\" at position 3", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		

+		// No field with a value 

+		arguments.clear();

+		arguments.add(attrStringNoValue);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:yearMonthDuration-from-string Invalid ISO8601 duration string \"P\": No duration components following P", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		

+		//		P must always be present

+		arguments.clear();

+		arguments.add(attrStringNoP);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:yearMonthDuration-from-string Invalid ISO8601 duration string \"1Y2M\" at position 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		//		Canonical Form of output may not have more than 12 months, but input as string is ok?

+		arguments.clear();

+		arguments.add(attrStringBigMonths);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (XPathYearMonthDuration)res.getValue().getValue();

+		assertEquals(new XPathYearMonthDuration(1, 1, 12), resValue);

+		

+		// Canonical representation of 0 Months

+		arguments.clear();

+		arguments.add(attrStringZeroMonths);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (XPathYearMonthDuration)res.getValue().getValue();

+		assertEquals(new XPathYearMonthDuration(1, 0, 0), resValue);

+		

+		//		T must be absent iff all time items are absent

+		arguments.clear();

+		arguments.add(attrStringMissingTOk);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:yearMonthDuration-from-string Invalid XPath yearMonthDuraiton \"{durationSign=1years=0months=0days=3hours=0minutes=0seconds=0millis=0}\": includes days, hours, minutes, or seconds", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// negative in middle of string not ok

+		arguments.clear();

+		arguments.add(attrStringMissingTBad);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:yearMonthDuration-from-string Invalid ISO8601 duration string \"P3D10H30M23S\" at position 6: out of order component", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		

+		// bad value

+		arguments.clear();

+		arguments.add(attrStringBadValue);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:yearMonthDuration-from-string Invalid ISO8601 duration string \"not valid obj value\" at position 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// bad arg type

+		arguments.clear();

+		arguments.add(attrStringBadType);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:yearMonthDuration-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+	}

+

+	@Test

+	public void testString_from_yearMonthDuration() {

+		FunctionArgumentAttributeValue attrObj1 = null;

+		FunctionArgumentAttributeValue attrStringBadType = null;

+		String objValueString = "P1Y2M";

+		try {

+			attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(objValueString));

+			attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));

+

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+		

+		FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_YEARMONTHDURATION;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_STRING_FROM_YEARMONTHDURATION, fd.getId());

+		assertEquals(DataTypes.DT_YEARMONTHDURATION.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(1), fd.getNumArgs());

+		

+		// test normal

+		arguments.clear();

+		arguments.add(attrObj1);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(objValueString, res.getValue().getValue());

+		

+		// bad arg type

+		arguments.clear();

+		arguments.add(attrStringBadType);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-from-yearMonthDuration Expected data type 'yearMonthDuration' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+	}

+	

+	

+

+

+	

+	

+	/**

+	 * X500Principal

+	 * 

+	 * See http://www.ietf.org/rfc/rfc2253.txt and http://www.ietf.org/rfc/rfc2251.txt

+	 */

+	@Test

+	public void testX500Principal_from_string() {

+		FunctionArgumentAttributeValue attrString1 = null;

+		FunctionArgumentAttributeValue attrStringNoComma = null;

+		FunctionArgumentAttributeValue attrStringEmpty = null;

+		FunctionArgumentAttributeValue attrStringNoValue = null;

+		FunctionArgumentAttributeValue attrStringOrder = null;

+		FunctionArgumentAttributeValue attrStringDottedDecimalOID = null;

+		FunctionArgumentAttributeValue attrStringBadValue = null;

+		FunctionArgumentAttributeValue attrStringBadType = null;

+		try {

+			attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("CN=Name, L=local, ST=NJ, O=ATT, C=USA"));

+			attrStringNoComma = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("CN=Name, L=local ST=NJ, O=ATT, C=USA"));

+			attrStringEmpty = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(""));

+			attrStringNoValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("CN=Name, L=, ST=NJ, O=ATT, C=USA"));

+			attrStringOrder = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("L=local, ST=NJ, O=ATT, CN=Name, C=USA"));

+			attrStringDottedDecimalOID = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2.5.4.3=A. N. Other"));

+

+			attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value"));

+			attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));

+

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+

+		

+		FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_X500NAME_FROM_STRING;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_X500NAME_FROM_STRING, fd.getId());

+		assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_X500NAME.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(1), fd.getNumArgs());

+		

+		// test normal

+		arguments.clear();

+		arguments.add(attrString1);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		X500Principal resValue = (X500Principal)res.getValue().getValue();

+		assertEquals(new X500Principal("CN=Name, L=local, ST=NJ, O=ATT, C=USA"), resValue);

+		

+		// no comma between components => next attribute/value is included as part of first value

+		arguments.clear();

+		arguments.add(attrStringNoComma);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (X500Principal)res.getValue().getValue();

+		assertEquals(new X500Principal("CN=Name, L=local ST=NJ, O=ATT, C=USA"), resValue);

+		

+		// nothing in name (fail)

+		arguments.clear();

+		arguments.add(attrStringEmpty);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (X500Principal)res.getValue().getValue();

+		assertEquals(new X500Principal(""), resValue);

+		

+		// type value with no =

+		arguments.clear();

+		arguments.add(attrStringNoValue);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (X500Principal)res.getValue().getValue();

+		assertEquals(new X500Principal("CN=Name, L=, ST=NJ, O=ATT, C=USA"), resValue);

+		

+		// different order

+		arguments.clear();

+		arguments.add(attrStringOrder);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (X500Principal)res.getValue().getValue();

+		assertNotEquals(new X500Principal("CN=Name, L=local, ST=NJ, O=ATT, C=USA"), resValue);

+	

+		// dotted-decimal name with numbers

+		arguments.clear();

+		arguments.add(attrStringDottedDecimalOID);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (X500Principal)res.getValue().getValue();

+		assertEquals(new X500Principal("2.5.4.3=A. N. Other"), resValue);

+		

+

+		

+		// bad value

+		arguments.clear();

+		arguments.add(attrStringBadValue);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:x500Name-from-string improperly specified input name: not valid obj value", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// bad arg type

+		arguments.clear();

+		arguments.add(attrStringBadType);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:x500Name-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+	}

+

+	@Test

+	public void testString_from_x500Name() {

+		FunctionArgumentAttributeValue attrObj1 = null;

+		FunctionArgumentAttributeValue attrStringBadType = null;

+		String objValueString = "CN=Name, L=local, ST=NJ, O=ATT, C=USA";

+		try {

+			attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(objValueString));

+			attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));

+

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+		

+		FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_X500NAME;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_STRING_FROM_X500NAME, fd.getId());

+		assertEquals(DataTypes.DT_X500NAME.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(1), fd.getNumArgs());

+		

+		// test normal

+		arguments.clear();

+		arguments.add(attrObj1);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(objValueString, res.getValue().getValue());

+		

+		// bad arg type

+		arguments.clear();

+		arguments.add(attrStringBadType);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-from-x500Name Expected data type 'x500Name' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+	}

+

+	

+	

+	

+	/**

+	 * RFC822Name

+	 */

+	@Test

+	public void testRFC822Name_from_string() {

+		FunctionArgumentAttributeValue attrString1 = null;

+		FunctionArgumentAttributeValue attrStringCapsDomain = null;

+		FunctionArgumentAttributeValue attrStringCapsLocal = null;

+		FunctionArgumentAttributeValue attrStringMissingAt = null;

+		FunctionArgumentAttributeValue attrStringMissingLocal = null;

+		FunctionArgumentAttributeValue attrStringMissingDomain = null;

+		FunctionArgumentAttributeValue attrStringEmpty = null;

+		FunctionArgumentAttributeValue attrStringBadValue = null;

+		FunctionArgumentAttributeValue attrStringBadType = null;

+		try {

+			attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("local@Domain"));

+			attrStringCapsDomain = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("local@DOMAIN"));

+			attrStringCapsLocal = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("LOCAL@Domain"));

+			attrStringMissingAt = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("localDomain"));

+			attrStringMissingLocal = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("@Domain"));

+			attrStringMissingDomain = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("local@"));

+			attrStringEmpty = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(""));

+			

+			attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value"));

+			attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));

+

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+		

+		FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_RFC822NAME_FROM_STRING;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_RFC822NAME_FROM_STRING, fd.getId());

+		assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_RFC822NAME.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(1), fd.getNumArgs());

+		

+		// test normal

+		arguments.clear();

+		arguments.add(attrString1);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		RFC822Name resValue = (RFC822Name)res.getValue().getValue();

+		assertEquals(new RFC822Name("local", "domain"), resValue);

+		

+		// caps domain

+		arguments.clear();

+		arguments.add(attrStringCapsDomain);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (RFC822Name)res.getValue().getValue();

+		assertEquals(new RFC822Name("local", "domain"), resValue);

+		

+		// caps local

+		arguments.clear();

+		arguments.add(attrStringCapsLocal);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (RFC822Name)res.getValue().getValue();

+		assertNotEquals(new RFC822Name("local", "domain"), resValue);

+		

+		// missing at

+		arguments.clear();

+		arguments.add(attrStringMissingAt);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:rfc822Name-from-string Invalid RFC822Name \"localDomain\": missing local part", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// missing local

+		arguments.clear();

+		arguments.add(attrStringMissingLocal);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:rfc822Name-from-string Invalid RFC822Name \"@Domain\": empty parts", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// missing domain

+		arguments.clear();

+		arguments.add(attrStringMissingDomain);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:rfc822Name-from-string Invalid RFC822Name \"local@\": empty parts", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// empty

+		arguments.clear();

+		arguments.add(attrStringEmpty);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:rfc822Name-from-string Invalid RFC822Name \"\": missing local part", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		

+		// bad value

+		arguments.clear();

+		arguments.add(attrStringBadValue);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:rfc822Name-from-string Invalid RFC822Name \"not valid obj value\": missing local part", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// bad arg type

+		arguments.clear();

+		arguments.add(attrStringBadType);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:rfc822Name-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+	}

+

+	@Test

+	public void testString_from_rfc822Name() {

+		FunctionArgumentAttributeValue attrObj1 = null;

+		FunctionArgumentAttributeValue attrStringBadType = null;

+		String objValueString = "local@DOMAIN";

+		try {

+			attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue(objValueString));

+			attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));

+

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+		

+		FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_RFC822NAME;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_STRING_FROM_RFC822NAME, fd.getId());

+		assertEquals(DataTypes.DT_RFC822NAME.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(1), fd.getNumArgs());

+		

+		// test normal

+		arguments.clear();

+		arguments.add(attrObj1);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals("local@domain", res.getValue().getValue());

+		

+		// bad arg type

+		arguments.clear();

+		arguments.add(attrStringBadType);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-from-rfc822Name Expected data type 'rfc822Name' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+	}

+	

+	

+	

+	

+	/**

+	 * IPAddress

+	 */

+	@Test

+	public void testIPAddress_from_string() {

+		FunctionArgumentAttributeValue attrString1 = null;

+		FunctionArgumentAttributeValue attrStringFull = null;

+		FunctionArgumentAttributeValue attrStringMissingElement = null;

+		FunctionArgumentAttributeValue attrStringTooManyElement = null;

+		FunctionArgumentAttributeValue attrStringIllegalElement = null;

+		FunctionArgumentAttributeValue attrStringOutOfOrder = null;

+		

+		FunctionArgumentAttributeValue attrStringMask = null;

+		FunctionArgumentAttributeValue attrStringMissingMaskElement = null;

+		FunctionArgumentAttributeValue attrStringTooManyMaskElement = null;

+		FunctionArgumentAttributeValue attrStringIllegalMaskElement = null;

+		FunctionArgumentAttributeValue attrStringMaskNoValue = null;

+		

+		FunctionArgumentAttributeValue attrStringMinusPort = null;

+		FunctionArgumentAttributeValue attrStringPortMinus = null;

+		FunctionArgumentAttributeValue attrStringPortPort = null;

+		FunctionArgumentAttributeValue attrStringNoPort = null;

+		FunctionArgumentAttributeValue attrStringBadPort = null;

+		FunctionArgumentAttributeValue attrStringTooManyPorts = null;

+		FunctionArgumentAttributeValue attrStringBadValue = null;

+		FunctionArgumentAttributeValue attrStringBadType = null;

+		

+		// set up for v4 address tests - this setup and the tests are repeated for V6

+		short[] addrShorts= {123, 134, 156, 255 };

+		short[] addrMaskShorts= {255, 255, 255, 255 };

+		try {

+			attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.156.255"));

+			attrStringFull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.156.255/255.255.255.255:123-456"));

+			attrStringMissingElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.255"));

+			attrStringTooManyElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.255.111.222"));

+			attrStringIllegalElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.256.255"));

+			attrStringOutOfOrder = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.256.255:123-456/255.255.255.255"));

+

+			attrStringMask = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.156.255/255.255.255.255"));

+			attrStringMissingMaskElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.156.255/123.134.255"));

+			attrStringTooManyMaskElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.156.255/122.134.155.111.222"));

+			attrStringIllegalMaskElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.156.255/123.134.256.255"));

+			attrStringMaskNoValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.156.255/"));

+			// optional mask

+			// "/" with no mask (fail)

+

+			attrStringMinusPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.156.255:-123"));

+			attrStringPortMinus = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.156.255:123-"));

+			attrStringPortPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.156.255:1234567-432"));

+			attrStringNoPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.156.255:"));

+			attrStringBadPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.156.255:12.34"));

+			attrStringTooManyPorts = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.156.255:-123-456"));

+

+

+			

+			attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value"));

+			attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));

+

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+		

+		FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_IPADDRESS_FROM_STRING;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_IPADDRESS_FROM_STRING, fd.getId());

+		assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_IPADDRESS.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(1), fd.getNumArgs());

+		

+		// test normal

+		arguments.clear();

+		arguments.add(attrString1);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		IPAddress resValue = (IPAddress)res.getValue().getValue();

+		assertEquals(new IPv4Address(addrShorts, null, null), resValue);

+

+		// fully-loaded address

+		arguments.clear();

+		arguments.add(attrStringFull);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (IPAddress)res.getValue().getValue();

+		try {

+			assertEquals(new IPv4Address(addrShorts, addrMaskShorts, PortRange.newInstance("123-456")), resValue);

+		} catch (Exception e) {

+			fail("port error e="+e);

+		}

+		

+		// missing element

+		arguments.clear();

+		arguments.add(attrStringMissingElement);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:ipAddress-from-string Invalid IPv4 address string \"123.134.255\": invalid address", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// too many elements

+		arguments.clear();

+		arguments.add(attrStringTooManyElement);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:ipAddress-from-string Invalid IPv4 address string \"123.134.255.111.222\": invalid address", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// illegal element

+		arguments.clear();

+		arguments.add(attrStringIllegalElement);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:ipAddress-from-string Invalid IPv4 address string \"123.134.256.255\": invalid octet: \"256", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// Out of order

+		arguments.clear();

+		arguments.add(attrStringOutOfOrder);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:ipAddress-from-string Invalid IPv4 address string \"123.134.256.255:123-456/255.255.255.255\": out of order components", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		

+		// simple mask

+		arguments.clear();

+		arguments.add(attrStringMask);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (IPAddress)res.getValue().getValue();

+		try {

+			assertEquals(new IPv4Address(addrShorts, addrMaskShorts, null), resValue);

+		} catch (Exception e) {

+			fail("port error e="+e);

+		}

+		

+		// missing mask element

+		arguments.clear();

+		arguments.add(attrStringMissingMaskElement);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:ipAddress-from-string Invalid IPv4 address string \"123.134.255\": invalid address", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// too many mask elements

+		arguments.clear();

+		arguments.add(attrStringTooManyMaskElement);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:ipAddress-from-string Invalid IPv4 address string \"122.134.155.111.222\": invalid address", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// illegal Mask element

+		arguments.clear();

+		arguments.add(attrStringIllegalMaskElement);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:ipAddress-from-string Invalid IPv4 address string \"123.134.256.255\": invalid octet: \"256", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		//mask indicator without value

+		arguments.clear();

+		arguments.add(attrStringMaskNoValue);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:ipAddress-from-string Invalid IPv4 address string \"\": invalid address", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		

+		// portrange (-port, port-, port-port)

+		arguments.clear();

+		arguments.add(attrStringMinusPort);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (IPAddress)res.getValue().getValue();

+		try {

+			assertEquals(new IPv4Address(addrShorts, null, PortRange.newInstance("-123")), resValue);

+		} catch (ParseException e) {

+			fail("port error e="+e);

+		}

+		

+		arguments.clear();

+		arguments.add(attrStringPortMinus);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (IPAddress)res.getValue().getValue();

+		try {

+			assertEquals(new IPv4Address(addrShorts, null, PortRange.newInstance("123-")), resValue);

+		} catch (ParseException e) {

+			fail("port error e="+e);

+		}

+		

+		arguments.clear();

+		arguments.add(attrStringPortPort);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (IPAddress)res.getValue().getValue();

+		try {

+			assertEquals(new IPv4Address(addrShorts, null, PortRange.newInstance("1234567-432")), resValue);

+		} catch (ParseException e) {

+			fail("port error e="+e);

+		}

+		

+		// ":" without port

+		arguments.clear();

+		arguments.add(attrStringNoPort);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:ipAddress-from-string Invalid IPv4 address string \"123.134.156.255:\": no portrange given after ':'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		

+		// bad port number

+		arguments.clear();

+		arguments.add(attrStringBadPort);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:ipAddress-from-string Invalid PortRange \"12.34\": invalid port number", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// bad port range

+		arguments.clear();

+		arguments.add(attrStringTooManyPorts);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:ipAddress-from-string Invalid PortRange \"-123-456\": too many ranges", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		

+		// bad value

+		arguments.clear();

+		arguments.add(attrStringBadValue);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:ipAddress-from-string Unknown IPAddress type for \"not valid obj value\"", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// bad arg type

+		arguments.clear();

+		arguments.add(attrStringBadType);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:ipAddress-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+	

+	

+		//

+		// V6 IP Addresses

+		//

+		

+		// reset the variable for IPv6 tests

+		FunctionArgumentAttributeValue attrStringAlternateFull = null;

+		FunctionArgumentAttributeValue attrStringEmptyElement = null;

+		FunctionArgumentAttributeValue attrString2xEmptyElement = null;

+		FunctionArgumentAttributeValue attrStringNoStartBracket = null;

+		FunctionArgumentAttributeValue attrStringNoEndBracket = null;

+		short[] addrv6Shorts = {(short)0x2001, (short)0xdb8, (short)0x85a3, (short)0x0, (short)0x0, (short)0x8a2e, (short)0x370, (short)0x1};

+		Short prefix = new Short((short) 121);

+		try {

+			attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1]"));

+			attrStringFull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1/121]:123-456"));

+			attrStringAlternateFull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1]/121:123-456"));

+			attrStringEmptyElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3::8a2e:370:1]"));

+			attrString2xEmptyElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3::8a2e::1]"));

+			attrStringNoStartBracket = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2002:db8:85a3::8a2e::1]"));

+			attrStringNoEndBracket = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3::8a2e::1"));

+

+			attrStringMissingElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:1]"));

+			attrStringTooManyElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1:123]"));

+			attrStringIllegalElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:mnop:85a3:0:0:8a2e:370:1]"));

+			attrStringOutOfOrder = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:mnop:85a3:0:0:8a2e:370:1:123-456/121]"));

+

+			attrStringMask = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1/21]"));

+			attrStringIllegalMaskElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1/130]"));

+			attrStringMaskNoValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1/]"));

+

+			attrStringMinusPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1]:-123"));

+			attrStringPortMinus = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1]:123-"));

+			attrStringPortPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1]:1234567-432"));

+			attrStringNoPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1]:"));

+			attrStringBadPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1]:12.34"));

+			attrStringTooManyPorts = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1]:-123-456"));

+

+			attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value"));

+			attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));

+

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+	

+		

+		// test normal

+		arguments.clear();

+		arguments.add(attrString1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (IPAddress)res.getValue().getValue();

+		assertEquals(new IPv6Address(addrv6Shorts, null, null), resValue);

+

+		// fully-loaded address - "prefix" is inside the brackets (not clear if this is correct)

+		arguments.clear();

+		arguments.add(attrStringFull);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (IPAddress)res.getValue().getValue();

+		try {

+			assertEquals(new IPv6Address(addrv6Shorts, new Short(prefix), PortRange.newInstance("123-456")), resValue);

+		} catch (Exception e) {

+			fail("port error e="+e);

+		}

+		

+		// Alternate way of identifying "prefix" - outside the brackets

+		arguments.clear();

+		arguments.add(attrStringAlternateFull);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (IPAddress)res.getValue().getValue();

+		try {

+			assertEquals(new IPv6Address(addrv6Shorts, prefix, PortRange.newInstance("123-456")), resValue);

+		} catch (Exception e) {

+			fail("port error e="+e);

+		}

+		

+		

+		// consecutive zero elements removed

+		arguments.clear();

+		arguments.add(attrStringEmptyElement);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (IPAddress)res.getValue().getValue();

+		try {

+			assertEquals(new IPv6Address(addrv6Shorts, prefix, null), resValue);

+		} catch (Exception e) {

+			fail("port error e="+e);

+		}

+		

+		// consecutive zero elements removed in two locations (no-no)

+		arguments.clear();

+		arguments.add(attrString2xEmptyElement);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:ipAddress-from-string Invalid IPv6Address string \"2001:db8:85a3::8a2e::1\": multiple zero runs", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// address must have [] on it

+		arguments.clear();

+		arguments.add(attrStringNoStartBracket);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:ipAddress-from-string Invalid IPv6Address string \"2002:db8:85a3::8a2e::1]\": missing opening bracket", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		arguments.clear();

+		arguments.add(attrStringNoEndBracket);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:ipAddress-from-string Invalid IPv6Address string \"[2001:db8:85a3::8a2e::1\": missing closing bracket", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		

+		// missing element

+		arguments.clear();

+		arguments.add(attrStringMissingElement);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:ipAddress-from-string Invalid IPv6Address string \"2001:db8:85a3:0:0:8a2e:1\": not enough address fields", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// too many elements

+		arguments.clear();

+		arguments.add(attrStringTooManyElement);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:ipAddress-from-string Invalid IPv6Address string \"2001:db8:85a3:0:0:8a2e:370:1:123\"", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// illegal element

+		arguments.clear();

+		arguments.add(attrStringIllegalElement);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:ipAddress-from-string Invalid IPv6Address component \"mnop\": invalid hex", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// Out of order

+		arguments.clear();

+		arguments.add(attrStringOutOfOrder);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:ipAddress-from-string Invalid IPv6Address string \"2001:mnop:85a3:0:0:8a2e:370:1:123-456\"", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		

+		// simple mask

+		arguments.clear();

+		arguments.add(attrStringMask);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (IPAddress)res.getValue().getValue();

+		try {

+			assertEquals(new IPv6Address(addrv6Shorts, prefix, null), resValue);

+		} catch (Exception e) {

+			fail("port error e="+e);

+		}

+		

+		// illegal Mask element

+		arguments.clear();

+		arguments.add(attrStringIllegalMaskElement);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:ipAddress-from-string Invalid Ipv6Address string \"[2001:db8:85a3:0:0:8a2e:370:1/130]\": prefix is larger than 128", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		//mask indicator without value

+		arguments.clear();

+		arguments.add(attrStringMaskNoValue);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:ipAddress-from-string Invalid Ipv6Address string \"[2001:db8:85a3:0:0:8a2e:370:1/]\": prefix designation without value", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		

+		// portrange (-port, port-, port-port)

+		arguments.clear();

+		arguments.add(attrStringMinusPort);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (IPAddress)res.getValue().getValue();

+		try {

+			assertEquals(new IPv6Address(addrv6Shorts, null, PortRange.newInstance("-123")), resValue);

+		} catch (ParseException e) {

+			fail("port error e="+e);

+		}

+		

+		arguments.clear();

+		arguments.add(attrStringPortMinus);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (IPAddress)res.getValue().getValue();

+		try {

+			assertEquals(new IPv6Address(addrv6Shorts, null, PortRange.newInstance("123-")), resValue);

+		} catch (ParseException e) {

+			fail("port error e="+e);

+		}

+		

+		arguments.clear();

+		arguments.add(attrStringPortPort);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (IPAddress)res.getValue().getValue();

+		try {

+			assertEquals(new IPv6Address(addrv6Shorts, null, PortRange.newInstance("1234567-432")), resValue);

+		} catch (ParseException e) {

+			fail("port error e="+e);

+		}

+		

+		// ":" without port

+		arguments.clear();

+		arguments.add(attrStringNoPort);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:ipAddress-from-string Invalid IPv6 address string \"[2001:db8:85a3:0:0:8a2e:370:1]:\": no portrange given after ':'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		

+		// bad port number

+		arguments.clear();

+		arguments.add(attrStringBadPort);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:ipAddress-from-string Invalid PortRange \"12.34\": invalid port number", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// bad port range

+		arguments.clear();

+		arguments.add(attrStringTooManyPorts);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:ipAddress-from-string Invalid PortRange \"-123-456\": too many ranges", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		

+	

+	

+	

+	}

+

+	@Test

+	public void testString_from_ipAddress() {

+		FunctionArgumentAttributeValue attrObj1 = null;

+		FunctionArgumentAttributeValue attrObjV6 = null;

+		FunctionArgumentAttributeValue attrStringBadType = null;

+		String objValueString = "123.145.255.255";

+		String objValueStringV6 = "[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]";

+		try {

+			attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_IPADDRESS.createAttributeValue(objValueString));

+			attrObjV6 = new FunctionArgumentAttributeValue(DataTypes.DT_IPADDRESS.createAttributeValue(objValueStringV6));

+			

+			attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));

+

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+		

+		FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_IPADDRESS;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_STRING_FROM_IPADDRESS, fd.getId());

+		assertEquals(DataTypes.DT_IPADDRESS.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(1), fd.getNumArgs());

+		

+		// test normal V4

+		arguments.clear();

+		arguments.add(attrObj1);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(objValueString, res.getValue().getValue());

+		

+		// test normal V6

+		arguments.clear();

+		arguments.add(attrObjV6);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(objValueStringV6.toLowerCase(), res.getValue().getValue());

+		

+		// bad arg type

+		arguments.clear();

+		arguments.add(attrStringBadType);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-from-ipAddress Expected data type 'ipAddress' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+	}

+	

+	

+	

+	

+	

+	

+	

+	

+	

+	

+	/**

+	 * RFC2396DomainName

+	 */

+	@Test

+	public void testRFC2396DomainName_from_string() {

+		FunctionArgumentAttributeValue attrString1 = null;

+		FunctionArgumentAttributeValue attrString2 = null;

+		FunctionArgumentAttributeValue attrStringMinusPort = null;

+		FunctionArgumentAttributeValue attrStringPortMinus = null;

+		FunctionArgumentAttributeValue attrStringPortPort = null;

+		FunctionArgumentAttributeValue attrStringNoPort = null;

+		FunctionArgumentAttributeValue attrStringBadPort = null;

+		FunctionArgumentAttributeValue attrStringTooManyPorts = null;

+	

+		FunctionArgumentAttributeValue attrStringBadValue = null;

+		FunctionArgumentAttributeValue attrStringBadType = null;

+		try {

+			attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("host"));

+			attrString2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("host.host"));

+		

+			attrStringMinusPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("host.host:-123"));

+			attrStringPortMinus = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("host.host:123-"));

+			attrStringPortPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("host.host:1234567-432"));

+			attrStringNoPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("host.host:"));

+			attrStringBadPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("host.host:12.34"));

+			attrStringTooManyPorts = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("host.host:-123-456"));

+		

+			attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value"));

+			attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));

+

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+		

+		FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_DNSNAME_FROM_STRING;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_DNSNAME_FROM_STRING, fd.getId());

+		assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_DNSNAME.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(1), fd.getNumArgs());

+		

+		// test normal

+		arguments.clear();

+		arguments.add(attrString1);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		RFC2396DomainName resValue = (RFC2396DomainName)res.getValue().getValue();

+		assertEquals(new RFC2396DomainName("host", null), resValue);

+		

+		arguments.clear();

+		arguments.add(attrString2);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (RFC2396DomainName)res.getValue().getValue();

+		assertEquals(new RFC2396DomainName("host.host", null), resValue);

+		

+

+		// portrange (-port, port-, port-port)

+		arguments.clear();

+		arguments.add(attrStringMinusPort);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (RFC2396DomainName)res.getValue().getValue();

+		try {

+			assertEquals(new RFC2396DomainName("host.host", PortRange.newInstance("-123")), resValue);

+		} catch (ParseException e) {

+			fail("port error e="+e);

+		}

+		

+		arguments.clear();

+		arguments.add(attrStringPortMinus);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (RFC2396DomainName)res.getValue().getValue();

+		try {

+			assertEquals(new RFC2396DomainName("host.host", PortRange.newInstance("123-")), resValue);

+		} catch (ParseException e) {

+			fail("port error e="+e);

+		}

+		

+		arguments.clear();

+		arguments.add(attrStringPortPort);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (RFC2396DomainName)res.getValue().getValue();

+		try {

+			assertEquals(new RFC2396DomainName("host.host", PortRange.newInstance("1234567-432")), resValue);

+		} catch (ParseException e) {

+			fail("port error e="+e);

+		}

+		

+		// ":" without port

+		arguments.clear();

+		arguments.add(attrStringNoPort);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dnsName-from-string Invalid RFC 2396 port range \"host.host:\": no port numbers", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// bad port number

+		arguments.clear();

+		arguments.add(attrStringBadPort);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dnsName-from-string Invalid RFC 2396 port range \"12.34\"", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// bad port range

+		arguments.clear();

+		arguments.add(attrStringTooManyPorts);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dnsName-from-string Invalid RFC 2396 port range \"-123-456\"", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// bad value

+		arguments.clear();

+		arguments.add(attrStringBadValue);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dnsName-from-string Invalid RFC 2396 host name \"not valid obj value\"", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// bad arg type

+		arguments.clear();

+		arguments.add(attrStringBadType);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:dnsName-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+	}

+

+	@Test

+	public void testString_from_dnsName() {

+		FunctionArgumentAttributeValue attrObj1 = null;

+		FunctionArgumentAttributeValue attrStringBadType = null;

+		String objValueString = "someName.com";

+		try {

+			attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_DNSNAME.createAttributeValue(objValueString));

+			attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));

+

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+		

+		FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_DNSNAME;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_STRING_FROM_DNSNAME, fd.getId());

+		assertEquals(DataTypes.DT_DNSNAME.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(1), fd.getNumArgs());

+		

+		// test normal

+		arguments.clear();

+		arguments.add(attrObj1);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(objValueString, res.getValue().getValue());

+		

+		// bad arg type

+		arguments.clear();

+		arguments.add(attrStringBadType);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-from-dnsName Expected data type 'dnsName' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+	}

+	

+	

+	

+	

+	

+	

+	

+}

diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringEqualIgnoreCaseTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringEqualIgnoreCaseTest.java
new file mode 100755
index 0000000..81fc048
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringEqualIgnoreCaseTest.java
@@ -0,0 +1,119 @@
+/*

+ *                        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.std.functions;

+

+import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.assertFalse;

+import static org.junit.Assert.assertTrue;

+import static org.junit.Assert.fail;

+

+import java.util.ArrayList;

+import java.util.List;

+

+import org.junit.Test;

+

+import com.att.research.xacml.api.XACML3;

+import com.att.research.xacml.std.datatypes.DataTypes;

+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue;

+import com.att.research.xacmlatt.pdp.std.StdFunctions;

+

+/**

+ * Only one function to test here.  Code copy/pasted from FunctionDefinitionEqualityTest

+ * 

+ * TO RUN - use jUnit

+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test

+ * 

+ * In the first implementation of XACML we had separate files for each XACML Function.

+ * This release combines multiple Functions in fewer files to minimize code duplication.

+ * This file supports the following XACML codes:

+ * 		string-equal-ignore-case

+ * 

+ * @author glenngriffin

+ *

+ */

+public class FunctionDefinitionStringEqualIgnoreCaseTest {

+

+	/*

+	 * variables useful in the following tests

+	 */

+	List<FunctionArgument> arguments = new ArrayList<FunctionArgument>();

+	

+	FunctionArgumentAttributeValue stringAttr1 = null;

+	FunctionArgumentAttributeValue stringAttr2 = null;

+	FunctionArgumentAttributeValue stringAttr3 = null;

+	FunctionArgumentAttributeValue stringAttr4 = null;

+	

+	FunctionArgumentAttributeValue intAttr1 = null;

+

+	public FunctionDefinitionStringEqualIgnoreCaseTest() {

+		try {

+			stringAttr1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("abc"));

+			stringAttr2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("abc"));

+			stringAttr3 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("ABC"));

+			stringAttr4 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("def"));

+			intAttr1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1));

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+	}

+	

+	

+	/**

+	 * String match even when Case is different

+	 */

+	@Test

+	public void testFunctionDefinitionStringEqualIgnoreCase() {

+		

+		FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_STRING_EQUAL_IGNORE_CASE;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_STRING_EQUAL_IGNORE_CASE, fd.getId());

+		assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+

+		

+		// test normal equals and non-equals

+		// check "abc" with "abc"

+		arguments.add(stringAttr1);

+		arguments.add(stringAttr2);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		// check "abc" with "ABC" (should be same)

+		arguments.clear();

+		arguments.add(stringAttr1);

+		arguments.add(stringAttr3);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// test bad args data types?  Not needed?

+		arguments.clear();

+		arguments.add(stringAttr1);

+		arguments.add(intAttr1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+

+		

+//TODO - null in either first or 2nd arg => NullPointerException

+	}

+

+}

diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctionsTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctionsTest.java
new file mode 100755
index 0000000..7a3b1c5
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctionsTest.java
@@ -0,0 +1,1477 @@
+package com.att.research.xacmlatt.pdp.std.functions;

+

+import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.assertFalse;

+import static org.junit.Assert.assertTrue;

+import static org.junit.Assert.fail;

+

+import java.net.URI;

+import java.util.ArrayList;

+import java.util.List;

+

+import org.junit.Test;

+

+import com.att.research.xacml.api.XACML3;

+import com.att.research.xacml.std.datatypes.DataTypes;

+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue;

+import com.att.research.xacmlatt.pdp.std.StdFunctions;

+

+/**

+ * Test of PDP Functions (See XACML core spec section A.3)

+ * 

+ * TO RUN - use jUnit

+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test

+ * 

+ * @author glenngriffin

+ *

+ */

+public class FunctionDefinitionStringFunctionsTest {

+

+

+	/*

+	 * variables useful in the following tests

+	 */

+	List<FunctionArgument> arguments = new ArrayList<FunctionArgument>();

+	

+	ExpressionResult res;

+

+	

+	@Test

+	public void testConcatenate() {

+		String v1 = new String("abc");

+		String v2 = new String("def");

+		

+		FunctionArgumentAttributeValue attrV1 = null;

+		FunctionArgumentAttributeValue attrV2 = null;

+		FunctionArgumentAttributeValue attrNull = null;

+		FunctionArgumentAttributeValue attrBlank = null;

+		FunctionArgumentAttributeValue attrInteger = null;

+		try {

+			attrV1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v1));

+			attrV2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v2));

+			attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(""));

+			attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(null));

+			attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234));

+		} catch (Exception e) {

+			fail("creating attributes e="+ e);

+		}

+		

+		FunctionDefinitionStringFunctions<?,?> fd = (FunctionDefinitionStringFunctions<?,?>) StdFunctions.FD_STRING_CONCATENATE;

+

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_STRING_CONCATENATE, fd.getId());

+		assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+

+		

+		// match

+		arguments.clear();

+		arguments.add(attrV1);

+		arguments.add(attrV2);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(String.class, res.getValue().getValue().getClass());

+		String resValue = (String)res.getValue().getValue();

+		assertEquals(v1 + v2, resValue);

+		

+		// empty non-null first arg

+		arguments.clear();

+		arguments.add(attrBlank);

+		arguments.add(attrV2);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(String.class, res.getValue().getValue().getClass());

+		resValue = (String)res.getValue().getValue();

+		assertEquals(v2, resValue);

+		

+		// empty non-null second arg

+		arguments.clear();

+		arguments.add(attrV1);

+		arguments.add(attrBlank);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(String.class, res.getValue().getValue().getClass());

+		resValue = (String)res.getValue().getValue();

+		assertEquals(v1, resValue);

+		

+		// two blanks

+		arguments.clear();

+		arguments.add(attrBlank);

+		arguments.add(attrBlank);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(String.class, res.getValue().getValue().getClass());

+		resValue = (String)res.getValue().getValue();

+		assertEquals("", resValue);

+		

+		// null firat arg

+		arguments.clear();

+		arguments.add(attrNull);

+		arguments.add(attrBlank);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-concatenate Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+			

+		

+		// null second arg

+		arguments.clear();

+		arguments.add(attrV1);

+		arguments.add(attrNull);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-concatenate Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// bad arg type

+		arguments.clear();

+		arguments.add(attrInteger);

+		arguments.add(attrV2);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-concatenate Expected data type 'string' saw 'integer'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// null second arg

+		arguments.clear();

+		arguments.add(attrV1);

+		arguments.add(attrNull);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-concatenate Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+	}

+	

+	

+	

+	@Test

+	public void testStringStartsWith() {

+		String v1 = new String("abc");

+		String bigger = new String("abc some string");

+		String biggerNoMatch = new String(" abc some string");

+		String caps = new String("AbC");

+	

+		FunctionArgumentAttributeValue attrV1 = null;

+		FunctionArgumentAttributeValue attrBigger = null;

+		FunctionArgumentAttributeValue attrBiggerNoMatch = null;

+		FunctionArgumentAttributeValue attrCaps = null;

+		FunctionArgumentAttributeValue attrNull = null;

+		FunctionArgumentAttributeValue attrBlank = null;

+		FunctionArgumentAttributeValue attrInteger = null;

+		try {

+			attrV1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v1));

+			attrBigger = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(bigger));

+			attrBiggerNoMatch = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(biggerNoMatch));

+			attrCaps = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(caps));

+			attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(""));

+			attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(null));

+			attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234));

+		} catch (Exception e) {

+			fail("creating attributes e="+ e);

+		}

+		

+		FunctionDefinitionStringFunctions<?,?> fd = (FunctionDefinitionStringFunctions<?,?>) StdFunctions.FD_STRING_STARTS_WITH;

+

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_STRING_STARTS_WITH, fd.getId());

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+

+		

+		// match

+		arguments.clear();

+		arguments.add(attrV1);

+		arguments.add(attrBigger);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertEquals(true, resValue);

+		

+		// no match

+		arguments.clear();

+		arguments.add(attrV1);

+		arguments.add(attrBiggerNoMatch);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(false, resValue);

+		

+		// caps no match

+		arguments.clear();

+		arguments.add(attrCaps);

+		arguments.add(attrBigger);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(false, resValue);

+		

+		// bigger on the inside

+		arguments.clear();

+		arguments.add(attrBigger);

+		arguments.add(attrV1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(false, resValue);

+		

+		// empty non-null first arg

+		arguments.clear();

+		arguments.add(attrBlank);

+		arguments.add(attrBigger);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(true, resValue);

+		

+		// empty non-null second arg

+		arguments.clear();

+		arguments.add(attrV1);

+		arguments.add(attrBlank);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(false, resValue);

+		

+		// two blanks

+		arguments.clear();

+		arguments.add(attrBlank);

+		arguments.add(attrBlank);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(true, resValue);

+		

+		// null firat arg

+		arguments.clear();

+		arguments.add(attrNull);

+		arguments.add(attrBlank);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-starts-with Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// null second arg

+		arguments.clear();

+		arguments.add(attrV1);

+		arguments.add(attrNull);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-starts-with Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+			

+		// illegal arg type

+		arguments.clear();

+		arguments.add(attrInteger);

+		arguments.add(attrBigger);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-starts-with Expected data type 'string' saw 'integer'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+			

+	}

+	

+	

+	@Test

+	public void testAnyuriStartsWith() {

+

+	

+		FunctionArgumentAttributeValue attrV1 = null;

+		FunctionArgumentAttributeValue attrBigger = null;

+		FunctionArgumentAttributeValue attrBiggerNoMatch = null;

+		FunctionArgumentAttributeValue attrCaps = null;

+		FunctionArgumentAttributeValue attrBigString = null;

+		FunctionArgumentAttributeValue attrNull = null;

+		FunctionArgumentAttributeValue attrBlankString = null;

+		FunctionArgumentAttributeValue attrBlankURI = null;

+		FunctionArgumentAttributeValue attrInteger = null;

+		try {

+			String v1 = new String("abc");

+			URI bigger = new URI("abc.some.string");

+			URI biggerNoMatch = new URI("Zabc.some.string");

+			String caps = new String("AbC");

+			String bigString = "thisIsSomeReallyBigStringToMatch";

+			

+			attrV1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v1));

+			attrBigger = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(bigger));

+			attrBiggerNoMatch = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(biggerNoMatch));

+			attrCaps = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(caps));

+			attrBigString = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(bigString));

+			attrBlankString = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(""));

+			attrBlankURI = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(""));

+			attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(null));

+			attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234));

+		} catch (Exception e) {

+			fail("creating attributes e="+ e);

+		}

+		

+		FunctionDefinitionStringFunctions<?,?> fd = (FunctionDefinitionStringFunctions<?,?>) StdFunctions.FD_ANYURI_STARTS_WITH;

+

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_ANYURI_STARTS_WITH, fd.getId());

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+

+		

+		// match

+		arguments.clear();

+		arguments.add(attrV1);

+		arguments.add(attrBigger);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertEquals(true, resValue);

+		

+		// no match

+		arguments.clear();

+		arguments.add(attrV1);

+		arguments.add(attrBiggerNoMatch);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(false, resValue);

+		

+		// caps no match

+		arguments.clear();

+		arguments.add(attrCaps);

+		arguments.add(attrBigger);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(false, resValue);

+		

+		// bigger on the inside

+		arguments.clear();

+		arguments.add(attrBigString);

+		arguments.add(attrBigger);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(false, resValue);

+		

+		// empty non-null first arg

+		arguments.clear();

+		arguments.add(attrBlankString);

+		arguments.add(attrBigger);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(true, resValue);

+		

+		// empty non-null second arg

+		arguments.clear();

+		arguments.add(attrV1);

+		arguments.add(attrBlankURI);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(false, resValue);

+		

+		

+		// two blanks

+		arguments.clear();

+		arguments.add(attrBlankString);

+		arguments.add(attrBlankURI);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(true, resValue);

+		

+		// arguments reversed

+		arguments.clear();

+		arguments.add(attrBigger);

+		arguments.add(attrV1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:anyURI-starts-with Expected data type 'string' saw 'anyURI'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		

+		// null firat arg

+		arguments.clear();

+		arguments.add(attrNull);

+		arguments.add(attrBlankURI);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:anyURI-starts-with Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// null second arg

+		arguments.clear();

+		arguments.add(attrV1);

+		arguments.add(attrNull);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:anyURI-starts-with Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+			

+		// illegal arg type

+		arguments.clear();

+		arguments.add(attrInteger);

+		arguments.add(attrBigger);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:anyURI-starts-with Expected data type 'string' saw 'integer'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+			

+	}

+

+	

+	

+	

+	@Test

+	public void testStringEndsWith() {

+		String v1 = new String("abc");

+		String bigger = new String("abc some string abc");

+		String biggerNoMatch = new String(" abc some string abc ");

+		String caps = new String("AbC");

+	

+		FunctionArgumentAttributeValue attrV1 = null;

+		FunctionArgumentAttributeValue attrBigger = null;

+		FunctionArgumentAttributeValue attrBiggerNoMatch = null;

+		FunctionArgumentAttributeValue attrCaps = null;

+		FunctionArgumentAttributeValue attrNull = null;

+		FunctionArgumentAttributeValue attrBlank = null;

+		FunctionArgumentAttributeValue attrInteger = null;

+		try {

+			attrV1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v1));

+			attrBigger = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(bigger));

+			attrBiggerNoMatch = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(biggerNoMatch));

+			attrCaps = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(caps));

+			attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(""));

+			attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(null));

+			attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234));

+		} catch (Exception e) {

+			fail("creating attributes e="+ e);

+		}

+		

+		FunctionDefinitionStringFunctions<?,?> fd = (FunctionDefinitionStringFunctions<?,?>) StdFunctions.FD_STRING_ENDS_WITH;

+

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_STRING_ENDS_WITH, fd.getId());

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+

+		

+		// match

+		arguments.clear();

+		arguments.add(attrV1);

+		arguments.add(attrBigger);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertEquals(true, resValue);

+		

+		// no match

+		arguments.clear();

+		arguments.add(attrV1);

+		arguments.add(attrBiggerNoMatch);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(false, resValue);

+		

+		// caps no match

+		arguments.clear();

+		arguments.add(attrCaps);

+		arguments.add(attrBigger);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(false, resValue);

+		

+		// bigger on the inside

+		arguments.clear();

+		arguments.add(attrBigger);

+		arguments.add(attrV1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(false, resValue);

+		

+		// empty non-null first arg

+		arguments.clear();

+		arguments.add(attrBlank);

+		arguments.add(attrBigger);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(true, resValue);

+		

+		// empty non-null second arg

+		arguments.clear();

+		arguments.add(attrV1);

+		arguments.add(attrBlank);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(false, resValue);

+		

+		// two blanks

+		arguments.clear();

+		arguments.add(attrBlank);

+		arguments.add(attrBlank);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(true, resValue);

+		

+		// null firat arg

+		arguments.clear();

+		arguments.add(attrNull);

+		arguments.add(attrBlank);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-ends-with Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// null second arg

+		arguments.clear();

+		arguments.add(attrV1);

+		arguments.add(attrNull);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-ends-with Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+			

+		// illegal arg type

+		arguments.clear();

+		arguments.add(attrInteger);

+		arguments.add(attrBigger);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-ends-with Expected data type 'string' saw 'integer'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+			

+	}

+	

+	

+	@Test

+	public void testAnyuriEndsWith() {

+

+	

+		FunctionArgumentAttributeValue attrV1 = null;

+		FunctionArgumentAttributeValue attrBigger = null;

+		FunctionArgumentAttributeValue attrBiggerNoMatch = null;

+		FunctionArgumentAttributeValue attrCaps = null;

+		FunctionArgumentAttributeValue attrBigString = null;

+		FunctionArgumentAttributeValue attrNull = null;

+		FunctionArgumentAttributeValue attrBlankString = null;

+		FunctionArgumentAttributeValue attrBlankURI = null;

+		FunctionArgumentAttributeValue attrInteger = null;

+		try {

+			String v1 = new String("abc");

+			URI bigger = new URI("abc.some.stringabc");

+			URI biggerNoMatch = new URI("Zabc.some.stringabcZ");

+			String caps = new String("AbC");

+			String bigString = "thisIsSomeReallyBigStringToMatch";

+			

+			attrV1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v1));

+			attrBigger = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(bigger));

+			attrBiggerNoMatch = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(biggerNoMatch));

+			attrCaps = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(caps));

+			attrBigString = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(bigString));

+			attrBlankString = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(""));

+			attrBlankURI = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(""));

+			attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(null));

+			attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234));

+		} catch (Exception e) {

+			fail("creating attributes e="+ e);

+		}

+		

+		FunctionDefinitionStringFunctions<?,?> fd = (FunctionDefinitionStringFunctions<?,?>) StdFunctions.FD_ANYURI_ENDS_WITH;

+

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_ANYURI_ENDS_WITH, fd.getId());

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+

+		

+		// match

+		arguments.clear();

+		arguments.add(attrV1);

+		arguments.add(attrBigger);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertEquals(true, resValue);

+		

+		// no match

+		arguments.clear();

+		arguments.add(attrV1);

+		arguments.add(attrBiggerNoMatch);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(false, resValue);

+		

+		// caps no match

+		arguments.clear();

+		arguments.add(attrCaps);

+		arguments.add(attrBigger);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(false, resValue);

+		

+		// bigger on the inside

+		arguments.clear();

+		arguments.add(attrBigString);

+		arguments.add(attrBigger);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(false, resValue);

+		

+		// empty non-null first arg

+		arguments.clear();

+		arguments.add(attrBlankString);

+		arguments.add(attrBigger);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(true, resValue);

+		

+		// empty non-null second arg

+		arguments.clear();

+		arguments.add(attrV1);

+		arguments.add(attrBlankURI);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(false, resValue);

+		

+		

+		// two blanks

+		arguments.clear();

+		arguments.add(attrBlankString);

+		arguments.add(attrBlankURI);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(true, resValue);

+		

+		// arguments reversed

+		arguments.clear();

+		arguments.add(attrBigger);

+		arguments.add(attrV1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:anyURI-ends-with Expected data type 'string' saw 'anyURI'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		

+		// null firat arg

+		arguments.clear();

+		arguments.add(attrNull);

+		arguments.add(attrBlankURI);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:anyURI-ends-with Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// null second arg

+		arguments.clear();

+		arguments.add(attrV1);

+		arguments.add(attrNull);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:anyURI-ends-with Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// illegal arg type

+		arguments.clear();

+		arguments.add(attrInteger);

+		arguments.add(attrBigger);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:anyURI-ends-with Expected data type 'string' saw 'integer'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+			

+	}

+	

+	

+	

+	

+	@Test

+	public void testStringSubstring() {

+		String bigString = new String("abc some string abc");

+

+		FunctionArgumentAttributeValue attrBigString = null;

+		FunctionArgumentAttributeValue attrNull = null;

+		FunctionArgumentAttributeValue attrBlank = null;

+		FunctionArgumentAttributeValue attrDouble = null;

+	

+		FunctionArgumentAttributeValue attrInteger0 = null;

+		FunctionArgumentAttributeValue attrInteger1 = null;

+		FunctionArgumentAttributeValue attrIntegerM1 = null;

+		FunctionArgumentAttributeValue attrInteger8 = null;

+		FunctionArgumentAttributeValue attrInteger19 = null;

+		FunctionArgumentAttributeValue attrInteger20 = null;

+

+		

+		

+		try {

+			attrBigString = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(bigString));

+			attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(""));

+			attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(null));

+			attrInteger0 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(0));

+			attrInteger1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1));

+			attrIntegerM1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(-1));

+			attrInteger8 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(8));

+			attrInteger19 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(19));

+			attrInteger20 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(20));

+			attrDouble = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(123.4));

+		} catch (Exception e) {

+			fail("creating attributes e="+ e);

+		}

+		

+		FunctionDefinitionStringFunctions<?,?> fd = (FunctionDefinitionStringFunctions<?,?>) StdFunctions.FD_STRING_SUBSTRING;

+

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_STRING_SUBSTRING, fd.getId());

+		assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+

+		

+		// match

+		arguments.clear();

+		arguments.add(attrBigString);

+		arguments.add(attrInteger1);

+		arguments.add(attrInteger8);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(String.class, res.getValue().getValue().getClass());

+		String resValue = (String)res.getValue().getValue();

+		assertEquals("bc some", resValue);

+		

+		// edge: start

+		arguments.clear();

+		arguments.add(attrBigString);

+		arguments.add(attrInteger0);

+		arguments.add(attrInteger8);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(String.class, res.getValue().getValue().getClass());

+		resValue = (String)res.getValue().getValue();

+		assertEquals("abc some", resValue);

+		

+		// edge: end

+		arguments.clear();

+		arguments.add(attrBigString);

+		arguments.add(attrInteger8);

+		arguments.add(attrInteger19);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(String.class, res.getValue().getValue().getClass());

+		resValue = (String)res.getValue().getValue();

+		assertEquals(" string abc", resValue);

+		

+		// from index to end of string

+		arguments.clear();

+		arguments.add(attrBigString);

+		arguments.add(attrInteger8);

+		arguments.add(attrIntegerM1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(String.class, res.getValue().getValue().getClass());

+		resValue = (String)res.getValue().getValue();

+		assertEquals(" string abc", resValue);

+		

+		// first index too low

+		arguments.clear();

+		arguments.add(attrBigString);

+		arguments.add(attrIntegerM1);

+		arguments.add(attrInteger8);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-substring Start point '-1' out of range 0-19 for string='abc some string abc'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+			

+		

+		// second index too big

+		arguments.clear();

+		arguments.add(attrBigString);

+		arguments.add(attrInteger8);

+		arguments.add(attrInteger20);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-substring End point '20' out of range 0-19 for string='abc some string abc'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+			

+		// indexes reversed

+		arguments.clear();

+		arguments.add(attrBigString);

+		arguments.add(attrInteger8);

+		arguments.add(attrInteger1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-substring End point '1' less than start point 'null' for string='abc some string abc'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// indexes the same

+		arguments.clear();

+		arguments.add(attrBigString);

+		arguments.add(attrInteger8);

+		arguments.add(attrInteger8);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(String.class, res.getValue().getValue().getClass());

+		resValue = (String)res.getValue().getValue();

+		assertEquals("", resValue);

+		

+		// blank string with indexes both 0

+		arguments.clear();

+		arguments.add(attrBlank);

+		arguments.add(attrInteger0);

+		arguments.add(attrInteger0);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(String.class, res.getValue().getValue().getClass());

+		resValue = (String)res.getValue().getValue();

+		assertEquals("", resValue);

+		

+		// non-string first attribute

+		arguments.clear();

+		arguments.add(attrDouble);

+		arguments.add(attrInteger8);

+		arguments.add(attrInteger1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-substring Expected data type 'string' saw 'double'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// non-integer 2nd attr

+		arguments.clear();

+		arguments.add(attrBigString);

+		arguments.add(attrDouble);

+		arguments.add(attrInteger1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-substring Expected data type 'integer' saw 'double'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// non-integer 3rd attr

+		arguments.clear();

+		arguments.add(attrBigString);

+		arguments.add(attrInteger8);

+		arguments.add(attrDouble);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-substring Expected data type 'integer' saw 'double'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// 4 args

+		arguments.clear();

+		arguments.add(attrBigString);

+		arguments.add(attrInteger8);

+		arguments.add(attrInteger1);

+		arguments.add(attrInteger1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-substring Expected 3 arguments, got 4", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// 2 args

+		arguments.clear();

+		arguments.add(attrBigString);

+		arguments.add(attrInteger8);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-substring Expected 3 arguments, got 2", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// null 1st arg

+		arguments.clear();

+		arguments.add(attrNull);

+		arguments.add(attrInteger8);

+		arguments.add(attrInteger1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-substring Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		

+		// null 2nd arg

+		arguments.clear();

+		arguments.add(attrBigString);

+		arguments.add(attrNull);

+		arguments.add(attrInteger1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-substring Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+

+	}

+	

+	

+	

+	

+	@Test

+	public void testAnyURISubstring() {

+		String bigString = new String("http://company.com:8080/this/is/some/long/uri");

+

+		FunctionArgumentAttributeValue attrURI = null;

+		FunctionArgumentAttributeValue attrNull = null;

+		FunctionArgumentAttributeValue attrBlank = null;

+		FunctionArgumentAttributeValue attrDouble = null;

+	

+		FunctionArgumentAttributeValue attrInteger0 = null;

+		FunctionArgumentAttributeValue attrInteger1 = null;

+		FunctionArgumentAttributeValue attrIntegerM1 = null;

+		FunctionArgumentAttributeValue attrInteger8 = null;

+		FunctionArgumentAttributeValue attrInteger45 = null;

+		FunctionArgumentAttributeValue attrInteger46 = null;

+

+		

+		

+		try {

+			attrURI = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(bigString));

+			attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(""));

+			attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(null));

+			attrInteger0 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(0));

+			attrInteger1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1));

+			attrIntegerM1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(-1));

+			attrInteger8 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(8));

+			attrInteger45 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(45));

+			attrInteger46 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(46));

+			attrDouble = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(123.4));

+		} catch (Exception e) {

+			fail("creating attributes e="+ e);

+		}

+		

+		FunctionDefinitionStringFunctions<?,?> fd = (FunctionDefinitionStringFunctions<?,?>) StdFunctions.FD_ANYURI_SUBSTRING;

+

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_ANYURI_SUBSTRING, fd.getId());

+		assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+

+		

+		// match

+		arguments.clear();

+		arguments.add(attrURI);

+		arguments.add(attrInteger1);

+		arguments.add(attrInteger8);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(String.class, res.getValue().getValue().getClass());

+		String resValue = (String)res.getValue().getValue();

+		assertEquals("ttp://c", resValue);

+		

+		// edge: start

+		arguments.clear();

+		arguments.add(attrURI);

+		arguments.add(attrInteger0);

+		arguments.add(attrInteger8);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(String.class, res.getValue().getValue().getClass());

+		resValue = (String)res.getValue().getValue();

+		assertEquals("http://c", resValue);

+

+		// edge: end

+		arguments.clear();

+		arguments.add(attrURI);

+		arguments.add(attrInteger8);

+		arguments.add(attrInteger45);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(String.class, res.getValue().getValue().getClass());

+		resValue = (String)res.getValue().getValue();

+		assertEquals("ompany.com:8080/this/is/some/long/uri", resValue);

+		

+		// from index to end of string

+		arguments.clear();

+		arguments.add(attrURI);

+		arguments.add(attrInteger8);

+		arguments.add(attrIntegerM1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(String.class, res.getValue().getValue().getClass());

+		resValue = (String)res.getValue().getValue();

+		assertEquals("ompany.com:8080/this/is/some/long/uri", resValue);

+		

+		// first index too low

+		arguments.clear();

+		arguments.add(attrURI);

+		arguments.add(attrIntegerM1);

+		arguments.add(attrInteger8);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:anyURI-substring Start point '-1' out of range 0-45 for string='http://company.com:8080/this/is/some/long/uri'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+			

+		

+		// second index too big

+		arguments.clear();

+		arguments.add(attrURI);

+		arguments.add(attrInteger8);

+		arguments.add(attrInteger46);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:anyURI-substring End point '46' out of range 0-45 for string='http://company.com:8080/this/is/some/long/uri'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+			

+		// indexes reversed

+		arguments.clear();

+		arguments.add(attrURI);

+		arguments.add(attrInteger8);

+		arguments.add(attrInteger1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:anyURI-substring End point '1' less than start point 'null' for string='http://company.com:8080/this/is/some/long/uri'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// indexes the same

+		arguments.clear();

+		arguments.add(attrURI);

+		arguments.add(attrInteger8);

+		arguments.add(attrInteger8);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(String.class, res.getValue().getValue().getClass());

+		resValue = (String)res.getValue().getValue();

+		assertEquals("", resValue);

+		

+		// blank string with indexes both 0

+		arguments.clear();

+		arguments.add(attrBlank);

+		arguments.add(attrInteger0);

+		arguments.add(attrInteger0);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(String.class, res.getValue().getValue().getClass());

+		resValue = (String)res.getValue().getValue();

+		assertEquals("", resValue);

+		

+		// non-string first attribute

+		arguments.clear();

+		arguments.add(attrDouble);

+		arguments.add(attrInteger8);

+		arguments.add(attrInteger1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:anyURI-substring Expected data type 'anyURI' saw 'double'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// non-integer 2nd attr

+		arguments.clear();

+		arguments.add(attrURI);

+		arguments.add(attrDouble);

+		arguments.add(attrInteger1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:anyURI-substring Expected data type 'integer' saw 'double'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// non-integer 3rd attr

+		arguments.clear();

+		arguments.add(attrURI);

+		arguments.add(attrInteger8);

+		arguments.add(attrDouble);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:anyURI-substring Expected data type 'integer' saw 'double'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// 4 args

+		arguments.clear();

+		arguments.add(attrURI);

+		arguments.add(attrInteger8);

+		arguments.add(attrInteger1);

+		arguments.add(attrInteger1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:anyURI-substring Expected 3 arguments, got 4", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// 2 args

+		arguments.clear();

+		arguments.add(attrURI);

+		arguments.add(attrInteger8);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:anyURI-substring Expected 3 arguments, got 2", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// null 1st arg

+		arguments.clear();

+		arguments.add(attrNull);

+		arguments.add(attrInteger8);

+		arguments.add(attrInteger1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:anyURI-substring Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		

+		// null 2nd arg

+		arguments.clear();

+		arguments.add(attrURI);

+		arguments.add(attrNull);

+		arguments.add(attrInteger1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:anyURI-substring Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+	}

+	

+	

+	

+	

+	

+	

+	

+	

+	

+	

+	

+	

+	

+

+	

+	

+	

+	

+	

+	

+	

+	@Test

+	public void testStringContains() {

+		String v1 = new String("abc");

+		String bigger = new String("abc some string abc");

+		String biggerNoMatch = new String(" abc some string abc ");

+		String caps = new String("AbC");

+	

+		FunctionArgumentAttributeValue attrV1 = null;

+		FunctionArgumentAttributeValue attrBigger = null;

+		FunctionArgumentAttributeValue attrBiggerNoMatch = null;

+		FunctionArgumentAttributeValue attrCaps = null;

+		FunctionArgumentAttributeValue attrNull = null;

+		FunctionArgumentAttributeValue attrBlank = null;

+		FunctionArgumentAttributeValue attrInteger = null;

+		try {

+			attrV1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v1));

+			attrBigger = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(bigger));

+			attrBiggerNoMatch = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(biggerNoMatch));

+			attrCaps = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(caps));

+			attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(""));

+			attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(null));

+			attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234));

+		} catch (Exception e) {

+			fail("creating attributes e="+ e);

+		}

+		

+		FunctionDefinitionStringFunctions<?,?> fd = (FunctionDefinitionStringFunctions<?,?>) StdFunctions.FD_STRING_CONTAINS;

+

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_STRING_CONTAINS, fd.getId());

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+

+		

+		// match

+		arguments.clear();

+		arguments.add(attrV1);

+		arguments.add(attrBigger);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertEquals(true, resValue);

+		

+		// no match

+		arguments.clear();

+		arguments.add(attrBiggerNoMatch);

+		arguments.add(attrV1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(false, resValue);

+		

+		// caps no match

+		arguments.clear();

+		arguments.add(attrCaps);

+		arguments.add(attrBigger);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(false, resValue);

+		

+		// bigger on the inside

+		arguments.clear();

+		arguments.add(attrBigger);

+		arguments.add(attrV1);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(false, resValue);

+		

+		// empty non-null first arg

+		arguments.clear();

+		arguments.add(attrBlank);

+		arguments.add(attrBigger);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(true, resValue);

+		

+		// empty non-null second arg

+		arguments.clear();

+		arguments.add(attrV1);

+		arguments.add(attrBlank);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(false, resValue);

+		

+		// two blanks

+		arguments.clear();

+		arguments.add(attrBlank);

+		arguments.add(attrBlank);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(true, resValue);

+		

+		// null firat arg

+		arguments.clear();

+		arguments.add(attrNull);

+		arguments.add(attrBlank);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-contains Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// null second arg

+		arguments.clear();

+		arguments.add(attrV1);

+		arguments.add(attrNull);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-contains Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+			

+		// illegal arg type

+		arguments.clear();

+		arguments.add(attrInteger);

+		arguments.add(attrBigger);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:string-contains Expected data type 'string' saw 'integer'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+			

+	}

+	

+	

+	@Test

+	public void testAnyuriContains() {

+

+	

+		FunctionArgumentAttributeValue attrV1 = null;

+		FunctionArgumentAttributeValue attrBigger = null;

+		FunctionArgumentAttributeValue attrBiggerNoMatch = null;

+		FunctionArgumentAttributeValue attrCaps = null;

+		FunctionArgumentAttributeValue attrBigString = null;

+		FunctionArgumentAttributeValue attrNull = null;

+		FunctionArgumentAttributeValue attrBlankString = null;

+		FunctionArgumentAttributeValue attrBlankURI = null;

+		FunctionArgumentAttributeValue attrInteger = null;

+		try {

+			String v1 = new String("abc");

+			URI bigger = new URI("abc.some.stringabc");

+			URI biggerNoMatch = new URI("Zabc.some.stringabcZ");

+			String caps = new String("AbC");

+			String bigString = "thisIsSomeReallyBigStringToMatch";

+			

+			attrV1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v1));

+			attrBigger = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(bigger));

+			attrBiggerNoMatch = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(biggerNoMatch));

+			attrCaps = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(caps));

+			attrBigString = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(bigString));

+			attrBlankString = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(""));

+			attrBlankURI = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(""));

+			attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(null));

+			attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234));

+		} catch (Exception e) {

+			fail("creating attributes e="+ e);

+		}

+		

+		FunctionDefinitionStringFunctions<?,?> fd = (FunctionDefinitionStringFunctions<?,?>) StdFunctions.FD_ANYURI_CONTAINS;

+

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_ANYURI_CONTAINS, fd.getId());

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+

+		

+		// match

+		arguments.clear();

+		arguments.add(attrV1);

+		arguments.add(attrBigger);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertEquals(true, resValue);

+		

+		// no match

+		arguments.clear();

+		arguments.add(attrBigString);

+		arguments.add(attrBiggerNoMatch);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(false, resValue);

+		

+		// caps no match

+		arguments.clear();

+		arguments.add(attrCaps);

+		arguments.add(attrBigger);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(false, resValue);

+		

+		// bigger on the inside

+		arguments.clear();

+		arguments.add(attrBigString);

+		arguments.add(attrBigger);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(false, resValue);

+		

+		// empty non-null first arg

+		arguments.clear();

+		arguments.add(attrBlankString);

+		arguments.add(attrBigger);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(true, resValue);

+		

+		// empty non-null second arg

+		arguments.clear();

+		arguments.add(attrV1);

+		arguments.add(attrBlankURI);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(false, resValue);

+		

+		

+		// two blanks

+		arguments.clear();

+		arguments.add(attrBlankString);

+		arguments.add(attrBlankURI);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(Boolean.class, res.getValue().getValue().getClass());

+		resValue = (Boolean)res.getValue().getValue();

+		assertEquals(true, resValue);

+		

+		// arguments reversed

+		arguments.clear();

+		arguments.add(attrBigger);

+		arguments.add(attrV1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:anyURI-contains Expected data type 'string' saw 'anyURI'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		

+		// null firat arg

+		arguments.clear();

+		arguments.add(attrNull);

+		arguments.add(attrBlankURI);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:anyURI-contains Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// null second arg

+		arguments.clear();

+		arguments.add(attrV1);

+		arguments.add(attrNull);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:anyURI-contains Got null attribute", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// illegal arg type

+		arguments.clear();

+		arguments.add(attrInteger);

+		arguments.add(attrBigger);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:anyURI-contains Expected data type 'string' saw 'integer'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+			

+	}

+	

+	

+	

+}

diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalizeTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalizeTest.java
new file mode 100755
index 0000000..a09a696
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalizeTest.java
@@ -0,0 +1,98 @@
+package com.att.research.xacmlatt.pdp.std.functions;

+

+import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.assertFalse;

+import static org.junit.Assert.assertTrue;

+import static org.junit.Assert.fail;

+

+import java.util.ArrayList;

+import java.util.List;

+

+import org.junit.Test;

+

+import com.att.research.xacml.api.XACML3;

+import com.att.research.xacml.std.datatypes.DataTypes;

+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue;

+import com.att.research.xacmlatt.pdp.std.StdFunctions;

+

+/**

+ * Test of PDP Functions (See XACML core spec section A.3)

+ * 

+ * TO RUN - use jUnit

+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test

+ * 

+ * @author glenngriffin

+ *

+ */

+public class FunctionDefinitionStringNormalizeTest {

+	

+	/*

+	 * variables useful in the following tests

+	 */

+	List<FunctionArgument> arguments = new ArrayList<FunctionArgument>();

+	

+	@Test

+	public void testString_normalize_space() {

+		String initialString = "  First and last are whitespace 	";

+		FunctionArgumentAttributeValue attr1 = null;

+		try {

+			attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(initialString));

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+		

+		FunctionDefinitionStringNormalize fd = (FunctionDefinitionStringNormalize) StdFunctions.FD_STRING_NORMALIZE_SPACE;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_STRING_NORMALIZE_SPACE, fd.getId());

+		assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(1), fd.getNumArgs());

+		

+		

+		// test normal add

+		arguments.add(attr1);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		String resValue = (String)res.getValue().getValue();

+		assertEquals(initialString.length() - 4, resValue.length());

+		assertTrue(initialString.trim().equals(resValue));

+	}

+

+	

+	@Test

+	public void testString_normalize_to_lower_case() {

+		String initialString = "  First and last are whitespace 	";

+		FunctionArgumentAttributeValue attr1 = null;

+		try {

+			attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(initialString));

+		} catch (Exception e) {

+			fail("creating attribute e="+ e);

+		}

+		

+		FunctionDefinitionStringNormalize fd = (FunctionDefinitionStringNormalize) StdFunctions.FD_STRING_NORMALIZE_TO_LOWER_CASE;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_STRING_NORMALIZE_TO_LOWER_CASE, fd.getId());

+		assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(1), fd.getNumArgs());

+		

+		

+		// test normal add

+		arguments.add(attr1);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		String resValue = (String)res.getValue().getValue();

+		assertTrue(initialString.toLowerCase().equals(resValue));

+	}

+	

+}

diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionURIStringConcatenateTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionURIStringConcatenateTest.java
new file mode 100755
index 0000000..9da1f13
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionURIStringConcatenateTest.java
@@ -0,0 +1,165 @@
+package com.att.research.xacmlatt.pdp.std.functions;

+

+import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.assertFalse;

+import static org.junit.Assert.assertTrue;

+import static org.junit.Assert.fail;

+

+import java.net.URI;

+import java.util.ArrayList;

+import java.util.List;

+

+import org.junit.Test;

+

+import com.att.research.xacml.api.XACML2;

+import com.att.research.xacml.std.datatypes.DataTypes;

+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue;

+import com.att.research.xacmlatt.pdp.std.StdFunctions;

+

+/**

+ * Test of PDP Functions (See XACML core spec section A.3)

+ * 

+ * TO RUN - use jUnit

+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test

+ * 

+ * @author glenngriffin

+ *

+ */

+public class FunctionDefinitionURIStringConcatenateTest {

+

+	/*

+	 * THE FUNCTION BEING TESTED BY THIS CLASS IS DEPRECATED

+	 * uri-string-concatenate has been deprecated in XACML 3.0

+	 */

+

+	/*

+	 * variables useful in the following tests

+	 */

+	List<FunctionArgument> arguments = new ArrayList<FunctionArgument>();

+	

+

+	@SuppressWarnings("deprecation")

+	@Test

+	public void testURI_string_concatenate() {

+

+		// URI args

+		FunctionArgumentAttributeValue attrURI1 = null;

+

+		

+		FunctionArgumentAttributeValue attrStrAbc = null;

+		FunctionArgumentAttributeValue attrStrSlashMno = null;

+		FunctionArgumentAttributeValue attrStrSlashInMiddle = null;

+		FunctionArgumentAttributeValue attrStrWithSpace = null;

+

+		

+		try {

+			attrURI1 = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue("http://someplace"));

+		

+			

+			attrStrAbc = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("Abc"));

+			attrStrSlashMno = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("/Mno"));

+			attrStrSlashInMiddle = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("hij/pqr"));

+			attrStrWithSpace = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("x y z"));

+			

+

+		} catch (Exception e) {

+			fail("creating attributes e="+ e);

+		}

+		

+		// deprecation marking in the following line is correct - this function IS deprecated but still valid for XACML 3.0

+		FunctionDefinitionURIStringConcatenate fd = (FunctionDefinitionURIStringConcatenate) StdFunctions.FD_URI_STRING_CONCATENATE;

+

+		// check identity and type of the thing created

+		assertEquals(XACML2.ID_FUNCTION_URI_STRING_CONCATENATE, fd.getId());

+		assertEquals(DataTypes.DT_ANYURI.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+

+		

+		// add one string to uri

+		arguments.clear();

+		arguments.add(attrURI1);

+		arguments.add(attrStrAbc);

+		ExpressionResult res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(URI.class, res.getValue().getValue().getClass());

+		URI resValue = (URI)res.getValue().getValue();

+		assertEquals("http://someplaceAbc", resValue.toString());

+		

+		

+		// add 2 strings to uri

+		arguments.clear();

+		arguments.add(attrURI1);

+		arguments.add(attrStrAbc);

+		arguments.add(attrStrSlashMno);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(URI.class, res.getValue().getValue().getClass());

+		resValue = (URI)res.getValue().getValue();

+		assertEquals("http://someplaceAbc/Mno", resValue.toString());

+		

+		// slash in middle of string

+		arguments.clear();

+		arguments.add(attrURI1);

+		arguments.add(attrStrSlashInMiddle);

+		arguments.add(attrStrSlashMno);

+		res = fd.evaluate(null, arguments);

+		assertTrue(res.isOk());

+		assertEquals(URI.class, res.getValue().getValue().getClass());

+		resValue = (URI)res.getValue().getValue();

+		assertEquals("http://someplacehij/pqr/Mno", resValue.toString());

+		

+		// create bad uri

+		arguments.clear();

+		arguments.add(attrURI1);

+		arguments.add(attrStrWithSpace);

+		arguments.add(attrStrSlashMno);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:uri-string-concatenate Final string 'http://someplacex y z/Mno' not URI, Illegal character in authority at index 7: http://someplacex y z/Mno", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// no args

+		arguments.clear();

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:uri-string-concatenate Expected 2 or more arguments, got 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// one arg

+		arguments.clear();

+		arguments.add(attrURI1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:uri-string-concatenate Expected 2 or more arguments, got 1", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		

+		// first arg not uri

+		arguments.clear();

+		arguments.add(attrStrAbc);

+		arguments.add(attrURI1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:uri-string-concatenate Expected data type 'anyURI' saw 'string' at arg index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		

+		// 2nd arg not string

+		arguments.clear();

+		arguments.add(attrURI1);

+		arguments.add(attrURI1);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.isOk());

+		assertEquals("function:uri-string-concatenate Expected data type 'string' saw 'anyURI' at arg index 1", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+	}

+	

+

+	

+

+}

diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPathTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPathTest.java
new file mode 100755
index 0000000..5e622ab
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPathTest.java
@@ -0,0 +1,1107 @@
+package com.att.research.xacmlatt.pdp.std.functions;

+

+import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.assertFalse;

+import static org.junit.Assert.assertTrue;

+import static org.junit.Assert.fail;

+

+import java.io.BufferedWriter;

+import java.io.File;

+import java.io.FileWriter;

+import java.math.BigInteger;

+import java.util.ArrayList;

+import java.util.Iterator;

+import java.util.List;

+

+import javax.xml.namespace.NamespaceContext;

+import javax.xml.xpath.XPath;

+import javax.xml.xpath.XPathFactory;

+

+import org.junit.Test;

+

+import com.att.research.xacml.api.Request;

+import com.att.research.xacml.api.XACML3;

+import com.att.research.xacml.std.IdentifierImpl;

+import com.att.research.xacml.std.StdRequest;

+import com.att.research.xacml.std.StdStatus;

+import com.att.research.xacml.std.datatypes.DataTypes;

+import com.att.research.xacml.std.datatypes.XPathExpressionWrapper;

+import com.att.research.xacml.std.dom.DOMRequest;

+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;

+import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue;

+import com.att.research.xacmlatt.pdp.std.StdEvaluationContext;

+import com.att.research.xacmlatt.pdp.std.StdFunctions;

+

+/**

+ * Test of PDP Functions (See XACML core spec section A.3)

+ * 

+ * TO RUN - use jUnit

+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test

+ * 

+ * @author glenngriffin

+ *

+ */

+public class FunctionDefinitionXPathTest {

+	

+	//

+	// Strings for the Request contents

+	//

+	

+	String reqStrMainStart = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" 

+			+ "<Request xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" 

+			+ " http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"" 

+			+ " ReturnPolicyIdList=\"false\""

+			+ " CombinedDecision=\"false\""

+			+ " xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\""

+			+ " xmlns:md=\"http://www.medico.com/schemas/record\""

+			+ " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"

+			+ "	<Attributes Category=\"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\">"

+			+ "		<Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject:subject-id\">"

+			+ "			<AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Julius Hibbert</AttributeValue>"

+			+ "		</Attribute>"

+			+ "		<Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:2.0:conformance-test:test-attr\">"

+			+ "			<AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">   This  is IT!  </AttributeValue>"

+			+ "		</Attribute>"

+			+ "		<Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:2.0:conformance-test:test-attr\">"

+			+ "			<AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">   This  is IT!  </AttributeValue>"

+			+ "		</Attribute>"

+			+ "</Attributes>";

+	      

+	String reqStrResourceStart =   "<Attributes Category=\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\">";

+

+	String reqStrContentMdRecord =

+		" <Content>" +

+			"<md:record>" +

+                "<md:hospital_info>" +

+                   "<md:name>ABC Hospital</md:name>" +

+                    "<md:department>Surgery</md:department>" +

+                "</md:hospital_info>" +

+                "<md:patient_info>" +

+                    "<md:name>Bart Simpson</md:name>" +

+                    "<md:age>60</md:age>" +

+                    "<md:sex>male</md:sex>" +

+                    "<md:health_insurance>123456</md:health_insurance>" +

+                "</md:patient_info>" +

+                "<md:diagnosis_info>" +

+                    "<md:diagnosis>" +

+                        "<md:item type=\"primary\">Gastric Cancer</md:item>" +

+                        "<md:item type=\"secondary\">Hyper tension</md:item>" +

+                    "</md:diagnosis>" +

+                    "<md:pathological_diagnosis>" +

+                        "<md:diagnosis>" +

+                            "<md:item type=\"primary\">Well differentiated adeno carcinoma</md:item>" +

+                        "</md:diagnosis>" +

+                        "<md:date>2000-10-05</md:date>" +

+                        "<md:malignancy type=\"yes\"/>" +

+                    "</md:pathological_diagnosis>" +

+                "</md:diagnosis_info>  " +             

+           " </md:record>" +

+         "</Content>";

+	String reqStrMalformedContent = 

+			" <Content>" +

+					"<md:record>" +

+		                "<md:hospital_info>" +

+		                   "<md:name>ABC Hospital</md:name>" +

+		                        "<md:malignancy type=\"yes\"/>" +

+		    "</Content>";

+	String reqStrResourceEnd = "    <Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:1.0:resource:resource-id\">"

+			+ "		<AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#anyURI\">http://medico.com/record/patient/BartSimpson</AttributeValue>"

+			+ "  </Attribute>"

+			+ "</Attributes> ";

+	String reqStrActionStart =   "<Attributes Category=\"urn:oasis:names:tc:xacml:3.0:attribute-category:action\">";

+

+	String reqStrActionEnd = "<Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:1.0:action:action-id\">"

+			+ "<AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">read</AttributeValue>"

+			+ "</Attribute>"

+			+ "</Attributes> ";

+	String reqStrEnvironmentStartEnd = "  <Attributes Category=\"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\" />";

+	String reqStrMainEnd = " </Request>";

+

+	

+	// combined strings for convenience

+	String reqStrMainResourceStart = reqStrMainStart + reqStrResourceStart;

+	String reqStrResourceAllEnd = reqStrResourceEnd + reqStrActionStart + reqStrActionEnd + reqStrEnvironmentStartEnd + reqStrMainEnd;

+	

+	

+	/*

+	 * variables useful in the following tests

+	 */

+	List<FunctionArgument> arguments = new ArrayList<FunctionArgument>();

+	

+	

+	

+	// Name Spaces used in the XML as part of these examples (copied from the Conformance tests) - needed for compiling XPaths

+	NamespaceContext nameSpaceContext = new NamespaceContext() {

+	    @Override

+	    public Iterator<?> getPrefixes(String arg0) { return null;}

+

+	    @Override

+	    public String getPrefix(String arg0) {return null;}

+

+	    @Override

+	    public String getNamespaceURI(String arg0) {

+	        if("md".equals(arg0)) {

+	            return "http://www.medico.com/schemas/record";

+	        } else if ("xacml-context".equals(arg0)) {

+	        	return "urn:oasis:names:tc:xacml:3.0:context:schema:os";

+	        } else if ("xsi".equals(arg0)) {

+	        	return "http://www.w3.org/2001/XMLSchema-instance";

+	        }

+	        return null;

+	    }

+	};

+	

+	

+	

+	//

+	// XPath Function Attributes available for use in tests  (representing appropriate fragment of Policy)

+	//

+	

+	FunctionArgumentAttributeValue attrXnull = null;

+	FunctionArgumentAttributeValue attrXEmpty = null;

+	FunctionArgumentAttributeValue attrXNoCategory = null;

+	FunctionArgumentAttributeValue attrXNoValue = null;

+	FunctionArgumentAttributeValue attrXSlashSlashMdRecord = null;

+	FunctionArgumentAttributeValue attrXSlashSlashStar = null;

+	FunctionArgumentAttributeValue attrXSlashSlashMdName = null;

+	FunctionArgumentAttributeValue attrXSlashSlashMdMalignancy = null;

+	FunctionArgumentAttributeValue attrXNotInRequest = null;

+	FunctionArgumentAttributeValue attrXSlashSlashMdRecordSlashStar = null;

+	FunctionArgumentAttributeValue attrXMdPatientInfo = null;

+	

+	FunctionArgumentAttributeValue attrBadType = null;

+

+	// String version of attrs for use in Deprecated functions

+	FunctionArgumentAttributeValue attrStrnull = null;

+	FunctionArgumentAttributeValue attrStrEmpty = null;

+	FunctionArgumentAttributeValue attrStrNoCategory = null;

+	FunctionArgumentAttributeValue attrStrNoValue = null;

+	FunctionArgumentAttributeValue attrStrSlashSlashMdRecord = null;

+	FunctionArgumentAttributeValue attrStrSlashSlashStar = null;

+	FunctionArgumentAttributeValue attrStrSlashSlashMdName = null;

+	FunctionArgumentAttributeValue attrStrSlashSlashMdMalignancy = null;

+	FunctionArgumentAttributeValue attrStrNotInRequest = null;

+	FunctionArgumentAttributeValue attrStrSlashSlashMdRecordSlashStar = null;

+	FunctionArgumentAttributeValue attrStrMdPatientInfo = null;

+	

+	

+	//

+	// REQUEST objects available for use in tests

+	//

+	Request requestEmpty = new StdRequest(StdStatus.STATUS_OK);

+	Request requestMdRecord = null;

+	Request requestDoubleResources = null;

+	Request requestResourceActionContent = null;

+	Request requestContentInAction = null;

+

+

+	

+	

+	/**

+	 * Set up all variables in one place because it is complicated (lots of steps needed for each attribute)

+	 */

+	public FunctionDefinitionXPathTest() {

+		try {

+			XPathFactory xPathFactory = XPathFactory.newInstance();

+			XPath xpath = xPathFactory.newXPath();

+			xpath.setNamespaceContext(nameSpaceContext);

+			

+			// Create XPaths to use in expressions

+			XPathExpressionWrapper xEmpty = new XPathExpressionWrapper("");

+			XPathExpressionWrapper xSlashSlashMdRecord = new XPathExpressionWrapper(xpath.compile("//md:record"));

+			XPathExpressionWrapper xSlashSlashStar = new XPathExpressionWrapper(xpath.compile("//*"));

+			XPathExpressionWrapper xSlashSlashMdName = new XPathExpressionWrapper(xpath.compile("//md:name"));

+			XPathExpressionWrapper xSlashSlashMdMalignancy = new XPathExpressionWrapper(xpath.compile("//md:malignancy"));

+			XPathExpressionWrapper xNotInRequest = new XPathExpressionWrapper(xpath.compile("value_Not_in_request"));

+			XPathExpressionWrapper xSlashSlashMdRecordSlashStar = new XPathExpressionWrapper(xpath.compile("//md:record/*"));

+			XPathExpressionWrapper xMdPatientInfo = new XPathExpressionWrapper(xpath.compile("md:patient_info"));

+

+	

+			

+			// create Function Attributes out of the XPathExpressions

+			attrXnull = new FunctionArgumentAttributeValue(null);

+			attrXEmpty = new FunctionArgumentAttributeValue(DataTypes.DT_XPATHEXPRESSION.createAttributeValue(xEmpty));

+			attrXNoCategory = new FunctionArgumentAttributeValue(DataTypes.DT_XPATHEXPRESSION.createAttributeValue(xSlashSlashMdRecord));

+			attrXNoValue = new FunctionArgumentAttributeValue(DataTypes.DT_XPATHEXPRESSION.createAttributeValue(xEmpty,

+					new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" )));

+			attrXSlashSlashMdRecord = new FunctionArgumentAttributeValue(DataTypes.DT_XPATHEXPRESSION.createAttributeValue(xSlashSlashMdRecord,

+					new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" )));

+			attrXSlashSlashStar = new FunctionArgumentAttributeValue(DataTypes.DT_XPATHEXPRESSION.createAttributeValue(xSlashSlashStar,

+					new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" )));

+			attrXSlashSlashMdName = new FunctionArgumentAttributeValue(DataTypes.DT_XPATHEXPRESSION.createAttributeValue(xSlashSlashMdName,

+					new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" )));

+			attrXSlashSlashMdMalignancy = new FunctionArgumentAttributeValue(DataTypes.DT_XPATHEXPRESSION.createAttributeValue(xSlashSlashMdMalignancy,

+					new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" )));

+			attrXNotInRequest = new FunctionArgumentAttributeValue(DataTypes.DT_XPATHEXPRESSION.createAttributeValue(xNotInRequest,

+					new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" )));

+			

+			attrXSlashSlashMdRecordSlashStar = new FunctionArgumentAttributeValue(DataTypes.DT_XPATHEXPRESSION.createAttributeValue(xSlashSlashMdRecordSlashStar,

+					new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" )));

+			attrXMdPatientInfo = new FunctionArgumentAttributeValue(DataTypes.DT_XPATHEXPRESSION.createAttributeValue(xMdPatientInfo,

+					new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" )));	

+			

+			

+			// Deprecated versions of args

+			attrStrnull = new FunctionArgumentAttributeValue(null);

+			attrStrEmpty = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(""));

+			attrStrNoCategory = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("//md:record"));

+			attrStrNoValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("",

+					new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" )));

+			attrStrSlashSlashMdRecord = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("//md:record",

+					new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" )));

+			attrStrSlashSlashStar = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("//*",

+					new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" )));

+			attrStrSlashSlashMdName = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("//md:name",

+					new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" )));

+			attrStrSlashSlashMdMalignancy = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("//md:malignancy",

+					new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" )));

+			attrStrNotInRequest = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("value_Not_in_request",

+					new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" )));

+			

+			attrStrSlashSlashMdRecordSlashStar = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("//md:record/*",

+					new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" )));

+			attrStrMdPatientInfo = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("md:patient_info",

+					new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" )));	

+			

+			

+			

+			

+			attrBadType = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("some string"));

+		

+			

+			

+			// Request objects

+			// to create a Request object the easiest way is to put the xml into a file and use the DOMRequest to load it.

+			

+			// single Content in the Resources section (normal valid request)

+			String reqString = reqStrMainResourceStart + reqStrContentMdRecord + reqStrResourceAllEnd;

+				File tFile = File.createTempFile("functionJunit", "request");

+				BufferedWriter bw = new BufferedWriter(new FileWriter(tFile));

+				bw.append(reqString);

+				bw.flush();

+				bw.close();

+			requestMdRecord = DOMRequest.load(tFile);

+				tFile.delete();

+				

+			// Resources included twice

+			reqString = reqStrMainResourceStart + reqStrContentMdRecord + reqStrResourceEnd + reqStrResourceStart + reqStrContentMdRecord +reqStrResourceAllEnd;

+				tFile = File.createTempFile("functionJunit", "request");

+				bw = new BufferedWriter(new FileWriter(tFile));

+				bw.append(reqString);

+				bw.flush();

+				bw.close();

+			requestDoubleResources = DOMRequest.load(tFile);

+				tFile.delete();

+					

+				

+			// content included in both Resource and Action - ok

+			reqString = reqStrMainResourceStart + reqStrContentMdRecord + reqStrResourceEnd + reqStrActionStart + reqStrContentMdRecord + reqStrActionEnd + reqStrMainEnd;

+				tFile = File.createTempFile("functionJunit", "request");

+				bw = new BufferedWriter(new FileWriter(tFile));

+				bw.append(reqString);

+				bw.flush();

+				bw.close();	

+			requestResourceActionContent = DOMRequest.load(tFile);

+				tFile.delete();

+				

+			// Content included only in Action - missing content produces non-error result according to spec

+			reqString = reqStrMainResourceStart + reqStrResourceEnd + reqStrActionStart + reqStrContentMdRecord + reqStrActionEnd + reqStrMainEnd;

+				tFile = File.createTempFile("functionJunit", "request");

+				bw = new BufferedWriter(new FileWriter(tFile));

+				bw.append(reqString);

+				bw.flush();

+				bw.close();		

+			requestContentInAction = DOMRequest.load(tFile);

+				tFile.delete();

+			

+				

+				

+			// Test that Bad XML is caught

+			@SuppressWarnings("unused")

+			Request requestContentMisplaced = null;

+			@SuppressWarnings("unused")

+			Request requestMalformedContent = null;

+			@SuppressWarnings("unused")

+			Request requestDoubleContent = null;

+

+			

+			// Content included twice - error

+			reqString = reqStrMainResourceStart + reqStrContentMdRecord + reqStrContentMdRecord +reqStrResourceAllEnd;

+				tFile = File.createTempFile("functionJunit", "request");

+				bw = new BufferedWriter(new FileWriter(tFile));

+				bw.append(reqString);

+				bw.flush();

+				bw.close();

+			try {

+				requestDoubleContent = DOMRequest.load(tFile);

+					tFile.delete();

+			} catch (com.att.research.xacml.std.dom.DOMStructureException e) {

+				// this is what it should do, so just continue

+			} catch (Exception e) {

+				fail("Unexpected exception for bad XML, e="+e);

+			}	

+				

+			// Bad XML - Content not under a Category

+			reqString = reqStrMainStart + reqStrContentMdRecord + reqStrResourceStart + reqStrResourceEnd + reqStrActionStart + reqStrActionEnd + reqStrMainEnd;

+				tFile = File.createTempFile("functionJunit", "request");

+				bw = new BufferedWriter(new FileWriter(tFile));

+				bw.append(reqString);

+				bw.flush();

+				bw.close();

+			try {

+				requestContentMisplaced = DOMRequest.load(tFile);

+					tFile.delete();

+			} catch (com.att.research.xacml.std.dom.DOMStructureException e) {

+				// this is what it should do, so just continue

+			} catch (Exception e) {

+				fail("Unexpected exception for bad XML, e="+e);

+			}

+				

+			// Bad XML - Content is not valid XML

+			reqString = reqStrMainResourceStart + reqStrMalformedContent + reqStrResourceAllEnd;

+				tFile = File.createTempFile("functionJunit", "request");

+				bw = new BufferedWriter(new FileWriter(tFile));

+				bw.append(reqString);

+				bw.flush();

+				bw.close();

+			try {

+				requestMalformedContent = DOMRequest.load(tFile);

+					tFile.delete();

+			} catch (com.att.research.xacml.std.dom.DOMStructureException e) {

+				// this is what it should do, so just continue

+			} catch (Exception e) {

+				fail("Unexpected exception for bad XML, e="+e);

+			}

+			

+		} catch (Exception e) {

+			fail("Constructor initializing variables, e="+ e + "  cause="+e.getCause());

+		}

+		

+	}

+	

+

+	

+	

+	

+	

+	

+	

+	@Test

+	public void testXpath_node_count() {

+

+

+		

+		FunctionDefinitionXPath<?> fd = (FunctionDefinitionXPath<?>) StdFunctions.FD_XPATH_NODE_COUNT;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_XPATH_NODE_COUNT, fd.getId());

+		assertEquals(DataTypes.DT_XPATHEXPRESSION.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(1), fd.getNumArgs());

+		

+

+		// match all elements within context

+		arguments.clear();

+		arguments.add(attrXSlashSlashStar);

+		ExpressionResult res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);

+		assertTrue(res.isOk());

+		BigInteger resValue = (BigInteger)res.getValue().getValue();

+		assertEquals(new BigInteger("18"), resValue);

+	

+		// match exactly 1 element

+		arguments.clear();

+		arguments.add(attrXSlashSlashMdMalignancy);

+		res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);

+		assertTrue(res.isOk());

+		resValue = (BigInteger)res.getValue().getValue();

+		assertEquals(new BigInteger("1"), resValue);

+		

+		// match a few but not all

+		arguments.clear();

+		arguments.add(attrXSlashSlashMdName);

+		res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);

+		assertTrue(res.isOk());

+		resValue = (BigInteger)res.getValue().getValue();

+		assertEquals(new BigInteger("2"), resValue);

+		

+		

+		// verify variables using in other tests: count nodes immediately under md:record

+		arguments.clear();

+		arguments.add(attrXSlashSlashMdRecordSlashStar);

+		res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);

+		assertTrue(res.isOk());

+		resValue = (BigInteger)res.getValue().getValue();

+		assertEquals(new BigInteger("3"), resValue);

+		

+		// verify variables using in other tests: count number of records containing patient_info

+		arguments.clear();

+		arguments.add(attrXMdPatientInfo);

+		res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);

+		assertTrue(res.isOk());

+		resValue = (BigInteger)res.getValue().getValue();

+		assertEquals(new BigInteger("1"), resValue);

+		

+		// verify variables using in other tests: count number of records containing md:name

+		arguments.clear();

+		arguments.add(attrXSlashSlashMdName);

+		res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);

+		assertTrue(res.isOk());

+		resValue = (BigInteger)res.getValue().getValue();

+		assertEquals(new BigInteger("2"), resValue);

+		

+		// verify variables using in other tests: count number of records containing md:malignancy

+		arguments.clear();

+		arguments.add(attrXSlashSlashMdMalignancy);

+		res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);

+		assertTrue(res.isOk());

+		resValue = (BigInteger)res.getValue().getValue();

+		assertEquals(new BigInteger("1"), resValue);

+		

+		

+		

+		

+		// match no element

+		arguments.clear();

+		arguments.add(attrXNotInRequest);

+		res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);

+		assertTrue(res.isOk());

+		resValue = (BigInteger)res.getValue().getValue();

+		assertEquals(new BigInteger("0"), resValue);

+		

+		// Resources included twice

+		arguments.clear();

+		arguments.add(attrXSlashSlashMdName);

+		res = fd.evaluate(new StdEvaluationContext(requestDoubleResources, null, null), arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:xpath-node-count More than one Content section for id 'urn:oasis:names:tc:xacml:3.0:attribute-category:resource'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+

+		// Content in both Resource and Action categories (ok)

+		arguments.clear();

+		arguments.add(attrXSlashSlashMdName);

+		res = fd.evaluate(new StdEvaluationContext(requestResourceActionContent, null, null), arguments);

+		assertTrue(res.isOk());

+		resValue = (BigInteger)res.getValue().getValue();

+		assertEquals(new BigInteger("2"), resValue);

+

+		// Content only in Action category (missing in Resources -> 0 according to spec)

+		arguments.clear();

+		arguments.add(attrXSlashSlashMdName);

+		res = fd.evaluate(new StdEvaluationContext(requestContentInAction, null, null), arguments);

+		assertTrue(res.isOk());

+		resValue = (BigInteger)res.getValue().getValue();

+		assertEquals(new BigInteger("0"), resValue);

+

+		

+

+		

+//TODO - any other tests????

+		

+		// null Evaluation Context

+		arguments.clear();

+		arguments.add(attrXEmpty);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:xpath-node-count Got null EvaluationContext", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// null Request

+		arguments.clear();

+		arguments.add(attrXSlashSlashMdRecord);

+		res = fd.evaluate(new StdEvaluationContext(null, null, null), arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:xpath-node-count Got null Request in EvaluationContext", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// null attribute

+		arguments.clear();

+		arguments.add(attrXnull);

+		res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:xpath-node-count Got null attribute at arg index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// no value

+		arguments.clear();

+		arguments.add(attrXNoValue);

+		res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:xpath-node-count XPathExpression returned null at index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// no category

+		arguments.clear();

+		arguments.add(attrXNoCategory);

+		res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:xpath-node-count Got null Category at index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+

+		// too many args

+		arguments.clear();

+		arguments.add(attrXEmpty);

+		arguments.add(attrXEmpty);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:xpath-node-count Expected 1 arguments, got 2", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// too few args

+		arguments.clear();

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:xpath-node-count Expected 1 arguments, got 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// bad arg type

+		arguments.clear();

+		arguments.add(attrBadType);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:xpath-node-count Expected data type 'xpathExpression' saw 'string' at arg index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// null args

+		arguments.clear();

+		arguments.add(null);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:xpath-node-count Got null argument at arg index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+	}

+

+	

+	@Test

+	public void testXpath_node_equal() {

+

+		

+		FunctionDefinitionXPath<?> fd = (FunctionDefinitionXPath<?>) StdFunctions.FD_XPATH_NODE_EQUAL;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_XPATH_NODE_EQUAL, fd.getId());

+		assertEquals(DataTypes.DT_XPATHEXPRESSION.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		

+		// test normal success - exactly the same set

+		arguments.clear();

+		arguments.add(attrXSlashSlashMdName);

+		arguments.add(attrXSlashSlashMdName);

+		ExpressionResult res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// success - second list is subset of first list

+		arguments.clear();

+		arguments.add(attrXSlashSlashMdRecordSlashStar);

+		arguments.add(attrXMdPatientInfo);

+		res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// success - first list is subset of second list

+		arguments.clear();

+		arguments.add(attrXMdPatientInfo);

+		arguments.add(attrXSlashSlashMdRecordSlashStar);

+		res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// success - second list contains children of first list

+		arguments.clear();

+		arguments.add(attrXSlashSlashMdRecord);

+		arguments.add(attrXSlashSlashMdName);

+		res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// success - first list contains children of second list

+		arguments.clear();

+		arguments.add(attrXSlashSlashMdName);

+		arguments.add(attrXSlashSlashMdRecord);

+		res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+

+		

+		// two non-overlapping sets

+		arguments.clear();

+		arguments.add(attrXSlashSlashMdMalignancy);

+		arguments.add(attrXSlashSlashMdName);

+		res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// first list contains nothing

+		arguments.clear();

+		arguments.add(attrXNotInRequest);

+		arguments.add(attrXSlashSlashMdName);

+		res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// second list contains nothing

+		arguments.clear();

+		arguments.add(attrXSlashSlashMdName);

+		arguments.add(attrXNotInRequest);

+		res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);		

+		

+		

+		

+//TODO	

+		//?????

+		///??????? add real tests

+		//////

+		

+		

+		// Resources included twice

+		arguments.clear();

+		arguments.add(attrXSlashSlashMdName);

+		arguments.add(attrXSlashSlashMdName);

+		res = fd.evaluate(new StdEvaluationContext(requestDoubleResources, null, null), arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:xpath-node-equal More than one Content section for id 'urn:oasis:names:tc:xacml:3.0:attribute-category:resource'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		

+

+		// Content in both Resource and Action categories (ok)

+		arguments.clear();

+		arguments.add(attrXSlashSlashMdName);

+		arguments.add(attrXSlashSlashMdName);

+		res = fd.evaluate(new StdEvaluationContext(requestResourceActionContent, null, null), arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		// Content only in Action category (missing in Resources -> 0 according to spec)

+		arguments.clear();

+		arguments.add(attrXSlashSlashMdName);

+		arguments.add(attrXSlashSlashMdName);

+		res = fd.evaluate(new StdEvaluationContext(requestContentInAction, null, null), arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		

+		// null Evaluation Context

+		arguments.clear();

+		arguments.add(attrXSlashSlashMdRecord);

+		arguments.add(attrXSlashSlashMdRecord);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:xpath-node-equal Got null EvaluationContext", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// null Request

+		arguments.clear();

+		arguments.add(attrXSlashSlashMdRecord);

+		arguments.add(attrXSlashSlashMdRecord);

+		res = fd.evaluate(new StdEvaluationContext(null, null, null), arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:xpath-node-equal Got null Request in EvaluationContext", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// null attribute

+		arguments.clear();

+		arguments.add(attrXnull);

+		arguments.add(attrXSlashSlashMdRecord);

+		res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:xpath-node-equal Got null attribute at arg index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		arguments.clear();

+		arguments.add(attrXSlashSlashMdRecord);

+		arguments.add(attrXnull);

+		res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:xpath-node-equal Got null attribute at arg index 1", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// no value

+		arguments.clear();

+		arguments.add(attrXNoValue);

+		arguments.add(attrXSlashSlashMdRecord);

+		res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:xpath-node-equal XPathExpression returned null at index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		arguments.clear();

+		arguments.add(attrXSlashSlashMdRecord);

+		arguments.add(attrXNoValue);

+		res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:xpath-node-equal XPathExpression returned null at index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// no category

+		arguments.clear();

+		arguments.add(attrXNoCategory);

+		arguments.add(attrXSlashSlashMdRecord);

+		res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:xpath-node-equal Got null Category at index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		arguments.clear();

+		arguments.add(attrXSlashSlashMdRecord);

+		arguments.add(attrXNoCategory);

+		res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:xpath-node-equal XPathExpression returned null at index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// too many args

+		arguments.clear();

+		arguments.add(attrXEmpty);

+		arguments.add(attrXEmpty);

+		arguments.add(attrXEmpty);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:xpath-node-equal Expected 2 arguments, got 3", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// too few args

+		arguments.clear();

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:xpath-node-equal Expected 2 arguments, got 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		arguments.clear();

+		arguments.add(attrXEmpty);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:xpath-node-equal Expected 2 arguments, got 1", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+			

+		// bad arg type

+		arguments.clear();

+		arguments.add(attrBadType);

+		arguments.add(attrXEmpty);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:xpath-node-equal Expected data type 'xpathExpression' saw 'string' at arg index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		arguments.clear();

+		arguments.add(attrXEmpty);

+		arguments.add(attrBadType);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:xpath-node-equal Expected data type 'xpathExpression' saw 'string' at arg index 1", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// null args

+		arguments.clear();

+		arguments.add(attrXEmpty);

+		arguments.add(null);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:xpath-node-equal Got null argument at arg index 1", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		arguments.clear();

+		arguments.add(null);

+		arguments.add(attrXEmpty);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:xpath-node-equal Got null argument at arg index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+	}

+	

+	

+	

+	

+	@Test

+	public void testXpath_node_match() {

+

+		

+		FunctionDefinitionXPath<?> fd = (FunctionDefinitionXPath<?>) StdFunctions.FD_XPATH_NODE_MATCH;

+		

+		// check identity and type of the thing created

+		assertEquals(XACML3.ID_FUNCTION_XPATH_NODE_MATCH, fd.getId());

+		assertEquals(DataTypes.DT_XPATHEXPRESSION.getId(), fd.getDataTypeArgs().getId());

+		assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());

+		

+		// just to be safe...  If tests take too long these can probably be eliminated

+		assertFalse(fd.returnsBag());

+		assertEquals(new Integer(2), fd.getNumArgs());

+		

+		

+		// test normal success - exactly the same set

+		arguments.clear();

+		arguments.add(attrXSlashSlashMdName);

+		arguments.add(attrXSlashSlashMdName);

+		ExpressionResult res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);

+		assertTrue(res.isOk());

+		Boolean resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// success - second list is subset of first list

+		arguments.clear();

+		arguments.add(attrXSlashSlashMdRecordSlashStar);

+		arguments.add(attrXMdPatientInfo);

+		res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// success - first list is subset of second list

+		arguments.clear();

+		arguments.add(attrXMdPatientInfo);

+		arguments.add(attrXSlashSlashMdRecordSlashStar);

+		res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// success - second list contains children of first list

+		arguments.clear();

+		arguments.add(attrXSlashSlashMdRecord);

+		arguments.add(attrXSlashSlashMdName);

+		res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+		

+		// success - first list contains children of second list

+		arguments.clear();

+		arguments.add(attrXSlashSlashMdName);

+		arguments.add(attrXSlashSlashMdRecord);

+		res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		

+		

+		// two non-overlapping sets

+		arguments.clear();

+		arguments.add(attrXSlashSlashMdMalignancy);

+		arguments.add(attrXSlashSlashMdName);

+		res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// first list contains nothing

+		arguments.clear();

+		arguments.add(attrXNotInRequest);

+		arguments.add(attrXSlashSlashMdName);

+		res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		// second list contains nothing

+		arguments.clear();

+		arguments.add(attrXSlashSlashMdName);

+		arguments.add(attrXNotInRequest);

+		res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);	

+		

+//TODO		

+		//?????

+		///??????? add real tests

+		//////

+		

+		

+		// Resources included twice

+		arguments.clear();

+		arguments.add(attrXSlashSlashMdName);

+		arguments.add(attrXSlashSlashMdName);

+		res = fd.evaluate(new StdEvaluationContext(requestDoubleResources, null, null), arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:xpath-node-match More than one Content section for id 'urn:oasis:names:tc:xacml:3.0:attribute-category:resource'", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+

+		// Content in both Resource and Action categories (ok)

+		arguments.clear();

+		arguments.add(attrXSlashSlashMdName);

+		arguments.add(attrXSlashSlashMdName);

+		res = fd.evaluate(new StdEvaluationContext(requestResourceActionContent, null, null), arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertTrue(resValue);

+

+		// Content only in Action category (missing in Resources -> 0 according to spec)

+		arguments.clear();

+		arguments.add(attrXSlashSlashMdName);

+		arguments.add(attrXSlashSlashMdName);

+		res = fd.evaluate(new StdEvaluationContext(requestContentInAction, null, null), arguments);

+		assertTrue(res.isOk());

+		resValue = (Boolean)res.getValue().getValue();

+		assertFalse(resValue);

+		

+		

+		// null Evaluation Context

+		arguments.clear();

+		arguments.add(attrXSlashSlashMdRecord);

+		arguments.add(attrXSlashSlashMdRecord);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:xpath-node-match Got null EvaluationContext", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// null Request

+		arguments.clear();

+		arguments.add(attrXSlashSlashMdRecord);

+		arguments.add(attrXSlashSlashMdRecord);

+		res = fd.evaluate(new StdEvaluationContext(null, null, null), arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:xpath-node-match Got null Request in EvaluationContext", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// null attribute

+		arguments.clear();

+		arguments.add(attrXnull);

+		arguments.add(attrXSlashSlashMdRecord);

+		res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:xpath-node-match Got null attribute at arg index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		arguments.clear();

+		arguments.add(attrXSlashSlashMdRecord);

+		arguments.add(attrXnull);

+		res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:xpath-node-match Got null attribute at arg index 1", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// no value

+		arguments.clear();

+		arguments.add(attrXNoValue);

+		arguments.add(attrXSlashSlashMdRecord);

+		res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:xpath-node-match XPathExpression returned null at index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		arguments.clear();

+		arguments.add(attrXSlashSlashMdRecord);

+		arguments.add(attrXNoValue);

+		res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:xpath-node-match XPathExpression returned null at index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// no category

+		arguments.clear();

+		arguments.add(attrXNoCategory);

+		arguments.add(attrXSlashSlashMdRecord);

+		res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:xpath-node-match Got null Category at index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		arguments.clear();

+		arguments.add(attrXSlashSlashMdRecord);

+		arguments.add(attrXNoCategory);

+		res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:xpath-node-match XPathExpression returned null at index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// too many args

+		arguments.clear();

+		arguments.add(attrXEmpty);

+		arguments.add(attrXEmpty);

+		arguments.add(attrXEmpty);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:xpath-node-match Expected 2 arguments, got 3", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// too few args

+		arguments.clear();

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:xpath-node-match Expected 2 arguments, got 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		arguments.clear();

+		arguments.add(attrXEmpty);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:xpath-node-match Expected 2 arguments, got 1", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+			

+		// bad arg type

+		arguments.clear();

+		arguments.add(attrBadType);

+		arguments.add(attrXEmpty);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:xpath-node-match Expected data type 'xpathExpression' saw 'string' at arg index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		arguments.clear();

+		arguments.add(attrXEmpty);

+		arguments.add(attrBadType);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:xpath-node-match Expected data type 'xpathExpression' saw 'string' at arg index 1", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		// null args

+		arguments.clear();

+		arguments.add(attrXEmpty);

+		arguments.add(null);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:xpath-node-match Got null argument at arg index 1", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		arguments.clear();

+		arguments.add(null);

+		arguments.add(attrXEmpty);

+		res = fd.evaluate(null, arguments);

+		assertFalse(res.getStatus().isOk());

+		assertEquals( "function:xpath-node-match Got null argument at arg index 0", res.getStatus().getStatusMessage());

+		assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());

+		

+		

+		

+	}

+	

+

+	

+	//

+	// DEPRECATED versions that use String arguments rather than XPATHEXPRESSIONs

+	// are NOT supported due to ambiguity in the semantics between 2.0 (<Request> is root and has only one <Content> in resources)

+	//	and 3.0 (<Content> is root and there are multiple <Content> sections in any category)

+	//

+	

+

+	

+}

diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/json/RequestCategoryTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/json/RequestCategoryTest.java
new file mode 100755
index 0000000..c5c40e3
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/json/RequestCategoryTest.java
@@ -0,0 +1,4165 @@
+/*

+ *                        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.std.json;

+

+import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.fail;

+

+import org.junit.Test;

+

+import com.att.research.xacml.api.Request;

+import com.att.research.xacml.std.json.JSONRequest;

+import com.att.research.xacml.std.json.JSONStructureException;

+

+/**

+ * Test JSON Request convert to object - Category sub-component.  Does not include "Default" Categories (Subject, Action, Resource, Environment).

+ * Basic existance/absence of Category is tested in RequestMainTest.

+ * 

+ * TO RUN - use jUnit

+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test

+ * 

+ * NOTE:

+ * The "correct" way to verify that each JSON string gets translated into our internal Objects correctly is to look explicitly at each of the child objects

+ * and verify that they are correct.  This would involve a lot of coding to get child of child of child and individually verify each property of each element.

+ * To simplify testing we assume that request.toString() correctly includes a complete text representation of every sub-component of the Request object

+ * and we compare the resulting String to our expected String.

+ * This has two possible sources of error:

+ * 	- toString might not include some sub-component, and

+ * 	- the initial verification of the resulting string is done by hand and may have been incorrect.

+ * 

+ * @author glenngriffin

+ *

+ */

+public class RequestCategoryTest {

+	

+	// The request object output from each test conversion from JSON string

+	Request request;

+

+	

+	/*

+	 * Request that uses all fields with both single and multiple  entries

+	 */

+	String allFieldsRequest = 

+			"{\"Request\": {" +

+					"\"ReturnPolicyIdList\" : true ," +

+					"\"CombinedDecision\" : true ," +

+					"\"XPathVersion\" : \"http://www.w3.org/TR/1999/REC-xpath-19991116\"," +

+					"\"MultiRequests\" : {" +

+			            "\"RequestReference\": [" +

+			            	"{ " +

+			                	"\"ReferenceId\" : [\"foo1\",\"bar1\"]" +

+			                "}," +

+			                "{" +

+			                	"\"ReferenceId\" : [\"foo2\",\"bar1\"]" +

+			                "}]" +   

+			          "}," +

+

+					"\"Category\": [" +

+						"{ " +

+					    	"\"CategoryId\": \"custom-category\", " +

+					    	"\"Id\" : \"customId\", " +

+					    	"\"Attribute\" : [" +

+					    		"{" +

+					    			"\"AttributeId\"		: \"document-id\", " +

+					    			"\"DataType\"	: \"integer\", " +

+					    			"\"Value\"	: 123 " +

+								"}, " +

+								"{" +

+				    				"\"AttributeId\"		: \"document-url\", " +

+				    				"\"DataType\"	: \"anyURI\", " +

+				    				"\"Value\"	: \"http://somewhere.over.the.com/rainbow\" " +

+				    			"}, " +

+								"{" +

+				    				"\"AttributeId\"		: \"page-list\", " +

+				    				"\"Value\"	: [1, 2, 3, 4.5, 3, 2, 1] " +

+							"} " +

+					    	"]" +

+					    "}, " +

+					    "{ " +

+					    	"\"CategoryId\": \"another-custom-cat\", " +

+					    	"\"Id\" : \"anotherXmlId\", " +

+					    	"\"Attribute\" : []" +

+					    "} " +

+					"], " +

+					    

+					"\"AccessSubject\":{ " +

+						"\"Content\" : \"<?xml version=\\\"1.0\\\"?><catalog>" + 

+							"<book id=\\\"bk101\\\"><author>Gambardella, Matthew</author><title>XML Developer's Guide</title><genre>Computer</genre>" +

+							"<price>44.95</price><publish_date>2000-10-01</publish_date><description>An in-depth look at creating applications with XML.</description>"+

+							"</book></catalog>\"," +

+						"\"Attribute\" : []" +

+					"}, " +

+					

+					"\"Resource\" : {" +

+						"\"Content\" : \"PD94bWwgdmVyc2lvbj0iMS4wIj8+PGNhdGFsb2c+PGJvb2sgaWQ9ImJrMTAxIj48YXV0aG9yPkdhbWJhcmRlbGxhLCBNYXR0aGV3PC9hdXRob3I+PHRpdGxlPlhNT" +

+							"CBEZXZlbG9wZXIncyBHdWlkZTwvdGl0bGU+PGdlbnJlPkNvbXB1dGVyPC9nZW5yZT48cHJpY2U+NDQuOTU8L3ByaWNlPjxwdWJsaXNoX2RhdGU+MjAwMC0xMC0wMTwvcHVibGlzaF"+

+							"9kYXRlPjxkZXNjcmlwdGlvbj5BbiBpbi1kZXB0aCBsb29rIGF0IGNyZWF0aW5nIGFwcGxpY2F0aW9ucyB3aXRoIFhNTC48L2Rlc2NyaXB0aW9uPjwvYm9vaz48L2NhdGFsb2c+\"" +

+

+

+					"} " +

+

+			          

+			"}}";

+	

+	/*

+	 * The following example comes directly from the JSON Profile Spec

+	 */

+	String exampleFromSpec = "{ " +

+			"\"Request\" : { " +

+				"\"AccessSubject\" : { " +

+					"\"Attribute\": [ " +

+						"{ " +

+							"\"Id\" : \"subject-id\", " +

+							"\"Value\" : \"Andreas\" " +

+						"}, " +

+						"{ " +

+							"\"Id\" : \"location\", " +

+							"\"Value\" : \"Gamla Stan\" " +

+						"} " +

+					"] " +

+				"}, " +

+				"\"Action\" : { " +

+					"\"Attribute\":  " +

+						"{ " +

+							"\"Id\" : \"action-id\", " +

+							"\"Value\" : \"http://www.xacml.eu/buy\", " +

+							"\"DataType\" : \"anyURI\" " +

+						"} " +

+				"}, " +

+				"\"Resource\" : { " +

+					"\"Attribute\": [ " +

+						"{ " +

+							"\"Id\" : \"book-title\", " +

+							"\"Value\" : \"Learn German in 90 days\" " +

+						"}, " +

+						"{ " +

+							"\"Id\" : \"currency\", " +

+							"\"Value\" : \"SEK\" " +

+						"}, " +

+						"{ " +

+							"\"Id\" : \"price\", " +

+							"\"Value\" : 123.34 " +

+						"} " +

+						"] " +

+					"} " +

+				"} " +

+			"} ";

+

+	

+	/*

+	 * The following example comes directly from the JSON Profile Spec (modified to include a "</Catalog>" missing from both examples).

+	 * It shows the two ways of handling XPath content, as escaped XML and as Base64 encoding.

+	 */

+	String xPathExampleFromSpec = "{ " +

+			"\"Request\" : { " +

+				"\"Resource\" : { " +

+					"\"Attribute\": [ " +

+						"{ " +

+						 	"\"Id\" : \"urn:oasis:names:tc:xacml:3.0:content-selector\", " +

+				            "\"DataType\" : \"xpathExpression\", " +

+				            "\"Value\" : { " +

+				                "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\", " +

+				                "\"Namespaces\" : [{ " +

+				                    	"\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " +

+				                    	"}, " +

+				                    "{ " +

+				                    	"\"Prefix\" : \"md\", " +

+				                    	"\"Namespace\" : \"urn:example:med:schemas:record\" " +

+				                    "} " +

+				                "], " +

+				                "\"XPath\" : \"md:record/md:patient/md:patientDoB\" " +

+				            "} " +

+				        "} " +

+					"] " +

+				"} " +

+			"} " +

+		"} ";

+

+

+	

+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

+

+	// Top-level of Category

+	@Test

+	public void testCategoryTopLevel() {	

+		

+		// empty Category

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// Missing value

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\" }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\" : }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// Category without CategoryId

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{}] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// Category with CategoryId value missing or =""

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\"] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"\" ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// CategoryId wrong type

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : true } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : 123 } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// Category with Id

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Id\" : \"customId\" } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category},xmlId=customId}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// Category with Id - wrong type

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Id\" : true } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Id\" : 123 } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		

+		// Category without Id	

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\" } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		

+		// Category with standard CategoryId

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\" } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// Category with extra unknown field

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", unknown } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"unknown\" : 123 } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// Category with multiple sub-Category objects using same CategoryId

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"category1\" }, {\"CategoryId\" : \"category1\" } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=category1}}{super={category=category1}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+	}

+

+	

+	

+	// Tests related to Attributes

+	@Test

+	public void testCategoryAttributes() {	

+	

+		// Category with Attribute but none given ("Attribute" : [] )		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+

+		// Category Attribute with empty attribute (missing both AttributeId and Id)

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// Category Attribute with AttributeId and no Value

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"AttributeId\" : \"document-id\" " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// Category Attribute missing AttributeId but with Id		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"AttributeId\" : \"document-id\", " +

+	    			"\"Value\"	: 123 " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// Category Attribute missing AttributeId but with Id

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: 123 " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// Category Attribute including both AttributeId and Id with same value

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"AttributeId\" : \"document-id\", " +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: 123 " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// Category Attribute missing both AttributeId and Id

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Value\"	: 123 " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// Category Attribute AttributeId not string

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"AttributeId\" : true, " +

+	    			"\"Value\"	: 123 " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"AttributeId\" : 123, " +

+	    			"\"Value\"	: 123 " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// Category Attribute Id not string

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : true, " +

+	    			"\"Value\"	: 123 " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : 123, " +

+	    			"\"Value\"	: 123 " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		

+		// Category Attribute with DataType

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"integer\", " +

+	    			"\"Value\"	: 123 " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// Category Attribute with DataType not string (e.g. "DataType" : 55.5 )

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: true, " +

+	    			"\"Value\"	: 123 " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// Category Attribute with unknown DataType

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"no such data type\", " +

+	    			"\"Value\"	: 123 " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: 321, " +

+	    			"\"Value\"	: 123 " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// Category Attribute with multiple value array

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"dayTimeDuration\", " +

+	    			"\"Value\"	: [\"P3D\", \"P2DT12H34M\", \"PT15M\"] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#dayTimeDuration,value={super={durationSign=1years=0months=0days=3hours=0minutes=0seconds=0millis=0},factionalSeconds=0.0}}{dataTypeId=http://www.w3.org/2001/XMLSchema#dayTimeDuration,value={super={durationSign=1years=0months=0days=2hours=12minutes=34seconds=0millis=0},factionalSeconds=0.0}}{dataTypeId=http://www.w3.org/2001/XMLSchema#dayTimeDuration,value={super={durationSign=1years=0months=0days=0hours=0minutes=15seconds=0millis=0},factionalSeconds=0.0}}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// Category Attribute multiple value with null in array

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"dayTimeDuration\", " +

+	    			"\"Value\"	: [\"P3D\", , \"P15M\"] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// Category Attribute with array value with no values ("Attribute": [ {"AttributeId" :"a", Value:[] } ] }  )

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"dayTimeDuration\", " +

+	    			"\"Value\"	: [ ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// Category Attribute with no DataType and array with no values

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// Category Attribute with Issuer

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+					"\"Issuer\" : \"University Press\", " +

+	    			"\"DataType\"	: \"integer\", " +

+	    			"\"Value\"	: 123 " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}],issuer=University Press,includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// Category Attribute with Issuer not string

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+					"\"Issuer\" : true, " +

+	    			"\"DataType\"	: \"integer\", " +

+	    			"\"Value\"	: 123 " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+					"\"Issuer\" : 4.56, " +

+	    			"\"DataType\"	: \"integer\", " +

+	    			"\"Value\"	: 123 " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// Category Attribute with includeInResult=true

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: 123, " +

+	    			"\"IncludeInResult\" : true " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}],includeInResults=true}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// Category Attribute with includeInResult = false

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: 123, " +

+	    			"\"IncludeInResult\" : false " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// Category Attribute with includeInResult not boolean

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: 123, " +

+	    			"\"IncludeInResult\" : \"abc\" " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: 123, " +

+	    			"\"IncludeInResult\" : 123.45 " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+	}

+

+	

+	

+	// Tests related to DataTypes within Attributes

+	@Test

+	public void testCategoryAttributesDataTypesSimple() {	

+		

+		// Category Attribute using full Identifier for each data type

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#string\", " +

+	    			"\"Value\"	: \"abc\" " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#boolean\", " +

+	    			"\"Value\"	: true " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#integer\", " +

+	    			"\"Value\"	: 123 " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#double\", " +

+	    			"\"Value\"	: 123.34 " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=123.34}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#time\", " +

+	    			"\"Value\"	: \"12:00:00Z\" " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#time,value=12:00:00Z}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#date\", " +

+	    			"\"Value\"	: \"2002-10-10\" " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#date,value=2002-10-10}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#dateTime\", " +

+	    			"\"Value\"	: \"2002-10-10T12:00:00Z\" " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#dateTime,value=2002-10-10T12:00:00Z}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#dayTimeDuration\", " +

+	    			"\"Value\"	: \"P23DT7H12M54S\" " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#dayTimeDuration,value={super={durationSign=1years=0months=0days=23hours=7minutes=12seconds=54millis=0},factionalSeconds=54.0}}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#yearMonthDuration\", " +

+	    			"\"Value\"	: \"P165Y8M\" " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#yearMonthDuration,value={super={durationSign=1years=165months=8days=0hours=0minutes=0seconds=0millis=0},monthsDuration=1988}}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#anyURI\", " +

+	    			"\"Value\"	: \"aValue\" " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#hexBinary\", " +

+	    			"\"Value\"	: \"FA027B7D12CC34DDD20012AEEF\" " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#hexBinary,value={data=[-6,2,123,125,18,-52,52,-35,-46,0,18,-82,-17]}}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#base64Binary\", " +

+	    			"\"Value\"	: \"lvbj0iMS4wIj8+PGNhdGFsb2c+PGJvb2sgaWQ9ImJrMTAxIj48YXV0aG9y\" " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-106,-10,-29,-46,35,18,-29,2,35,-13,-29,-58,54,23,70,22,-58,-10,115,-29,-58,38,-10,-10,-78,6,-106,67,-46,38,38,-77,19,3,18,35,-29,-58,23,87,70,-122,-9]}}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name\", " +

+	    			"\"Value\"	: \"someone.else@A.COMPANY.com\" " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name,value={localName=someone.else,domainName=A.COMPANY.com}}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"urn:oasis:names:tc:xacml:1.0:data-type:x500Name\", " +

+	    			"\"Value\"	: \"cn=Julius Hibbert, o=Medi Corporation, c=US\" " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:x500Name,value=CN=Julius Hibbert, O=Medi Corporation, C=US}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"urn:oasis:names:tc:xacml:2.0:data-type:ipAddress\", " +

+	    			"\"Value\"	: \"121.221.43.58:12345\" " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:ipAddress,value=121.221.43.58:12345-12345}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"urn:oasis:names:tc:xacml:2.0:data-type:dnsName\", " +

+	    			"\"Value\"	: \"aValue\" " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:dnsName,value={domainName=aValue}}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\", " +

+	    			"\"Value\"	: {" +

+	    				"\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +

+	    				"\"Namespaces\" : ["

+	    					+ "{ "+

+    							"\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " +

+    							"}," +

+    							"{" +

+    								"\"Prefix\" : \"md\", " +

+    								"\"Namespace\" : \"urn:example:med:schemas:record\" " +

+    							"}], "+

+    					"\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+

+            		"}" +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression,value={path=md:record/md:patient/md:patientDoB,Namespace={[{md,urn:example:med:schemas:record}{urn:oasis:names:tc:xacml:3.0:core:schema:wd-17}]},status=null,xpathExpressionWrapped=null},xpathCategory=urn:oasis:names:tc:xacml:3.0:attribute-category:resource}],includeInResults=false}]}}]}", request.toString());

+

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+

+		

+		// Category Attribute shorthand notation for each data type

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"string\", " +

+	    			"\"Value\"	: \"abc\" " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"boolean\", " +

+	    			"\"Value\"	: true " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"integer\", " +

+	    			"\"Value\"	: 123 " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"double\", " +

+	    			"\"Value\"	: 123.34 " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=123.34}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"time\", " +

+	    			"\"Value\"	: \"12:00:00Z\" " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#time,value=12:00:00Z}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"date\", " +

+	    			"\"Value\"	: \"2002-10-10\" " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#date,value=2002-10-10}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"dateTime\", " +

+	    			"\"Value\"	: \"2002-10-10T12:00:00Z\" " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#dateTime,value=2002-10-10T12:00:00Z}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"dayTimeDuration\", " +

+	    			"\"Value\"	: \"P23DT7H12M54S\" " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#dayTimeDuration,value={super={durationSign=1years=0months=0days=23hours=7minutes=12seconds=54millis=0},factionalSeconds=54.0}}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"yearMonthDuration\", " +

+	    			"\"Value\"	: \"P165Y8M\" " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#yearMonthDuration,value={super={durationSign=1years=165months=8days=0hours=0minutes=0seconds=0millis=0},monthsDuration=1988}}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"anyURI\", " +

+	    			"\"Value\"	: \"aValue\" " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"hexBinary\", " +

+	    			"\"Value\"	: \"FA027B7D12CC34DDD20012AEEF\" " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#hexBinary,value={data=[-6,2,123,125,18,-52,52,-35,-46,0,18,-82,-17]}}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"base64Binary\", " +

+	    			"\"Value\"	: \"lvbj0iMS4wIj8+PGNhdGFsb2c+PGJvb2sgaWQ9ImJrMTAxIj48YXV0aG9y\" " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-106,-10,-29,-46,35,18,-29,2,35,-13,-29,-58,54,23,70,22,-58,-10,115,-29,-58,38,-10,-10,-78,6,-106,67,-46,38,38,-77,19,3,18,35,-29,-58,23,87,70,-122,-9]}}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"rfc822Name\", " +

+	    			"\"Value\"	: \"someone.else@A.COMPANY.com\" " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name,value={localName=someone.else,domainName=A.COMPANY.com}}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"x500Name\", " +

+	    			"\"Value\"	: \"cn=Julius Hibbert, o=Medi Corporation, c=US\" " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:x500Name,value=CN=Julius Hibbert, O=Medi Corporation, C=US}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"ipAddress\", " +

+	    			"\"Value\"	: \"121.221.43.58:12345\" " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:ipAddress,value=121.221.43.58:12345-12345}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"dnsName\", " +

+	    			"\"Value\"	: \"aValue\" " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:dnsName,value={domainName=aValue}}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"xpathExpression\", " +

+	    			"\"Value\"	: {" +

+	    				"\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +

+	    				"\"Namespaces\" : ["

+	    					+ "{ "+

+    							"\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " +

+    							"}," +

+    							"{" +

+    								"\"Prefix\" : \"md\", " +

+    								"\"Namespace\" : \"urn:example:med:schemas:record\" " +

+    							"}], "+

+    					"\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+

+            		"}" +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression,value={path=md:record/md:patient/md:patientDoB,Namespace={[{md,urn:example:med:schemas:record}{urn:oasis:names:tc:xacml:3.0:core:schema:wd-17}]},status=null,xpathExpressionWrapped=null},xpathCategory=urn:oasis:names:tc:xacml:3.0:attribute-category:resource}],includeInResults=false}]}}]}", request.toString());

+

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+

+		

+		

+		// infer data type - only integer, boolean and double are distinguishable from strings; everything else is treated as a string

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: \"abc\" " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: true " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: 123 " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: 123.34 " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=123.34}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: \"12:00:00Z\" " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12:00:00Z}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: \"2002-10-10\" " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: \"2002-10-10T12:00:00Z\" " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10T12:00:00Z}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: \"P23DT7H12M54S\" " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P23DT7H12M54S}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: \"P165Y8M\" " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P165Y8M}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: \"aValue\" " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: \"FA027B7D12CC34DDD20012AEEF\" " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=FA027B7D12CC34DDD20012AEEF}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: \"lvbj0iMS4wIj8+PGNhdGFsb2c+PGJvb2sgaWQ9ImJrMTAxIj48YXV0aG9y\" " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lvbj0iMS4wIj8+PGNhdGFsb2c+PGJvb2sgaWQ9ImJrMTAxIj48YXV0aG9y}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: \"someone.else@A.COMPANY.com\" " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=someone.else@A.COMPANY.com}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"urn:oasis:names:tc:xacml:1.0:data-type:x500Name\", " +

+	    			"\"Value\"	: \"cn=Julius Hibbert, o=Medi Corporation, c=US\" " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:x500Name,value=CN=Julius Hibbert, O=Medi Corporation, C=US}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: \"121.221.43.58:12345\" " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=121.221.43.58:12345}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: \"aValue\" " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: \"aValue\" " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: {" +

+	    				"\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +

+	    				"\"Namespaces\" : ["

+	    					+ "{ "+

+    							"\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " +

+    							"}," +

+    							"{" +

+    								"\"Prefix\" : \"md\", " +

+    								"\"Namespace\" : \"urn:example:med:schemas:record\" " +

+    							"}], "+

+    					"\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+

+            		"}" +

+					"}] } ] }}");

+			// gets inferred to a String containing the whole structure under Value as a String

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value={XPathCategory=urn:oasis:names:tc:xacml:3.0:attribute-category:resource, Namespaces=[{Namespace=urn:oasis:names:tc:xacml:3.0:core:schema:wd-17}, {Prefix=md, Namespace=urn:example:med:schemas:record}], XPath=md:record/md:patient/md:patientDoB}}],includeInResults=false}]}}]}", request.toString());

+

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+	}

+	

+	

+	

+	@Test

+	public void testCategoryAttributesDataTypesNotMatchValue() {	

+

+		// Category Attribute with DataType not matching value type (JSON type derived from syntax)

+		// AUTO-CONVERSION from Boolean to String!

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#string\", " +

+	    			"\"Value\"	: true " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// SUCCESSFUL AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#string\", " +

+	    			"\"Value\"	: 123 " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// SUCCESSFUL AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#string\", " +

+	    			"\"Value\"	: 123.34 " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123.34}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#boolean\", " +

+	    			"\"Value\"	: \"abc\" " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#boolean\", " +

+	    			"\"Value\"	: 123 " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#boolean\", " +

+	    			"\"Value\"	: 123.45 " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// SUCCESSFUL AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#integer\", " +

+	    			"\"Value\"	: \"123\" " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#integer\", " +

+	    			"\"Value\"	: true " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#integer\", " +

+	    			"\"Value\"	: 123.45 " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+

+		// SUCCESSFUL AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#double\", " +

+	    			"\"Value\"	: \"123.34\" " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=123.34}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#double\", " +

+	    			"\"Value\"	: true " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// allow integer to auto-convert to double when DataType is given

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#double\", " +

+	    			"\"Value\"	: 123 " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=123.0}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// special JavaScript values not allowed except for -0 (inappropriate requirement in spec - check it anyway)

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#integer\", " +

+	    			"\"Value\"	: \"NaN\" " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#integer\", " +

+	    			"\"Value\"	: \"INF\" " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#integer\", " +

+	    			"\"Value\"	: \"-INF\" " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// JavaScript 0 and -0 are ok

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#integer\", " +

+	    			"\"Value\"	: 0 " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=0}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#integer\", " +

+	    			"\"Value\"	: -0 " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=0}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		

+		// All other data types are checked when we convert internally, so value must be syntactically correct

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#time\", " +

+	    			"\"Value\"	: \"syntactically incorrect value\" " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#date\", " +

+	    			"\"Value\"	: \"syntactically incorrect value\" " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#dateTime\", " +

+	    			"\"Value\"	: \"syntactically incorrect value\" " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#dayTimeDuration\", " +

+	    			"\"Value\"	: \"syntactically incorrect value\" " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#yearMonthDuration\", " +

+	    			"\"Value\"	: \"syntactically incorrect value\" " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#anyURI\", " +

+	    			"\"Value\"	: \"syntactically incorrect value\" " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#hexBinary\", " +

+	    			"\"Value\"	: \"syntactically incorrect value\" " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// Base64 convert does not throw an exception if the contents are not Base64, so cannot test for this.

+		// Any problem with the data will have to be discovered later when the data is used.

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name\", " +

+	    			"\"Value\"	: \"syntactically incorrect value\" " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"urn:oasis:names:tc:xacml:1.0:data-type:x500Name\", " +

+	    			"\"Value\"	: \"syntactically incorrect value\" " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"urn:oasis:names:tc:xacml:2.0:data-type:ipAddress\", " +

+	    			"\"Value\"	: \"syntactically incorrect value\" " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"urn:oasis:names:tc:xacml:2.0:data-type:dnsName\", " +

+	    			"\"Value\"	: \"syntactically incorrect value\" " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+

+		// Cannot test XPathExpressions here.  The XPathExpression gets converted into a simple String value within the XPathExpression object,

+		// but it is not evaluated or compiled at that time.  Therefore we do not know whether or not the value is valid until it is used in a computation.

+

+	}

+	

+	

+	@Test

+	public void testArrayDataTypes() {

+		

+		// array of size 0

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#string\", " +

+	    			"\"Value\"	: [] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		

+		// Category Attribute value array DataType given (repeat for all data types)

+		// Category Attribute using full Identifier for each data type

+		// Category Attribute shorthand notation for each data type

+		// Also tests for mixes of different JSON types (trying incorrect strings for XACML data types whenever possible)

+		// string

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#string\", " +

+	    			"\"Value\"	: [\"abc\", \"def\", \"hig\", \"lmn\"] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=def}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=hig}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lmn}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"string\", " +

+	    			"\"Value\"	: [\"abc\", \"def\", \"hig\", \"lmn\"] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=def}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=hig}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lmn}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// SUCCESSFUL AUTO-CONVERT to DataType

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#string\", " +

+	    			"\"Value\"	: [\"abc\", true, \"hig\", \"lmn\"] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=hig}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lmn}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// SUCCESSFUL AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#string\", " +

+	    			"\"Value\"	: [\"abc\",123, \"hig\", \"lmn\"] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=hig}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lmn}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// SUCCESSFUL AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#string\", " +

+	    			"\"Value\"	: [\"abc\", 34.34, \"hig\", \"lmn\"] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=34.34}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=hig}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lmn}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		

+		// boolean

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#boolean\", " +

+	    			"\"Value\"	: [true, true, false, true, false ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=false}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=false}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"boolean\", " +

+	    			"\"Value\"	: [true, true, false, true, false ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=false}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=false}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#boolean\", " +

+	    			"\"Value\"	: [true, \"abc\", false, true, false ] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#boolean\", " +

+	    			"\"Value\"	: [true, 123, false, true, false ] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#boolean\", " +

+	    			"\"Value\"	: [true, 12.34, false, true, false ] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		

+		

+		// integer

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#integer\", " +

+	    			"\"Value\"	: [123, 456, 765, 234] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=456}{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=765}{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=234}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"integer\", " +

+	    			"\"Value\"	: [123, 456, 765, 234] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=456}{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=765}{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=234}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#integer\", " +

+	    			"\"Value\"	: [123, \"abc\", 765, 234] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#integer\", " +

+	    			"\"Value\"	: [123, true, 765, 234] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#integer\", " +

+	    			"\"Value\"	: [123, 34.56, 765, 234] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		

+		// double

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#double\", " +

+	    			"\"Value\"	: [ 123.34, 543.54, 3445.455, 4543,543 ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=123.34}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=543.54}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=3445.455}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=4543.0}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=543.0}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"double\", " +

+	    			"\"Value\"	: [ 123.34, 543.54, 3445.455, 4543,543 ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=123.34}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=543.54}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=3445.455}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=4543.0}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=543.0}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// special case - auto-convert integer to boolean

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#double\", " +

+	    			"\"Value\"	: [ 123.34, 111122, 3445.455, 4543,543 ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=123.34}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=111122.0}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=3445.455}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=4543.0}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=543.0}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#double\", " +

+	    			"\"Value\"	: [ 123.34, true, 3445.455, 4543,543 ] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#double\", " +

+	    			"\"Value\"	: [ 123.34, \"abb\", 3445.455, 4543,543 ] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		

+		// time

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#time\", " +

+	    			"\"Value\"	: [ \"12:00:00Z\", \"12:00:00Z\", \"12:00:00Z\"] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#time,value=12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#time,value=12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#time,value=12:00:00Z}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"time\", " +

+	    			"\"Value\"	: [ \"12:00:00Z\", \"12:00:00Z\", \"12:00:00Z\"] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#time,value=12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#time,value=12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#time,value=12:00:00Z}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#time\", " +

+	    			"\"Value\"	: [ \"12:00:00Z\", \"not a time\", \"12:00:00Z\"] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#time\", " +

+	    			"\"Value\"	: [ \"12:00:00Z\", true, \"12:00:00Z\"] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#time\", " +

+	    			"\"Value\"	: [ \"12:00:00Z\", 123, \"12:00:00Z\"] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#time\", " +

+	    			"\"Value\"	: [ \"12:00:00Z\", 12.34, \"12:00:00Z\"] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		

+		// date

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#date\", " +

+	    			"\"Value\"	: [\"2002-10-10\",\"2002-10-10\",\"2002-10-10\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#date,value=2002-10-10}{dataTypeId=http://www.w3.org/2001/XMLSchema#date,value=2002-10-10}{dataTypeId=http://www.w3.org/2001/XMLSchema#date,value=2002-10-10}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"date\", " +

+	    			"\"Value\"	: [\"2002-10-10\",\"2002-10-10\",\"2002-10-10\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#date,value=2002-10-10}{dataTypeId=http://www.w3.org/2001/XMLSchema#date,value=2002-10-10}{dataTypeId=http://www.w3.org/2001/XMLSchema#date,value=2002-10-10}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#date\", " +

+	    			"\"Value\"	: [\"2002-10-10\",\"not a date\",\"2002-10-10\" ] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#date\", " +

+	    			"\"Value\"	: [\"2002-10-10\",true,\"2002-10-10\" ] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#date\", " +

+	    			"\"Value\"	: [\"2002-10-10\",123,\"2002-10-10\" ] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#date\", " +

+	    			"\"Value\"	: [\"2002-10-10\",123.45,\"2002-10-10\" ] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		

+		// dateTime

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#dateTime\", " +

+	    			"\"Value\"	: [ \"2002-10-10T12:00:00Z\",\"2002-10-10T12:00:00Z\",\"2002-10-10T12:00:00Z\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#dateTime,value=2002-10-10T12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#dateTime,value=2002-10-10T12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#dateTime,value=2002-10-10T12:00:00Z}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"dateTime\", " +

+	    			"\"Value\"	: [ \"2002-10-10T12:00:00Z\",\"2002-10-10T12:00:00Z\",\"2002-10-10T12:00:00Z\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#dateTime,value=2002-10-10T12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#dateTime,value=2002-10-10T12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#dateTime,value=2002-10-10T12:00:00Z}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#dateTime\", " +

+	    			"\"Value\"	: [ \"2002-10-10T12:00:00Z\",\"not a dateTime\",\"2002-10-10T12:00:00Z\" ] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#dateTime\", " +

+	    			"\"Value\"	: [ \"2002-10-10T12:00:00Z\",true,\"2002-10-10T12:00:00Z\" ] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#dateTime\", " +

+	    			"\"Value\"	: [ \"2002-10-10T12:00:00Z\",123,\"2002-10-10T12:00:00Z\" ] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#dateTime\", " +

+	    			"\"Value\"	: [ \"2002-10-10T12:00:00Z\",12.34,\"2002-10-10T12:00:00Z\" ] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		

+		// dayTimeDuration

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#dayTimeDuration\", " +

+	    			"\"Value\"	: [ \"P23DT7H12M54S\",\"P23DT7H12M54S\",\"P23DT7H12M54S\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#dayTimeDuration,value={super={durationSign=1years=0months=0days=23hours=7minutes=12seconds=54millis=0},factionalSeconds=54.0}}{dataTypeId=http://www.w3.org/2001/XMLSchema#dayTimeDuration,value={super={durationSign=1years=0months=0days=23hours=7minutes=12seconds=54millis=0},factionalSeconds=54.0}}{dataTypeId=http://www.w3.org/2001/XMLSchema#dayTimeDuration,value={super={durationSign=1years=0months=0days=23hours=7minutes=12seconds=54millis=0},factionalSeconds=54.0}}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"dayTimeDuration\", " +

+	    			"\"Value\"	: [ \"P23DT7H12M54S\",\"P23DT7H12M54S\",\"P23DT7H12M54S\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#dayTimeDuration,value={super={durationSign=1years=0months=0days=23hours=7minutes=12seconds=54millis=0},factionalSeconds=54.0}}{dataTypeId=http://www.w3.org/2001/XMLSchema#dayTimeDuration,value={super={durationSign=1years=0months=0days=23hours=7minutes=12seconds=54millis=0},factionalSeconds=54.0}}{dataTypeId=http://www.w3.org/2001/XMLSchema#dayTimeDuration,value={super={durationSign=1years=0months=0days=23hours=7minutes=12seconds=54millis=0},factionalSeconds=54.0}}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#dayTimeDuration\", " +

+	    			"\"Value\"	: [ \"P23DT7H12M54S\",\"not a duration\",\"P23DT7H12M54S\" ] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#dayTimeDuration\", " +

+	    			"\"Value\"	: [ \"P23DT7H12M54S\",true,\"P23DT7H12M54S\" ] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#dayTimeDuration\", " +

+	    			"\"Value\"	: [ \"P23DT7H12M54S\",123,\"P23DT7H12M54S\" ] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#dayTimeDuration\", " +

+	    			"\"Value\"	: [ \"P23DT7H12M54S\",11.22,\"P23DT7H12M54S\" ] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		

+		// yearMonth duration

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#yearMonthDuration\", " +

+	    			"\"Value\"	: [ \"P165Y8M\",\"P165Y8M\",\"P165Y8M\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#yearMonthDuration,value={super={durationSign=1years=165months=8days=0hours=0minutes=0seconds=0millis=0},monthsDuration=1988}}{dataTypeId=http://www.w3.org/2001/XMLSchema#yearMonthDuration,value={super={durationSign=1years=165months=8days=0hours=0minutes=0seconds=0millis=0},monthsDuration=1988}}{dataTypeId=http://www.w3.org/2001/XMLSchema#yearMonthDuration,value={super={durationSign=1years=165months=8days=0hours=0minutes=0seconds=0millis=0},monthsDuration=1988}}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"yearMonthDuration\", " +

+	    			"\"Value\"	: [ \"P165Y8M\",\"P165Y8M\",\"P165Y8M\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#yearMonthDuration,value={super={durationSign=1years=165months=8days=0hours=0minutes=0seconds=0millis=0},monthsDuration=1988}}{dataTypeId=http://www.w3.org/2001/XMLSchema#yearMonthDuration,value={super={durationSign=1years=165months=8days=0hours=0minutes=0seconds=0millis=0},monthsDuration=1988}}{dataTypeId=http://www.w3.org/2001/XMLSchema#yearMonthDuration,value={super={durationSign=1years=165months=8days=0hours=0minutes=0seconds=0millis=0},monthsDuration=1988}}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#yearMonthDuration\", " +

+	    			"\"Value\"	: [ \"P165Y8M\",\"not a duration\",\"P165Y8M\" ] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#yearMonthDuration\", " +

+	    			"\"Value\"	: [ \"P165Y8M\",true,\"P165Y8M\" ] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#yearMonthDuration\", " +

+	    			"\"Value\"	: [ \"P165Y8M\",123,\"P165Y8M\" ] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#yearMonthDuration\", " +

+	    			"\"Value\"	: [ \"P165Y8M\",11.22,\"P165Y8M\" ] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		

+		// anyURI

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#anyURI\", " +

+	    			"\"Value\"	: [ \"aValue\",\"aValue\",\"aValue\"] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"anyURI\", " +

+	    			"\"Value\"	: [ \"aValue\",\"aValue\",\"aValue\"] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// SUCCESSFUL AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#anyURI\", " +

+	    			"\"Value\"	: [ \"aValue\",true,\"aValue\"] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// SUCCESSFUL AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#anyURI\", " +

+	    			"\"Value\"	: [ \"aValue\",123,\"aValue\"] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#anyURI\", " +

+	    			"\"Value\"	: [ \"aValue\",11.111,\"aValue\"] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=11.111}{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		

+		// hexBinary

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#hexBinary\", " +

+	    			"\"Value\"	: [ \"FA027B7D12CC34DDD20012AEEF\",\"FA027B7D12CC34DDD20012AEEF\",\"FA027B7D12CC34DDD20012AEEF\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#hexBinary,value={data=[-6,2,123,125,18,-52,52,-35,-46,0,18,-82,-17]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#hexBinary,value={data=[-6,2,123,125,18,-52,52,-35,-46,0,18,-82,-17]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#hexBinary,value={data=[-6,2,123,125,18,-52,52,-35,-46,0,18,-82,-17]}}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"hexBinary\", " +

+	    			"\"Value\"	: [ \"FA027B7D12CC34DDD20012AEEF\",\"FA027B7D12CC34DDD20012AEEF\",\"FA027B7D12CC34DDD20012AEEF\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#hexBinary,value={data=[-6,2,123,125,18,-52,52,-35,-46,0,18,-82,-17]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#hexBinary,value={data=[-6,2,123,125,18,-52,52,-35,-46,0,18,-82,-17]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#hexBinary,value={data=[-6,2,123,125,18,-52,52,-35,-46,0,18,-82,-17]}}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#hexBinary\", " +

+	    			"\"Value\"	: [ \"FA027B7D12CC34DDD20012AEEF\",true,\"012AEEF\" ] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#hexBinary\", " +

+	    			"\"Value\"	: [ \"FA027B7D12CC34DDD20012AEEF\",123,\"012AEEF\" ] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#hexBinary\", " +

+	    			"\"Value\"	: [ \"FA027B7D12CC34DDD20012AEEF\",11.44,\"012AEEF\" ] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		

+		// base64Binary

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#base64Binary\", " +

+	    			"\"Value\"	: [ \"aG9y\",\"lvbj0iMS4xIj48YXV0aG9y\",\"lvbjIj48YXV0aG9y\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[104,111,114]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-106,-10,-29,-46,35,18,-29,18,35,-29,-58,23,87,70,-122,-9]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-106,-10,-29,34,62,60,97,117,116,104,111,114]}}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"base64Binary\", " +

+	    			"\"Value\"	: [ \"aG9y\",\"lvbj0iMS4xIj48YXV0aG9y\",\"lvbjIj48YXV0aG9y\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[104,111,114]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-106,-10,-29,-46,35,18,-29,18,35,-29,-58,23,87,70,-122,-9]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-106,-10,-29,34,62,60,97,117,116,104,111,114]}}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#base64Binary\", " +

+	    			"\"Value\"	: [ \"aG9y\",true,\"lvbjIj48YXV0aG9y\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[104,111,114]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-74,-69,-98]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-106,-10,-29,34,62,60,97,117,116,104,111,114]}}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#base64Binary\", " +

+	    			"\"Value\"	: [ \"aG9y\",1123,\"lvbjIj48YXV0aG9y\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[104,111,114]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-41,93,-73]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-106,-10,-29,34,62,60,97,117,116,104,111,114]}}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#base64Binary\", " +

+	    			"\"Value\"	: [ \"aG9y\",11.22,\"lvbjIj48YXV0aG9y\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[104,111,114]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-41,93,-74]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-106,-10,-29,34,62,60,97,117,116,104,111,114]}}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		

+		// RFC822 name

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name\", " +

+	    			"\"Value\"	: [ \"sne.else@A.COMPANY.com\",\"one.else@A.COMPANY.com\",\"someone.else@A.CONY.com\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name,value={localName=sne.else,domainName=A.COMPANY.com}}{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name,value={localName=one.else,domainName=A.COMPANY.com}}{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name,value={localName=someone.else,domainName=A.CONY.com}}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"rfc822Name\", " +

+	    			"\"Value\"	: [ \"sne.else@A.COMPANY.com\",\"one.else@A.COMPANY.com\",\"someone.else@A.CONY.com\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name,value={localName=sne.else,domainName=A.COMPANY.com}}{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name,value={localName=one.else,domainName=A.COMPANY.com}}{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name,value={localName=someone.else,domainName=A.CONY.com}}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name\", " +

+	    			"\"Value\"	: [ \"sne.else@A.COMPANY.com\",\"not a dns\",\"someone.else@A.CONY.com\" ] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name\", " +

+	    			"\"Value\"	: [ \"sne.else@A.COMPANY.com\",true,\"someone.else@A.CONY.com\" ] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name\", " +

+	    			"\"Value\"	: [ \"sne.else@A.COMPANY.com\",111,\"someone.else@A.CONY.com\" ] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name\", " +

+	    			"\"Value\"	: [ \"sne.else@A.COMPANY.com\",11.22,\"someone.else@A.CONY.com\" ] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		

+		// x500

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"urn:oasis:names:tc:xacml:1.0:data-type:x500Name\", " +

+	    			"\"Value\"	: [ \"cn=Julius Hibbert, o=Medi Corporation, c=US\", \"cn=Julius Hibbert, o=Medi Corporation, c=US\", \"cn=Julius Hibbert, o=Medi Corporation, c=US\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:x500Name,value=CN=Julius Hibbert, O=Medi Corporation, C=US}{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:x500Name,value=CN=Julius Hibbert, O=Medi Corporation, C=US}{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:x500Name,value=CN=Julius Hibbert, O=Medi Corporation, C=US}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"x500Name\", " +

+	    			"\"Value\"	: [ \"cn=Julius Hibbert, o=Medi Corporation, c=US\", \"cn=Julius Hibbert, o=Medi Corporation, c=US\", \"cn=Julius Hibbert, o=Medi Corporation, c=US\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:x500Name,value=CN=Julius Hibbert, O=Medi Corporation, C=US}{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:x500Name,value=CN=Julius Hibbert, O=Medi Corporation, C=US}{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:x500Name,value=CN=Julius Hibbert, O=Medi Corporation, C=US}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"urn:oasis:names:tc:xacml:1.0:data-type:x500Name\", " +

+	    			"\"Value\"	: [ \"cn=Julius Hibbert, o=Medi Corporation, c=US\", \"non-x500 string\", \"cn=Julius Hibbert, o=Medi Corporation, c=US\" ] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"urn:oasis:names:tc:xacml:1.0:data-type:x500Name\", " +

+	    			"\"Value\"	: [ \"cn=Julius Hibbert, o=Medi Corporation, c=US\", true, \"cn=Julius Hibbert, o=Medi Corporation, c=US\" ] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"urn:oasis:names:tc:xacml:1.0:data-type:x500Name\", " +

+	    			"\"Value\"	: [ \"cn=Julius Hibbert, o=Medi Corporation, c=US\", 1111, \"cn=Julius Hibbert, o=Medi Corporation, c=US\" ] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"urn:oasis:names:tc:xacml:1.0:data-type:x500Name\", " +

+	    			"\"Value\"	: [ \"cn=Julius Hibbert, o=Medi Corporation, c=US\", 11.22, \"cn=Julius Hibbert, o=Medi Corporation, c=US\" ] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		

+		// ipAddress

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"urn:oasis:names:tc:xacml:2.0:data-type:ipAddress\", " +

+	    			"\"Value\"	: [ \"121.221.43.58:12345\",\"121.221.43.58:12345\",\"121.221.43.58:12345\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:ipAddress,value=121.221.43.58:12345-12345}{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:ipAddress,value=121.221.43.58:12345-12345}{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:ipAddress,value=121.221.43.58:12345-12345}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"ipAddress\", " +

+	    			"\"Value\"	: [ \"121.221.43.58:12345\",\"121.221.43.58:12345\",\"121.221.43.58:12345\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:ipAddress,value=121.221.43.58:12345-12345}{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:ipAddress,value=121.221.43.58:12345-12345}{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:ipAddress,value=121.221.43.58:12345-12345}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"urn:oasis:names:tc:xacml:2.0:data-type:ipAddress\", " +

+	    			"\"Value\"	: [ \"121.221.43.58:12345\",\"not an ip address\",\"121.221.43.58:12345\" ] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"urn:oasis:names:tc:xacml:2.0:data-type:ipAddress\", " +

+	    			"\"Value\"	: [ \"121.221.43.58:12345\",true,\"121.221.43.58:12345\" ] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"urn:oasis:names:tc:xacml:2.0:data-type:ipAddress\", " +

+	    			"\"Value\"	: [ \"121.221.43.58:12345\",1111,\"121.221.43.58:12345\" ] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"urn:oasis:names:tc:xacml:2.0:data-type:ipAddress\", " +

+	    			"\"Value\"	: [ \"121.221.43.58:12345\",11.22,\"121.221.43.58:12345\" ] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		

+		// dnsName

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"urn:oasis:names:tc:xacml:2.0:data-type:dnsName\", " +

+	    			"\"Value\"	: [ \"aValue\", \"aValue\", \"aValue\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:dnsName,value={domainName=aValue}}{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:dnsName,value={domainName=aValue}}{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:dnsName,value={domainName=aValue}}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"dnsName\", " +

+	    			"\"Value\"	: [ \"aValue\", \"aValue\", \"aValue\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:dnsName,value={domainName=aValue}}{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:dnsName,value={domainName=aValue}}{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:dnsName,value={domainName=aValue}}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"urn:oasis:names:tc:xacml:2.0:data-type:dnsName\", " +

+	    			"\"Value\"	: [ \"aValue\", true, \"aValue\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:dnsName,value={domainName=aValue}}{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:dnsName,value={domainName=true}}{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:dnsName,value={domainName=aValue}}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"urn:oasis:names:tc:xacml:2.0:data-type:dnsName\", " +

+	    			"\"Value\"	: [ \"aValue\", 1111, \"aValue\" ] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"urn:oasis:names:tc:xacml:2.0:data-type:dnsName\", " +

+	    			"\"Value\"	: [ \"aValue\", 11.22, \"aValue\" ] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		

+		// xPathExpression

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\", " +

+	    			"\"Value\"	: [ "

+	    			+ "{" +

+	    				"\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +

+	    				"\"Namespaces\" : ["

+	    					+ "{ "+

+    							"\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " +

+    							"}," +

+    							"{" +

+    								"\"Prefix\" : \"md\", " +

+    								"\"Namespace\" : \"urn:example:med:schemas:record\" " +

+    							"}], "+

+    					"\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+

+            		"}," +

+            		"{" +

+    	    				"\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +

+    	    				"\"Namespaces\" : ["

+    	    					+ "{ "+

+        							"\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " +

+        							"}," +

+        							"{" +

+        								"\"Prefix\" : \"md\", " +

+        								"\"Namespace\" : \"urn:example:med:schemas:record\" " +

+        							"}], "+

+        					"\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+

+                		"}," +

+                		"{" +

+        	    				"\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +

+        	    				"\"Namespaces\" : ["

+        	    					+ "{ "+

+            							"\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " +

+            							"}," +

+            							"{" +

+            								"\"Prefix\" : \"md\", " +

+            								"\"Namespace\" : \"urn:example:med:schemas:record\" " +

+            							"}], "+

+            					"\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+

+                    		"}"

+	    			+ "] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource,values=[{dataTypeId=urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression,value={path=md:record/md:patient/md:patientDoB,Namespace={[{md,urn:example:med:schemas:record}{urn:oasis:names:tc:xacml:3.0:core:schema:wd-17}]},status=null,xpathExpressionWrapped=null},xpathCategory=urn:oasis:names:tc:xacml:3.0:attribute-category:resource}{dataTypeId=urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression,value={path=md:record/md:patient/md:patientDoB,Namespace={[{md,urn:example:med:schemas:record}{urn:oasis:names:tc:xacml:3.0:core:schema:wd-17}]},status=null,xpathExpressionWrapped=null},xpathCategory=urn:oasis:names:tc:xacml:3.0:attribute-category:resource}{dataTypeId=urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression,value={path=md:record/md:patient/md:patientDoB,Namespace={[{md,urn:example:med:schemas:record}{urn:oasis:names:tc:xacml:3.0:core:schema:wd-17}]},status=null,xpathExpressionWrapped=null},xpathCategory=urn:oasis:names:tc:xacml:3.0:attribute-category:resource}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\", " +

+	    			"\"Value\"	: [ "

+	    			+ "{" +

+	    				"\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +

+	    				"\"Namespaces\" : ["

+	    					+ "{ "+

+    							"\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " +

+    							"}," +

+    							"{" +

+    								"\"Prefix\" : \"md\", " +

+    								"\"Namespace\" : \"urn:example:med:schemas:record\" " +

+    							"}], "+

+    					"\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+

+            		"}," +

+            		"\"simpleString\"," +

+                		"{" +

+        	    				"\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +

+        	    				"\"Namespaces\" : ["

+        	    					+ "{ "+

+            							"\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " +

+            							"}," +

+            							"{" +

+            								"\"Prefix\" : \"md\", " +

+            								"\"Namespace\" : \"urn:example:med:schemas:record\" " +

+            							"}], "+

+            					"\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+

+                    		"}"

+	    			+ "] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\", " +

+	    			"\"Value\"	: [ "

+	    			+ "{" +

+	    				"\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +

+	    				"\"Namespaces\" : ["

+	    					+ "{ "+

+    							"\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " +

+    							"}," +

+    							"{" +

+    								"\"Prefix\" : \"md\", " +

+    								"\"Namespace\" : \"urn:example:med:schemas:record\" " +

+    							"}], "+

+    					"\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+

+            		"}," +

+            		"true," +

+                		"{" +

+        	    				"\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +

+        	    				"\"Namespaces\" : ["

+        	    					+ "{ "+

+            							"\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " +

+            							"}," +

+            							"{" +

+            								"\"Prefix\" : \"md\", " +

+            								"\"Namespace\" : \"urn:example:med:schemas:record\" " +

+            							"}], "+

+            					"\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+

+                    		"}"

+	    			+ "] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\", " +

+	    			"\"Value\"	: [ "

+	    			+ "{" +

+	    				"\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +

+	    				"\"Namespaces\" : ["

+	    					+ "{ "+

+    							"\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " +

+    							"}," +

+    							"{" +

+    								"\"Prefix\" : \"md\", " +

+    								"\"Namespace\" : \"urn:example:med:schemas:record\" " +

+    							"}], "+

+    					"\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+

+            		"}," +

+            		"123," +

+                		"{" +

+        	    				"\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +

+        	    				"\"Namespaces\" : ["

+        	    					+ "{ "+

+            							"\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " +

+            							"}," +

+            							"{" +

+            								"\"Prefix\" : \"md\", " +

+            								"\"Namespace\" : \"urn:example:med:schemas:record\" " +

+            							"}], "+

+            					"\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+

+                    		"}"

+	    			+ "] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\", " +

+	    			"\"Value\"	: [ "

+	    			+ "{" +

+	    				"\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +

+	    				"\"Namespaces\" : ["

+	    					+ "{ "+

+    							"\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " +

+    							"}," +

+    							"{" +

+    								"\"Prefix\" : \"md\", " +

+    								"\"Namespace\" : \"urn:example:med:schemas:record\" " +

+    							"}], "+

+    					"\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+

+            		"}," +

+            		"12.34," +

+                		"{" +

+        	    				"\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +

+        	    				"\"Namespaces\" : ["

+        	    					+ "{ "+

+            							"\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " +

+            							"}," +

+            							"{" +

+            								"\"Prefix\" : \"md\", " +

+            								"\"Namespace\" : \"urn:example:med:schemas:record\" " +

+            							"}], "+

+            					"\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+

+                    		"}"

+	    			+ "] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+

+	}

+	

+

+	

+	

+	

+	

+	

+	@Test

+	public void testArrayNoDataTypes() {

+		

+		// array of size 0

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		

+		// Category Attribute value array DataType Not given (repeat for all data types)

+		// Also tests for mixes of different JSON types (trying incorrect strings for XACML data types whenever possible)

+		// string

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [\"abc\", \"def\", \"hig\", \"lmn\"] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=def}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=hig}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lmn}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// SUCCESSFUL AUTO-CONVERT to DataType

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [\"abc\", true, \"hig\", \"lmn\"] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=hig}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lmn}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// SUCCESSFUL AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [\"abc\",123, \"hig\", \"lmn\"] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=hig}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lmn}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// SUCCESSFUL AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [\"abc\", 34.34, \"hig\", \"lmn\"] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=34.34}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=hig}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lmn}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		

+		// boolean

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [true, true, false, true, false ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=false}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=false}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [true, \"abc\", false, true, false ] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [true, 123, false, true, false ] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [true, 12.34, false, true, false ] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		

+		

+		// integer

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [123, 456, 765, 234] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=456}{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=765}{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=234}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [123, \"abc\", 765, 234] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [123, true, 765, 234] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+

+		

+		

+		// double

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ 123.34, 543.54, 3445.455, 4543,543 ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=123.34}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=543.54}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=3445.455}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=4543.0}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=543.0}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// special case - auto-convert integer to boolean

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ 123.34, 111122, 3445.455, 4543,543 ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=123.34}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=111122.0}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=3445.455}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=4543.0}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=543.0}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ 123.34, true, 3445.455, 4543,543 ] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ 123.34, \"abb\", 3445.455, 4543,543 ] " +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		

+		// time - defaults to String

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"12:00:00Z\", \"12:00:00Z\", \"12:00:00Z\"] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12:00:00Z}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// SUCCESSFUL AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"12:00:00Z\", true, \"12:00:00Z\"] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12:00:00Z}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// SUCCESSFUL AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"12:00:00Z\", 123, \"12:00:00Z\"] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12:00:00Z}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"12:00:00Z\", 12.34, \"12:00:00Z\"] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12.34}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12:00:00Z}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		

+		// date - defaults to String

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [\"2002-10-10\",\"2002-10-10\",\"2002-10-10\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [\"2002-10-10\",true,\"2002-10-10\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [\"2002-10-10\",123,\"2002-10-10\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [\"2002-10-10\",123.45,\"2002-10-10\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123.45}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		

+		// dateTime - defaults to String

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"2002-10-10T12:00:00Z\",\"2002-10-10T12:00:00Z\",\"2002-10-10T12:00:00Z\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10T12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10T12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10T12:00:00Z}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"2002-10-10T12:00:00Z\",true,\"2002-10-10T12:00:00Z\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10T12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10T12:00:00Z}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"2002-10-10T12:00:00Z\",123,\"2002-10-10T12:00:00Z\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10T12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10T12:00:00Z}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"2002-10-10T12:00:00Z\",12.34,\"2002-10-10T12:00:00Z\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10T12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12.34}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10T12:00:00Z}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		

+		// dayTimeDuration - defaults to String

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"P23DT7H12M54S\",\"P23DT7H12M54S\",\"P23DT7H12M54S\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P23DT7H12M54S}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P23DT7H12M54S}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P23DT7H12M54S}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		//AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"P23DT7H12M54S\",true,\"P23DT7H12M54S\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P23DT7H12M54S}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P23DT7H12M54S}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"P23DT7H12M54S\",123,\"P23DT7H12M54S\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P23DT7H12M54S}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P23DT7H12M54S}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"P23DT7H12M54S\",11.22,\"P23DT7H12M54S\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P23DT7H12M54S}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=11.22}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P23DT7H12M54S}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		

+		// yearMonth duration - defaults to String

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"P165Y8M\",\"P165Y8M\",\"P165Y8M\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P165Y8M}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P165Y8M}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P165Y8M}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"P165Y8M\",true,\"P165Y8M\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P165Y8M}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P165Y8M}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"P165Y8M\",123,\"P165Y8M\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P165Y8M}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P165Y8M}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"P165Y8M\",11.22,\"P165Y8M\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P165Y8M}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=11.22}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P165Y8M}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		

+		// anyURI - defaults to String

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"aValue\",\"aValue\",\"aValue\"] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"aValue\",true,\"aValue\"] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"aValue\",123,\"aValue\"] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"aValue\",11.111,\"aValue\"] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=11.111}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		

+		// hexBinary - defaults to String

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"FA027B7D12CC34DDD20012AEEF\",\"FA027B7D12CC34DDD20012AEEF\",\"FA027B7D12CC34DDD20012AEEF\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=FA027B7D12CC34DDD20012AEEF}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=FA027B7D12CC34DDD20012AEEF}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=FA027B7D12CC34DDD20012AEEF}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"FA027B7D12CC34DDD20012AEEF\",true,\"012AEEF\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=FA027B7D12CC34DDD20012AEEF}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=012AEEF}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"FA027B7D12CC34DDD20012AEEF\",123,\"012AEEF\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=FA027B7D12CC34DDD20012AEEF}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=012AEEF}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"FA027B7D12CC34DDD20012AEEF\",11.44,\"012AEEF\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=FA027B7D12CC34DDD20012AEEF}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=11.44}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=012AEEF}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		

+		// base64Binary - defaults to String

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"aG9y\",\"lvbj0iMS4xIj48YXV0aG9y\",\"lvbjIj48YXV0aG9y\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aG9y}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lvbj0iMS4xIj48YXV0aG9y}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lvbjIj48YXV0aG9y}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"aG9y\",true,\"lvbjIj48YXV0aG9y\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aG9y}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lvbjIj48YXV0aG9y}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"aG9y\",1123,\"lvbjIj48YXV0aG9y\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aG9y}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=1123}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lvbjIj48YXV0aG9y}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"aG9y\",11.22,\"lvbjIj48YXV0aG9y\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aG9y}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=11.22}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lvbjIj48YXV0aG9y}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// RFC822 name - defaults to String

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"sne.else@A.COMPANY.com\",\"one.else@A.COMPANY.com\",\"someone.else@A.CONY.com\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=sne.else@A.COMPANY.com}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=one.else@A.COMPANY.com}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=someone.else@A.CONY.com}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"sne.else@A.COMPANY.com\",true,\"someone.else@A.CONY.com\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=sne.else@A.COMPANY.com}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=someone.else@A.CONY.com}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"sne.else@A.COMPANY.com\",111,\"someone.else@A.CONY.com\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=sne.else@A.COMPANY.com}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=111}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=someone.else@A.CONY.com}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"sne.else@A.COMPANY.com\",11.22,\"someone.else@A.CONY.com\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=sne.else@A.COMPANY.com}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=11.22}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=someone.else@A.CONY.com}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		

+		// x500 - defaults to String

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"cn=Julius Hibbert, o=Medi Corporation, c=US\", \"cn=Julius Hibbert, o=Medi Corporation, c=US\", \"cn=Julius Hibbert, o=Medi Corporation, c=US\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=cn=Julius Hibbert, o=Medi Corporation, c=US}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=cn=Julius Hibbert, o=Medi Corporation, c=US}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=cn=Julius Hibbert, o=Medi Corporation, c=US}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"cn=Julius Hibbert, o=Medi Corporation, c=US\", true, \"cn=Julius Hibbert, o=Medi Corporation, c=US\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=cn=Julius Hibbert, o=Medi Corporation, c=US}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=cn=Julius Hibbert, o=Medi Corporation, c=US}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"cn=Julius Hibbert, o=Medi Corporation, c=US\", 1111, \"cn=Julius Hibbert, o=Medi Corporation, c=US\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=cn=Julius Hibbert, o=Medi Corporation, c=US}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=1111}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=cn=Julius Hibbert, o=Medi Corporation, c=US}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"cn=Julius Hibbert, o=Medi Corporation, c=US\", 11.22, \"cn=Julius Hibbert, o=Medi Corporation, c=US\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=cn=Julius Hibbert, o=Medi Corporation, c=US}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=11.22}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=cn=Julius Hibbert, o=Medi Corporation, c=US}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		

+		// ipAddress - defaults to String

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"121.221.43.58:12345\",\"121.221.43.58:12345\",\"121.221.43.58:12345\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=121.221.43.58:12345}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=121.221.43.58:12345}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=121.221.43.58:12345}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"121.221.43.58:12345\",true,\"121.221.43.58:12345\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=121.221.43.58:12345}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=121.221.43.58:12345}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"121.221.43.58:12345\",1111,\"121.221.43.58:12345\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=121.221.43.58:12345}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=1111}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=121.221.43.58:12345}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"121.221.43.58:12345\",11.22,\"121.221.43.58:12345\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=121.221.43.58:12345}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=11.22}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=121.221.43.58:12345}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		

+		// dnsName - defaults to String

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"aValue\", \"aValue\", \"aValue\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"aValue\", true, \"aValue\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"aValue\", 1111, \"aValue\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=1111}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"aValue\", 11.22, \"aValue\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=11.22}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		

+		// xPathExpression - defaults to String

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"aValue\", \"aValue\", \"aValue\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"aValue\", true, \"aValue\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"aValue\", 1111, \"aValue\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=1111}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		// AUTO-CONVERT

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"aValue\", 11.22, \"aValue\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=11.22}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+	}

+	

+	

+

+	

+	@Test

+	public void testXPathExpression() {

+		// Category Attribute with XPathExpression including XPathCategory and XPath

+		// Category Attribute with XPathExpression with Namespaces with/without Prefix

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"xpathExpression\", " +

+	    			"\"Value\"	: {" +

+	    				"\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +

+	    				"\"Namespaces\" : ["

+	    				  + "{ "+

+	    						"\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " +

+	    					"}," +

+	    					"{ "+

+    							"\"Prefix\" : \"lab\", " +

+    							"\"Namespace\" : \"http://somewhere/uri.html\" " +

+    						"}," +

+	    					"{" +

+	    						"\"Prefix\" : \"md\", " +

+	    						"\"Namespace\" : \"urn:example:med:schemas:record\" " +

+	    					"}], "+

+	    				"\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+

+            		"}" +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression,value={path=md:record/md:patient/md:patientDoB,Namespace={[{md,urn:example:med:schemas:record}{lab,http://somewhere/uri.html}{urn:oasis:names:tc:xacml:3.0:core:schema:wd-17}]},status=null,xpathExpressionWrapped=null},xpathCategory=urn:oasis:names:tc:xacml:3.0:attribute-category:resource}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// Category Attribute with XPathExpression missing XPathCategory

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"xpathExpression\", " +

+	    			"\"Value\"	: {" +

+	    				"\"Namespaces\" : [{ "+

+	    						"\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " +

+	    					"}," +

+	    					"{" +

+	    						"\"Prefix\" : \"md\", " +

+	    						"\"Namespace\" : \"urn:example:med:schemas:record\" " +

+	    					"}], "+

+	    				"\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+

+            		"}" +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// Category Attribute with XPathExpression missing XPath

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"xpathExpression\", " +

+	    			"\"Value\"	: {" +

+	    				"\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +

+	    				"\"Namespaces\" : [{ "+

+	    						"\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " +

+	    					"}," +

+	    					"{" +

+	    						"\"Prefix\" : \"md\", " +

+	    						"\"Namespace\" : \"urn:example:med:schemas:record\" " +

+	    					"}] "+

+            		"}" +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// Category Attribute with XPathExpression without Namespaces

+		// (path does not contain namespace references)

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"xpathExpression\", " +

+	    			"\"Value\"	: {" +

+	    				"\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +

+	    				"\"XPath\" : \"record/patient/patientDoB\" "+

+            		"}" +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression,value={path=record/patient/patientDoB,Namespace=null,status=null,xpathExpressionWrapped=null},xpathCategory=urn:oasis:names:tc:xacml:3.0:attribute-category:resource}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// Category Attribute with XPathExpression with 0 Namespaces

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"xpathExpression\", " +

+	    			"\"Value\"	: {" +

+	    				"\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +

+	    				"\"Namespaces\" : [], "+

+	    				"\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+

+            		"}" +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression,value={path=md:record/md:patient/md:patientDoB,Namespace=null,status=null,xpathExpressionWrapped=null},xpathCategory=urn:oasis:names:tc:xacml:3.0:attribute-category:resource}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		

+		// Category Attribute with XPathExpression with Namespaces without mandatory Namespace

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"xpathExpression\", " +

+	    			"\"Value\"	: {" +

+	    				"\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +

+	    				"\"Namespaces\" : [{ "+

+	    						"\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " +

+	    					"}," +

+	    					"{" +

+	    						"\"Prefix\" : \"md\", " +

+	    					"}], "+

+	    				"\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+

+            		"}" +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"xpathExpression\", " +

+	    			"\"Value\"	: {" +

+	    				"\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +

+	    				"\"Namespaces\" : [{ "+

+	    					"}," +

+	    					"{" +

+	    						"\"Prefix\" : \"md\", " +

+	    						"\"Namespace\" : \"urn:example:med:schemas:record\" " +

+	    					"}], "+

+	    				"\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+

+            		"}" +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+				

+		// Category Attribute with XPathExpression with Namespaces with 2 namespaces using same prefix

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"xpathExpression\", " +

+	    			"\"Value\"	: {" +

+	    				"\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +

+	    				"\"Namespaces\" : [{ "+

+							"\"Prefix\" : \"md\", " +

+	    						"\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " +

+	    					"}," +

+	    					"{" +

+	    						"\"Prefix\" : \"md\", " +

+	    						"\"Namespace\" : \"urn:example:med:schemas:record\" " +

+	    					"}], "+

+	    				"\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+

+            		"}" +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// Category Attribute with XPathExpression without Namespaces which are used within the XPathExpression (NOTE: Error is not syntactic and is not found by converter)

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"xpathExpression\", " +

+	    			"\"Value\"	: {" +

+	    				"\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +

+	    				"\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+

+            		"}" +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression,value={path=md:record/md:patient/md:patientDoB,Namespace=null,status=null,xpathExpressionWrapped=null},xpathCategory=urn:oasis:names:tc:xacml:3.0:attribute-category:resource}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// Category Attribute with XPathExpression containing simple value (must be object)

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"xpathExpression\", " +

+	    			"\"Value\"	: \"simple Value\"" +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// Category Attribute with Namespaces containing simple value (must be object)

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"xpathExpression\", " +

+	    			"\"Value\"	: {" +

+	    				"\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +

+	    				"\"Namespaces\" : [ \"simpleValue\"," +

+	    					"{" +

+	    						"\"Prefix\" : \"md\", " +

+	    						"\"Namespace\" : \"urn:example:med:schemas:record\" " +

+	    					"}], "+

+	    				"\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+

+            		"}" +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		

+		// Category Attribute with Namespaces non-string Namespace

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"xpathExpression\", " +

+	    			"\"Value\"	: {" +

+	    				"\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +

+	    				"\"Namespaces\" : [ {" +

+	    						"\"Prefix\" : \"md\", " +

+	    						"\"Namespace\" : 123 " +

+	    					"}], "+

+	    				"\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+

+            		"}" +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// Category Attribute with Namespaces non-string prefix

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"xpathExpression\", " +

+	    			"\"Value\"	: {" +

+	    				"\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +

+	    				"\"Namespaces\" : [ {" +

+	    						"\"Prefix\" : 123, " +

+	    						"\"Namespace\" : \"urn:example:med:schemas:record\" " +

+	    					"}], "+

+	    				"\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+

+            		"}" +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// Category Attribute with Namespaces non-string XPathCategory

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"xpathExpression\", " +

+	    			"\"Value\"	: {" +

+	    				"\"XPathCategory\" : 123," +

+	    				"\"Namespaces\" : [ {" +

+	    						"\"Prefix\" : \"md\", " +

+	    						"\"Namespace\" : \"urn:example:med:schemas:record\" " +

+	    					"}], "+

+	    				"\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+

+            		"}" +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// Category Attribute with Namespaces non-string XPath

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"xpathExpression\", " +

+	    			"\"Value\"	: {" +

+	    				"\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +

+	    				"\"Namespaces\" : [ {" +

+	    						"\"Prefix\" : \"md\", " +

+	    						"\"Namespace\" : \"urn:example:med:schemas:record\" " +

+	    					"}], "+

+	    				"\"XPath\" : 123 "+

+            		"}" +

+					"}] } ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+	}

+

+

+	

+	@Test

+	public void testContent() {

+

+		// Category with Content in XML, escaped properly

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"aValue\",\"aValue\",\"aValue\"] " +

+	    			"}]," +

+					"\"Content\" : \"<?xml version=\\\"1.0\\\"?><catalog>" + 

+						"<book id=\\\"bk101\\\"><author>Gambardella, Matthew</author><title>XML Developer's Guide</title><genre>Computer</genre>" +

+						"<price>44.95</price><publish_date>2000-10-01</publish_date><description>An in-depth look at creating applications with XML.</description>"+

+						"</book></catalog>\"" +

+					"} ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]},contentRoot=[catalog: null]}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// Category with Content in XML, double quotes and back-slashes NOT escaped properly?

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"aValue\",\"aValue\",\"aValue\"] " +

+	    			"}]," +

+					"\"Content\" : \"<?xml version=\\\"1.0\\\"?><catalog>" + 

+						"<book id=\"bk101\\\"><author>Gambardella, Matthew</author><title>XML Developer's Guide</title><genre>Computer</genre>" +

+						"<price>44.95</price><publish_date>2000-10-01</publish_date><description>An in-depth look at creating applications with XML.</description>"+

+						"</book></catalog>\"" +

+					"} ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// Category with Content in Base64

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"aValue\",\"aValue\",\"aValue\"] " +

+	    			"}]," +

+					"\"Content\" :  \"PD94bWwgdmVyc2lvbj0iMS4wIj8+PGNhdGFsb2c+PGJvb2sgaWQ9ImJrMTAxIj48YXV0aG9yPkdhbWJhcmRlbGxhLCBNYXR0aGV3PC9hdXRob3I+PHRpdGxlPlhNT" +

+							"CBEZXZlbG9wZXIncyBHdWlkZTwvdGl0bGU+PGdlbnJlPkNvbXB1dGVyPC9nZW5yZT48cHJpY2U+NDQuOTU8L3ByaWNlPjxwdWJsaXNoX2RhdGU+MjAwMC0xMC0wMTwvcHVibGlzaF"+

+							"9kYXRlPjxkZXNjcmlwdGlvbj5BbiBpbi1kZXB0aCBsb29rIGF0IGNyZWF0aW5nIGFwcGxpY2F0aW9ucyB3aXRoIFhNTC48L2Rlc2NyaXB0aW9uPjwvYm9vaz48L2NhdGFsb2c+\"" +

+					"} ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]},contentRoot=[catalog: null]}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// Category with Bad Content in Base64

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"aValue\",\"aValue\",\"aValue\"] " +

+	    			"}]," +

+					"\"Content\" :  \"PD94bWwgdmV\"" +

+					"} ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+	}

+	

+

+	

+	

+	@Test

+	public void testDuplicates() {

+		// duplicate of same element within Category array is ok

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#string\", " +

+	    			"\"Value\"	: \"abc\" " +

+					"}] }, " +

+					"{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+			    			"\"Id\" : \"document-id\", " +

+			    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#string\", " +

+			    			"\"Value\"	: \"abc\" " +

+							"}] } "

+					+ "] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}],includeInResults=false}]}}{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// duplicate Attribute

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [" +

+					"{\"CategoryId\" : \"custom-category\","

+					+ " \"Attribute\" : [{" +

+			    			"\"Id\" : \"document-id\", " +

+			    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#string\", " +

+			    			"\"Value\"	: \"abc\" " +

+							"}], "

+					+ " \"Attribute\" : [{" +

+			    			"\"Id\" : \"document-id\", " +

+			    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#string\", " +

+			    			"\"Value\"	: \"abc\" " +

+							"}] "

+							+ "} "

+					+ " }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// dup id

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#string\", " +

+	    			"\"Value\"	: \"abc\" " +

+					"}] } " 

+					+ "] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// dup DataType

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#string\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#string\", " +

+	    			"\"Value\"	: \"abc\" " +

+					"}] } " 

+					+ "] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// dup Value

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"DataType\"	: \"http://www.w3.org/2001/XMLSchema#string\", " +

+	    			"\"Value\"	: \"abc\" " +

+	    			"\"Value\"	: \"abc\" " +

+					"}] } " 

+					+ "] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		

+		// duplicate Content

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{"

+					+ "\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    				"\"Id\" : \"document-id\", " +

+	    				"\"Value\"	: [ \"aValue\",\"aValue\",\"aValue\"] " +

+	    				"}]," +

+	    				"\"Content\" : \"<?xml version=\\\"1.0\\\"?><catalog>" + 

+							"<book id=\\\"bk101\\\"><author>Gambardella, Matthew</author><title>XML Developer's Guide</title><genre>Computer</genre>" +

+							"<price>44.95</price><publish_date>2000-10-01</publish_date><description>An in-depth look at creating applications with XML.</description>"+

+							"</book></catalog>\" , " +

+						"\"Content\" : \"<?xml version=\\\"1.0\\\"?><catalog>" + 

+							"<book id=\\\"bk101\\\"><author>Gambardella, Matthew</author><title>XML Developer's Guide</title><genre>Computer</genre>" +

+							"<price>44.95</price><publish_date>2000-10-01</publish_date><description>An in-depth look at creating applications with XML.</description>"+

+							"</book></catalog>\"" +

+					"} ] }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+	}

+	

+

+	

+//TODO - Shorthand for CategoryId ????

+	

+	

+}

diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/json/RequestConformanceTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/json/RequestConformanceTest.java
new file mode 100755
index 0000000..85c3bed
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/json/RequestConformanceTest.java
@@ -0,0 +1,349 @@
+/*

+ *                        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.std.json;

+

+import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.fail;

+

+import java.io.File;

+import java.io.StringWriter;

+import java.util.ArrayList;

+import java.util.Collection;

+import java.util.Iterator;

+import java.util.List;

+

+import javax.xml.transform.Transformer;

+import javax.xml.transform.TransformerFactory;

+import javax.xml.transform.dom.DOMSource;

+import javax.xml.transform.stream.StreamResult;

+

+import org.junit.Test;

+

+import com.att.research.xacml.api.Request;

+import com.att.research.xacml.api.RequestAttributes;

+import com.att.research.xacml.api.RequestReference;

+import com.att.research.xacml.std.dom.DOMRequest;

+import com.att.research.xacml.std.json.JSONRequest;

+import com.att.research.xacml.std.json.JSONStructureException;

+/**

+ * Test JSON Request convert to object - Conformance tests

+ * 

+ * TO RUN - use jUnit

+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test

+ * 

+ * NOTE:

+ * The "correct" way to verify that each JSON string gets translated into our internal Objects correctly is to look explicitly at each of the child objects

+ * and verify that they are correct.  This would involve a lot of coding to get child of child of child and individually verify each property of each element.

+ * To simplify testing we assume that request.toString() correctly includes a complete text representation of every sub-component of the Request object

+ * and we compare the resulting String to our expected String.

+ * This has two possible sources of error:

+ * 	- toString might not include some sub-component, and

+ * 	- the initial verification of the resulting string is done by hand and may have been incorrect.

+ * 

+ * @author glenngriffin

+ *

+ */

+public class RequestConformanceTest {

+	

+	// where to find the conformance test XML files

+	private final String CONFORMANCE_DIRECTORY_PATH = "testsets/conformance/xacml3.0-ct-v.0.4";

+	

+	// The request object output from each test conversion from JSON string

+	Request request;

+

+

+	

+	

+	

+	// test just one of each top-level element.

+	// For simple elements also test for incorrect type

+	@Test

+	public void testConformanceRequests() {

+		

+		List<File> filesInDirectory = null;

+		

+		File conformanceDirectory = null;

+		

+		File currentFile = null;

+		

+		try {

+			conformanceDirectory = new File(CONFORMANCE_DIRECTORY_PATH);

+			filesInDirectory = getRequestsInDirectory(conformanceDirectory);

+		} catch (Exception e) {

+			fail("Unable to set up Conformance tests for dir '" + conformanceDirectory.getAbsolutePath()+"' e="+ e);

+		}

+		

+		// run through each XML file

+		//	- load the file from XML into an internal Request object

+		//	- generate the JSON representation of that Request object

+		//	- load that JSON representation into a new Request object

+		//	- compare the 2 Request objects

+		Request xmlRequest = null;

+		Request jsonRequest = null;

+		try {

+			for (File f : filesInDirectory) {

+				currentFile = f;

+

+//// This is a simple way to select just one file for debugging - comment out when not being used

+//if ( ! f.getName().equals("IIA023Request.xml")) {   continue;  }

+

+// during debugging it is helpful to know what file it is starting to work on

+//				System.out.println("starting file="+currentFile.getName());

+				

+				try {

+					// load XML into a Request object

+					xmlRequest = DOMRequest.load(f);

+					xmlRequest.getStatus();

+				} catch (Exception e) {

+					// if XML does not load, just note it and continue with next file

+					System.out.println("XML file did not load: '" + f.getName() + "  e=" + e);

+					continue;

+				}

+				

+//System.out.println(JSONRequest.toString(xmlRequest, false));

+

+				// generate JSON from the Request

+				String jsonString = JSONRequest.toString(xmlRequest, false);

+				

+

+// single-value elements

+//jsonString = "{\"Request\":{\"Category\":[{\"CategoryId\":\"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\",\"Attribute\":["

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":\"Julius Hibbert\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"IncludeInResult\":\"true\",\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-id\"},"

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":123,\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-string\"},"

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":\"true\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#boolean\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-boolean\"},"

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":\"56\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#integer\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-integer\"},"

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":\"27.5\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#double\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-double\"},"

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":\"2002-03-22\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#date\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-date\"},"

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":\"2002-03-22T08:23:47-05:00\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#dateTime\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-dateTime\"},"

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":\"P50DT5H4M3S\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#dayTimeDuration\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-dayTimeDuration\"},"

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":\"-P5Y3M\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#yearMonthDuration\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-yearMonthDuration\"},"

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":\"0bf7a9876cde\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#hexBinary\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-hexBinary\"},"

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":\"c3VyZS4=\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#base64Binary\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-rfc822Name\"},"

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":\"j_hibbert@medico.com\",\"DataType\":\"urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-rfc822Name\"},"

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":\"CN=Julius Hibbert, O=Medi Corporation, C=US\",\"DataType\":\"urn:oasis:names:tc:xacml:1.0:data-type:x500Name\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-x500Name\"},"

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":\"122.45.38.245/255.255.255.64:8080-8080\",\"DataType\":\"urn:oasis:names:tc:xacml:2.0:data-type:ipAddress\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-ipAddress\"},"

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":\"some.host.name:147-874\",\"DataType\":\"urn:oasis:names:tc:xacml:2.0:data-type:dnsName\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-dnsName\"}"

+//		+ "]},"

+//		+ "{\"CategoryId\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"Attribute\":["

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":{\"Namespaces\":[{\"Namespace\":\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\"},{\"Namespace\":\"http://www.medico.com/schemas/record\",\"Prefix\":\"md\"},{\"Namespace\":\"http://www.w3.org/2001/XMLSchema-instance\",\"Prefix\":\"xsi\"}],\"XPathCategory\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"XPath\":\"//md:records/md:record\"},\"DataType\":\"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:resource:xpathExpression\"},"

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":\"http://medico.com/record/patient/BartSimpson\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#anyURI\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:resource:resource-id\"}"

+//		+ "]},"

+//		+ "{\"CategoryId\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:action\",\"Attribute\":["

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":\"read\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:action:action-id\"}"

+//		+ "]},"

+//		+ "{\"CategoryId\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\",\"Attribute\":["

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":\"08:23:47-05:00\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#time\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:environment:current-time\"}"

+//		+ "]}],\"ReturnPolicyIdList\":false,\"CombinedDecision\":false}}";

+

+

+				

+				

+				

+				

+// array attributes WITH explicit data types

+			

+			

+				

+				

+// String for testing Arrays of Attribute values

+//jsonString = "{\"Request\":{\"Category\":[{\"CategoryId\":\"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\",\"Attribute\":["

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":[\"test string\",\"Julius Hibbert\",\"Julius Hibbert as string\"],\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-id\"},"

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":[true, false],\"DataType\":\"http://www.w3.org/2001/XMLSchema#boolean\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-boolean\"},"

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":[56, 12],\"DataType\":\"http://www.w3.org/2001/XMLSchema#integer\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-integer\"},"

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":[27.12, 12112.344],\"DataType\":\"http://www.w3.org/2001/XMLSchema#double\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-double\"},"

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":[\"2002-03-22\",\"1256-11-11\"],\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-date\"},"

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":[\"2002-03-22T08:23:47-05:00\",\"1056-11-05T19:08:12-14:30\"],\"DataType\":\"http://www.w3.org/2001/XMLSchema#dateTime\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-dateTime\"},"

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":[\"P50DT5H4M3S\",\"P12DT148H18M21S\"],\"DataType\":\"http://www.w3.org/2001/XMLSchema#dayTimeDuration\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-dayTimeDuration\"},"

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":\"-P5Y3M\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#yearMonthDuration\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-yearMonthDuration\"},"

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":\"-P28Y7M\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#yearMonthDuration\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-yearMonthDuration\"},"

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":\"0bf7a9876cde\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#hexBinary\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-hexBinary\"},"

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":\"0fb8\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#hexBinary\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-hexBinary\"},"

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":\"c3VyZS4=\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#base64Binary\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-rfc822Name\"},"

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":\"YXN1cmUu\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#base64Binary\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-rfc822Name\"},"

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":\"j_hibbert@medico.com\",\"DataType\":\"urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-rfc822Name\"},"

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":\"c_clown@nose_medico.com\",\"DataType\":\"urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-rfc822Name\"},"

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":\"CN=Julius Hibbert, O=Medi Corporation, C=US\",\"DataType\":\"urn:oasis:names:tc:xacml:1.0:data-type:x500Name\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-x500Name\"},"

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":\"CN=Crusty Clown, O=Red Nose Corporation, C=US\",\"DataType\":\"urn:oasis:names:tc:xacml:1.0:data-type:x500Name\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-x500Name\"},"

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":\"122.45.38.245/255.255.255.64:8080-8080\",\"DataType\":\"urn:oasis:names:tc:xacml:2.0:data-type:ipAddress\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-ipAddress\"},"

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":\"35.123.111.56/255.64.32.255:9999-9999\",\"DataType\":\"urn:oasis:names:tc:xacml:2.0:data-type:ipAddress\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-ipAddress\"},"

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":\"some.host.name:147-874\",\"DataType\":\"urn:oasis:names:tc:xacml:2.0:data-type:dnsName\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-dnsName\"},"

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":\"a.different.host:-45\",\"DataType\":\"urn:oasis:names:tc:xacml:2.0:data-type:dnsName\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-dnsName\"}"

+//		+ "]},"

+//		+ "{\"CategoryId\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"Attribute\":["

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":{\"Namespaces\":[{\"Namespace\":\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\"},{\"Namespace\":\"http://www.medico.com/schemas/record\",\"Prefix\":\"md\"},{\"Namespace\":\"http://www.w3.org/2001/XMLSchema-instance\",\"Prefix\":\"xsi\"}],\"XPathCategory\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"XPath\":\"//md:records/md:record\"},\"DataType\":\"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:resource:xpathExpression\"},"

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":{\"Namespaces\":[{\"Namespace\":\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\"},{\"Namespace\":\"http://www.medico.com/schemas/record\",\"Prefix\":\"md\"},{\"Namespace\":\"http://www.w3.org/2001/XMLSchema-instance\",\"Prefix\":\"xsi\"}],\"XPathCategory\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"XPath\":\"//md:records/md:diagnosis_info\"},\"DataType\":\"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:resource:xpathExpression\"},"

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":\"http://medico.com/record/patient/BartSimpson\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#anyURI\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:resource:resource-id\"},"

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":\"http://medico.com/record/patient/HomerSimpson\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#anyURI\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:resource:resource-id\"}"

+//		+ "],"

+//		+ "\"Content\":\"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?><md:records xmlns:md=\\\"http://www.medico.com/schemas/record\\\">\\r\\n            \\t<md:record>\\r\\n                \\t<md:patient_info>\\r\\n                    \\t<md:name>Bart Simpson</md:name>\\r\\n                    \\t<md:age>60</md:age>\\r\\n                    \\t<md:sex>male</md:sex>\\r\\n                    \\t<md:health_insurance>123456</md:health_insurance>\\r\\n                \\t</md:patient_info>\\r\\n                \\t<md:diagnosis_info>\\r\\n                    \\t<md:diagnosis>\\r\\n                        \\t<md:item type=\\\"primary\\\">Gastric Cancer</md:item>\\r\\n                        \\t<md:item type=\\\"secondary\\\">Hyper tension</md:item>\\r\\n                    \\t</md:diagnosis>\\r\\n                    \\t<md:pathological_diagnosis>\\r\\n                        \\t<md:diagnosis>\\r\\n                            \\t<md:item type=\\\"primary\\\">Well differentiated adeno carcinoma</md:item>\\r\\n                        \\t</md:diagnosis>\\r\\n                        \\t<md:date>2000-10-05</md:date>\\r\\n                        \\t<md:malignancy type=\\\"yes\\\"/>\\r\\n                    \\t</md:pathological_diagnosis>\\r\\n                \\t</md:diagnosis_info>                \\r\\n            \\t</md:record>\\r\\n            \\t<md:record>\\r\\n                \\t<md:patient_info>\\r\\n                    \\t<md:name>Homer Simpson</md:name>\\r\\n                    \\t<md:age>80</md:age>\\r\\n                    \\t<md:sex>male</md:sex>\\r\\n                    \\t<md:health_insurance>123456</md:health_insurance>\\r\\n                \\t</md:patient_info>\\r\\n                \\t<md:diagnosis_info>\\r\\n                    \\t<md:diagnosis>\\r\\n                        \\t<md:item type=\\\"primary\\\">Gastric Cancer</md:item>\\r\\n                        \\t<md:item type=\\\"secondary\\\">Hyper tension</md:item>\\r\\n                    \\t</md:diagnosis>\\r\\n                    \\t<md:pathological_diagnosis>\\r\\n                        \\t<md:diagnosis>\\r\\n                            \\t<md:item type=\\\"primary\\\">Well differentiated adeno carcinoma</md:item>\\r\\n                        \\t</md:diagnosis>\\r\\n                        \\t<md:date>2000-10-05</md:date>\\r\\n                        \\t<md:malignancy type=\\\"yes\\\"/>\\r\\n                    \\t</md:pathological_diagnosis>\\r\\n                \\t</md:diagnosis_info>                \\r\\n            \\t</md:record>\\r\\n\\t    </md:records>\"},"

+//		+ "{\"CategoryId\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:action\",\"Attribute\":["

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":\"read\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:action:action-id\"},"

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":\"write\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:action:action-id\"}"

+//		+ "]},"

+//		+ "{\"CategoryId\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\",\"Attribute\":["

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":\"08:23:47-05:00\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#time\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:environment:current-time\"},"

+//		+ "{\"Issuer\":\"ConformanceTester\",\"Value\":\"22:12:10Z\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#time\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:environment:current-time\"}]}]"

+//		+ ",\"ReturnPolicyIdList\":false,\"CombinedDecision\":false}}";

+

+	

+				

+				

+				// load JSON into a Request

+				jsonRequest = JSONRequest.load(jsonString);

+				

+				// compare the two Request objects

+				

+				// check simple things first

+				assertEquals("File '" + currentFile.getName() + "' CombinedDecision", xmlRequest.getCombinedDecision(), jsonRequest.getCombinedDecision());

+				assertEquals("File '" + currentFile.getName() + "' getReturnPolicyIdList", xmlRequest.getReturnPolicyIdList(), jsonRequest.getReturnPolicyIdList());

+				assertEquals("File '" + currentFile.getName() + "' requestDefaults", xmlRequest.getRequestDefaults(), jsonRequest.getRequestDefaults());

+

+				// multiRequests (guaranteed to not be null)

+				// We do NOT care about ordering, so compare the two collections inefficiently

+				Collection<RequestReference> xmlCollection = xmlRequest.getMultiRequests();

+				Collection<RequestReference> jsonCollection = jsonRequest.getMultiRequests();

+				String errorMessage = null;

+				if (jsonCollection.size() != xmlCollection.size()) {

+					errorMessage = "File '" + currentFile.getName() + "' MultiRequests not same size.  ";

+				} else if (! jsonCollection.containsAll(xmlCollection)) {

+					errorMessage = "File '" + currentFile.getName() + "' MultiRequests have different contents.  ";

+				}

+				if (errorMessage != null) {

+					String xmlContents = "";

+					String jsonContents = "";

+					Iterator<RequestReference> rrIt = xmlCollection.iterator();

+					while (rrIt.hasNext()) {

+						xmlContents += "\n   " + rrIt.next().toString(); 

+					}

+					rrIt = jsonCollection.iterator();

+					while (rrIt.hasNext()) { 

+						jsonContents += "\n  " + rrIt.next().toString(); 

+					}

+					fail(errorMessage + "\nXML(" + xmlCollection.size() + ")='" + xmlContents + 

+							"'  \nJSON(" + jsonCollection.size() + ")='" + jsonContents +

+							"'" +

+							"\njson='" + jsonString + "'");

+				}

+				

+				// attributes (guaranteed to not be null)

+				// We do NOT care about ordering, so compare the two collections inefficiently

+				Collection<RequestAttributes> xmlAttrCollection = xmlRequest.getRequestAttributes();

+				Collection<RequestAttributes> jsonAttrCollection = jsonRequest.getRequestAttributes();

+				errorMessage = null;

+				if (jsonAttrCollection.size() != xmlAttrCollection.size()) {

+					errorMessage = "File '" + currentFile.getName() + "' RequestAttributes not same size.  ";

+				} else if (! jsonAttrCollection.containsAll(xmlAttrCollection)) {

+					String attrName = "";

+					Iterator<RequestAttributes> rait = xmlAttrCollection.iterator();

+					while (rait.hasNext()) {

+						RequestAttributes ra = rait.next();

+						if (jsonAttrCollection.contains(ra) == false) {

+							attrName = ra.toString();

+						}

+					}

+					errorMessage = "File '" + currentFile.getName() + "' RequestAttributes have different contents.  JSON is missing attr=" + attrName;

+				}

+				if (errorMessage != null) {

+					String xmlContents = "";

+					String jsonContents = "";

+					Iterator<RequestAttributes> rrIt = xmlAttrCollection.iterator();

+					while (rrIt.hasNext()) {

+						RequestAttributes ras = rrIt.next();

+						xmlContents += "\n   " + ras.toString();

+						if (ras.getContentRoot() != null) {

+							StringWriter writer = new StringWriter();

+							Transformer transformer = null;

+							try {

+								transformer = TransformerFactory.newInstance().newTransformer();

+								transformer.transform(new DOMSource(ras.getContentRoot()), new StreamResult(writer));

+							} catch (Exception e) {

+								throw new JSONStructureException("Unable to Content node to string; e="+e);

+							}

+

+							xmlContents += "\n        Content: " + writer.toString();

+						}

+					}

+					rrIt = jsonAttrCollection.iterator();

+					while (rrIt.hasNext()) { 

+						RequestAttributes ras = rrIt.next();

+						jsonContents += "\n   " + ras.toString();	

+						if (ras.getContentRoot() != null) {

+							StringWriter writer = new StringWriter();

+							Transformer transformer = null;

+							try {

+								transformer = TransformerFactory.newInstance().newTransformer();

+								transformer.transform(new DOMSource(ras.getContentRoot()), new StreamResult(writer));

+							} catch (Exception e) {

+								throw new JSONStructureException("Unable to Content node to string; e="+e);

+							}

+

+							jsonContents += "\n        Content: " + writer.toString();

+						}

+					}

+					fail(errorMessage + "\nXML(" + xmlAttrCollection.size() + ")='" + xmlContents + 

+							"'  \nJSON(" + jsonAttrCollection.size() + ")='" + jsonContents +

+							"\njson='" + jsonString + "'");

+				}

+				

+

+			}			

+

+		} catch (Exception e) {

+			fail ("Failed test with '" + currentFile.getName() + "', e=" + e);

+		}

+

+		

+	}

+	

+	//

+	// HELPER to get list of all Request files in the given directory

+	//

+	

+	private List<File> getRequestsInDirectory(File directory) {

+		List<File> fileList = new ArrayList<File>();

+		

+		File[] fileArray = directory.listFiles();

+		for (File f : fileArray) {

+			if (f.isDirectory()) {

+				List<File> subDirList = getRequestsInDirectory(f);

+				fileList.addAll(subDirList);

+			}

+			if (f.getName().endsWith("Request.xml")) {

+				fileList.add(f);

+			}

+		}

+		return fileList;

+		

+	}

+	

+}

+

+

+

+

+/*

+Place to dump very long trace/exception strings that need manual editing to understand

+

+

+

+

+

+

+ */

+

+

+

+

+

+

+

+

+

diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/json/RequestDefaultCategoryTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/json/RequestDefaultCategoryTest.java
new file mode 100755
index 0000000..f919878
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/json/RequestDefaultCategoryTest.java
@@ -0,0 +1,1418 @@
+/*

+ *                        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.std.json;

+

+import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.fail;

+

+import org.junit.Test;

+

+import com.att.research.xacml.api.Request;

+import com.att.research.xacml.std.json.JSONRequest;

+import com.att.research.xacml.std.json.JSONStructureException;

+/**

+ * Test JSON Request convert to object - Default Category object tests

+ * 

+ * TO RUN - use jUnit

+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test

+ * 

+ * NOTE:

+ * The "correct" way to verify that each JSON string gets translated into our internal Objects correctly is to look explicitly at each of the child objects

+ * and verify that they are correct.  This would involve a lot of coding to get child of child of child and individually verify each property of each element.

+ * To simplify testing we assume that request.toString() correctly includes a complete text representation of every sub-component of the Request object

+ * and we compare the resulting String to our expected String.

+ * This has two possible sources of error:

+ * 	- toString might not include some sub-component, and

+ * 	- the initial verification of the resulting string is done by hand and may have been incorrect.

+ * 

+ * @author glenngriffin

+ *

+ */

+public class RequestDefaultCategoryTest {

+	

+	// The request object output from each test conversion from JSON string

+	Request request;

+

+	

+	/*

+	 * Request that uses all fields with both single and multiple  entries

+	 */

+	String allFieldsRequest = 

+			"{\"Request\": {" +

+					"\"ReturnPolicyIdList\" : true ," +

+					"\"CombinedDecision\" : true ," +

+					"\"XPathVersion\" : \"http://www.w3.org/TR/1999/REC-xpath-19991116\"," +

+					"\"MultiRequests\" : {" +

+			            "\"RequestReference\": [" +

+			            	"{ " +

+			                	"\"ReferenceId\" : [\"foo1\",\"bar1\"]" +

+			                "}," +

+			                "{" +

+			                	"\"ReferenceId\" : [\"foo2\",\"bar1\"]" +

+			                "}]" +   

+			          "}," +

+

+					"\"Category\": [" +

+						"{ " +

+					    	"\"CategoryId\": \"custom-category\", " +

+					    	"\"Id\" : \"customId\", " +

+					    	"\"Attribute\" : [" +

+					    		"{" +

+					    			"\"AttributeId\"		: \"document-id\", " +

+					    			"\"DataType\"	: \"integer\", " +

+					    			"\"Value\"	: 123 " +

+								"}, " +

+								"{" +

+				    				"\"AttributeId\"		: \"document-url\", " +

+				    				"\"DataType\"	: \"anyURI\", " +

+				    				"\"Value\"	: \"http://somewhere.over.the.com/rainbow\" " +

+				    			"}, " +

+								"{" +

+				    				"\"AttributeId\"		: \"page-list\", " +

+				    				"\"Value\"	: [1, 2, 3, 4.5, 3, 2, 1] " +

+							"} " +

+					    	"]" +

+					    "}, " +

+					    "{ " +

+					    	"\"CategoryId\": \"another-custom-cat\", " +

+					    	"\"Id\" : \"anotherXmlId\", " +

+					    	"\"Attribute\" : []" +

+					    "} " +

+					"], " +

+					    

+					"\"AccessSubject\":{ " +

+						"\"Content\" : \"<?xml version=\\\"1.0\\\"?><catalog>" + 

+							"<book id=\\\"bk101\\\"><author>Gambardella, Matthew</author><title>XML Developer's Guide</title><genre>Computer</genre>" +

+							"<price>44.95</price><publish_date>2000-10-01</publish_date><description>An in-depth look at creating applications with XML.</description>"+

+							"</book></catalog>\"," +

+						"\"Attribute\" : []" +

+					"}, " +

+					

+					"\"Resource\" : {" +

+						"\"Content\" : \"PD94bWwgdmVyc2lvbj0iMS4wIj8+PGNhdGFsb2c+PGJvb2sgaWQ9ImJrMTAxIj48YXV0aG9yPkdhbWJhcmRlbGxhLCBNYXR0aGV3PC9hdXRob3I+PHRpdGxlPlhNT" +

+							"CBEZXZlbG9wZXIncyBHdWlkZTwvdGl0bGU+PGdlbnJlPkNvbXB1dGVyPC9nZW5yZT48cHJpY2U+NDQuOTU8L3ByaWNlPjxwdWJsaXNoX2RhdGU+MjAwMC0xMC0wMTwvcHVibGlzaF"+

+							"9kYXRlPjxkZXNjcmlwdGlvbj5BbiBpbi1kZXB0aCBsb29rIGF0IGNyZWF0aW5nIGFwcGxpY2F0aW9ucyB3aXRoIFhNTC48L2Rlc2NyaXB0aW9uPjwvYm9vaz48L2NhdGFsb2c+\"" +

+

+

+					"} " +

+

+			          

+			"}}";

+	

+	/*

+	 * The following example comes directly from the JSON Profile Spec

+	 */

+	String exampleFromSpec = "{ " +

+			"\"Request\" : { " +

+				"\"AccessSubject\" : { " +

+					"\"Attribute\": [ " +

+						"{ " +

+							"\"Id\" : \"subject-id\", " +

+							"\"Value\" : \"Andreas\" " +

+						"}, " +

+						"{ " +

+							"\"Id\" : \"location\", " +

+							"\"Value\" : \"Gamla Stan\" " +

+						"} " +

+					"] " +

+				"}, " +

+				"\"Action\" : { " +

+					"\"Attribute\":  " +

+						"{ " +

+							"\"Id\" : \"action-id\", " +

+							"\"Value\" : \"http://www.xacml.eu/buy\", " +

+							"\"DataType\" : \"anyURI\" " +

+						"} " +

+				"}, " +

+				"\"Resource\" : { " +

+					"\"Attribute\": [ " +

+						"{ " +

+							"\"Id\" : \"book-title\", " +

+							"\"Value\" : \"Learn German in 90 days\" " +

+						"}, " +

+						"{ " +

+							"\"Id\" : \"currency\", " +

+							"\"Value\" : \"SEK\" " +

+						"}, " +

+						"{ " +

+							"\"Id\" : \"price\", " +

+							"\"Value\" : 123.34 " +

+						"} " +

+						"] " +

+					"} " +

+				"} " +

+			"} ";

+

+	

+	/*

+	 * The following example comes directly from the JSON Profile Spec (modified to include a "</Catalog>" missing from both examples).

+	 * It shows the two ways of handling XPath content, as escaped XML and as Base64 encoding.

+	 */

+	String xPathExampleFromSpec = "{ " +

+			"\"Request\" : { " +

+				"\"Resource\" : { " +

+					"\"Attribute\": [ " +

+						"{ " +

+						 	"\"Id\" : \"urn:oasis:names:tc:xacml:3.0:content-selector\", " +

+				            "\"DataType\" : \"xpathExpression\", " +

+				            "\"Value\" : { " +

+				                "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\", " +

+				                "\"Namespaces\" : [{ " +

+				                    	"\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " +

+				                    	"}, " +

+				                    "{ " +

+				                    	"\"Prefix\" : \"md\", " +

+				                    	"\"Namespace\" : \"urn:example:med:schemas:record\" " +

+				                    "} " +

+				                "], " +

+				                "\"XPath\" : \"md:record/md:patient/md:patientDoB\" " +

+				            "} " +

+				        "} " +

+					"] " +

+				"} " +

+			"} " +

+		"} ";

+

+	

+	// test Shorthand Category notation for elements not tested in their own section below.

+	// Categories that are more commonly used are fully tested. 

+	// Given that the functions within the categories are the same irrespective of the name of the category, 

+	// we assume that the contents of the category will work ok once the Shorthand notation is recognized, so all we need to test is the shorthand

+	// The ones that are tested in their own sections are:

+	//		AccessSubject

+	//		Action

+	//		Resource

+	//		Environment 

+	// test Subject

+	@Test

+	public void testCategoryShorthand() {

+	

+		// RecipientSubject present both as element within Category and as separate RecipientSubject element at same level as Category

+		try {

+			request = JSONRequest.load("{\"Request\" : {"

+					+ "\"Category\": ["

+						+ "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject\", \"Attribute\" : [{" +

+		    				"\"Id\" : \"document-id\", " +

+		    				"\"Value\"	: [ \"aValue\", \"aValue\", \"aValue\" ] " +

+						"}] }, "

+						+ "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject\", \"Attribute\" : [{" +

+		    				"\"Id\" : \"document-id\", " +

+		    				"\"Value\"	: \"aValue\"" +

+						"}] } "

+						+ "]," +

+					"\"RecipientSubject\" : { " +

+						"\"Attribute\": [ " +

+							"{ " +

+								"\"Id\" : \"subject-id\", " +

+								"\"Value\" : \"Andreas\" " +

+							"}, " +

+							"{ " +

+								"\"Id\" : \"location\", " +

+								"\"Value\" : \"Gamla Stan\" " +

+							"} " +

+						"] " +

+					"} " 

+				+ " }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		

+		// IntermediarySubject present both as element within Category and as separate IntermediarySubject element at same level as Category

+		try {

+			request = JSONRequest.load("{\"Request\" : {"

+					+ "\"Category\": ["

+						+ "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:intermediary-subject\", \"Attribute\" : [{" +

+		    				"\"Id\" : \"document-id\", " +

+		    				"\"Value\"	: [ \"aValue\", \"aValue\", \"aValue\" ] " +

+						"}] }, "

+						+ "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:intermediary-subject\", \"Attribute\" : [{" +

+		    				"\"Id\" : \"document-id\", " +

+		    				"\"Value\"	: \"aValue\"" +

+						"}] } "

+						+ "]," +

+					"\"IntermediarySubject\" : { " +

+						"\"Attribute\": [ " +

+							"{ " +

+								"\"Id\" : \"subject-id\", " +

+								"\"Value\" : \"Andreas\" " +

+							"}, " +

+							"{ " +

+								"\"Id\" : \"location\", " +

+								"\"Value\" : \"Gamla Stan\" " +

+							"} " +

+						"] " +

+					"} " 

+				+ " }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:intermediary-subject,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:intermediary-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:intermediary-subject,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:intermediary-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:intermediary-subject,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:intermediary-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:intermediary-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		

+		// Codebase present both as element within Category and as separate Codebase element at same level as Category

+		try {

+			request = JSONRequest.load("{\"Request\" : {"

+					+ "\"Category\": ["

+						+ "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:codebase\", \"Attribute\" : [{" +

+		    				"\"Id\" : \"document-id\", " +

+		    				"\"Value\"	: [ \"aValue\", \"aValue\", \"aValue\" ] " +

+						"}] }, "

+						+ "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:codebase\", \"Attribute\" : [{" +

+		    				"\"Id\" : \"document-id\", " +

+		    				"\"Value\"	: \"aValue\"" +

+						"}] } "

+						+ "]," +

+					"\"Codebase\" : { " +

+						"\"Attribute\": [ " +

+							"{ " +

+								"\"Id\" : \"subject-id\", " +

+								"\"Value\" : \"Andreas\" " +

+							"}, " +

+							"{ " +

+								"\"Id\" : \"location\", " +

+								"\"Value\" : \"Gamla Stan\" " +

+							"} " +

+						"] " +

+					"} " 

+				+ " }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:codebase,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:codebase,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:codebase,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:codebase,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:codebase,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:codebase,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:codebase,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		

+		

+		// RequestingMachine present both as element within Category and as separate RequestingMachine element at same level as Category

+		try {

+			request = JSONRequest.load("{\"Request\" : {"

+					+ "\"Category\": ["

+						+ "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:requesting-machine\", \"Attribute\" : [{" +

+		    				"\"Id\" : \"document-id\", " +

+		    				"\"Value\"	: [ \"aValue\", \"aValue\", \"aValue\" ] " +

+						"}] }, "

+						+ "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:requesting-machine\", \"Attribute\" : [{" +

+		    				"\"Id\" : \"document-id\", " +

+		    				"\"Value\"	: \"aValue\"" +

+						"}] } "

+						+ "]," +

+					"\"RequestingMachine\" : { " +

+						"\"Attribute\": [ " +

+							"{ " +

+								"\"Id\" : \"subject-id\", " +

+								"\"Value\" : \"Andreas\" " +

+							"}, " +

+							"{ " +

+								"\"Id\" : \"location\", " +

+								"\"Value\" : \"Gamla Stan\" " +

+							"} " +

+						"] " +

+					"} " 

+				+ " }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:requesting-machine,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:requesting-machine,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:requesting-machine,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:requesting-machine,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:requesting-machine,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:requesting-machine,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:requesting-machine,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+	}

+

+

+

+

+

+	

+

+

+	

+

+

+	

+	

+	

+	

+	

+	// test AccessSubject

+	// Include test for backward compatibility with "Subject"

+	@Test

+	public void testAccessSubjectRequest() {

+		

+		// AccessSubject absent

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"aValue\", \"aValue\", \"aValue\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// AccessSubject as normal element under Category (with CategoryId==subject category id)

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: \"aValue\" " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// multiple AccessSubjects under Category

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": ["

+					+ "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\", \"Attribute\" : [{" +

+	    				"\"Id\" : \"document-id\", " +

+	    				"\"Value\"	: [ \"aValue\", \"aValue\", \"aValue\" ] " +

+					"}] }, "

+					+ "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\", \"Attribute\" : [{" +

+	    				"\"Id\" : \"document-id\", " +

+	    				"\"Value\"	: \"aValue\"" +

+					"}] } "

+					+ "] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// AccessSubject present both as element within Category and as separate AccessSubject element at same level as Category

+		try {

+			request = JSONRequest.load("{\"Request\" : {"

+					+ "\"Category\": ["

+						+ "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\", \"Attribute\" : [{" +

+		    				"\"Id\" : \"document-id\", " +

+		    				"\"Value\"	: [ \"aValue\", \"aValue\", \"aValue\" ] " +

+						"}] }, "

+						+ "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\", \"Attribute\" : [{" +

+		    				"\"Id\" : \"document-id\", " +

+		    				"\"Value\"	: \"aValue\"" +

+						"}] } "

+						+ "]," +

+					"\"AccessSubject\" : { " +

+						"\"Attribute\": [ " +

+							"{ " +

+								"\"Id\" : \"subject-id\", " +

+								"\"Value\" : \"Andreas\" " +

+							"}, " +

+							"{ " +

+								"\"Id\" : \"location\", " +

+								"\"Value\" : \"Gamla Stan\" " +

+							"} " +

+						"] " +

+					"} " 

+				+ " }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// AccessSubject present, no other Category element

+		try {

+			request = JSONRequest.load("{\"Request\" : {"

+					+ 

+					"\"AccessSubject\" : { " +

+						"\"Attribute\": [ " +

+							"{ " +

+								"\"Id\" : \"subject-id\", " +

+								"\"Value\" : \"Andreas\" " +

+							"}, " +

+							"{ " +

+								"\"Id\" : \"location\", " +

+								"\"Value\" : \"Gamla Stan\" " +

+							"} " +

+						"] " +

+					"} " 

+				+ " }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		

+		// Subject present, no other Category element (Backward Compatibility

+		try {

+			request = JSONRequest.load("{\"Request\" : {"

+					+ 

+					"\"Subject\" : { " +

+						"\"Attribute\": [ " +

+							"{ " +

+								"\"Id\" : \"subject-id\", " +

+								"\"Value\" : \"Andreas\" " +

+							"}, " +

+							"{ " +

+								"\"Id\" : \"location\", " +

+								"\"Value\" : \"Gamla Stan\" " +

+							"} " +

+						"] " +

+					"} " 

+				+ " }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// AccessSubject present, 1/multiple other Category element also present

+		try {

+			request = JSONRequest.load("{\"Request\" : {"

+					+ "\"Category\": ["

+						+ "{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+		    				"\"Id\" : \"document-id\", " +

+		    				"\"Value\"	: \"aValue\"" +

+						"}] } "

+						+ "]," +

+					"\"AccessSubject\" : { " +

+						"\"Attribute\": [ " +

+							"{ " +

+								"\"Id\" : \"subject-id\", " +

+								"\"Value\" : \"Andreas\" " +

+							"}, " +

+							"{ " +

+								"\"Id\" : \"location\", " +

+								"\"Value\" : \"Gamla Stan\" " +

+							"} " +

+						"] " +

+					"} " 

+				+ " }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// 2 AccessSubjects - duplicates fail

+		try {

+			request = JSONRequest.load("{\"Request\" : {"

+					+ 

+					"\"AccessSubject\" : { " +

+						"\"Attribute\": [ " +

+							"{ " +

+								"\"Id\" : \"subject-id\", " +

+								"\"Value\" : \"Andreas\" " +

+							"}, " +

+							"{ " +

+								"\"Id\" : \"location\", " +

+								"\"Value\" : \"Gamla Stan\" " +

+							"} " +

+						"] " +

+					"} " 

+					+ 

+					"\"AccessSubject\" : { " +

+						"\"Attribute\": [ " +

+							"{ " +

+								"\"Id\" : \"subject-id\", " +

+								"\"Value\" : \"Andreas\" " +

+							"}, " +

+							"{ " +

+								"\"Id\" : \"location\", " +

+								"\"Value\" : \"Gamla Stan\" " +

+							"} " +

+						"] " +

+					"} " 

+				+ " }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// AccessSubject with correct Category value

+		try {

+			request = JSONRequest.load("{\"Request\" : {"

+					+ 

+					"\"AccessSubject\" : { " +

+						"\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\" ," +

+						"\"Attribute\": [ " +

+							"{ " +

+								"\"Id\" : \"subject-id\", " +

+								"\"Value\" : \"Andreas\" " +

+							"}, " +

+							"{ " +

+								"\"Id\" : \"location\", " +

+								"\"Value\" : \"Gamla Stan\" " +

+							"} " +

+						"] " +

+					"} " 

+				+ " }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// AccessSubject with wrong Category value

+		try {

+			request = JSONRequest.load("{\"Request\" : {"

+					+ 

+					"\"AccessSubject\" : { " +

+						"\"CategoryId\" : \"notthesubject\" ," +

+						"\"Attribute\": [ " +

+							"{ " +

+								"\"Id\" : \"subject-id\", " +

+								"\"Value\" : \"Andreas\" " +

+							"}, " +

+							"{ " +

+								"\"Id\" : \"location\", " +

+								"\"Value\" : \"Gamla Stan\" " +

+							"} " +

+						"] " +

+					"} " 

+				+ " }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// AccessSubject with array of sub-object AccessSubjects (Multi Decision)

+		try {

+			request = JSONRequest.load("{\"Request\" : {"

+					+ 

+					"\"AccessSubject\" : ["

+					+ "{ " +

+						"\"Attribute\": [ " +

+							"{ " +

+								"\"Id\" : \"subject-id\", " +

+								"\"Value\" : \"Andreas\" " +

+							"}, " +

+							"{ " +

+								"\"Id\" : \"location\", " +

+								"\"Value\" : \"Gamla Stan\" " +

+							"} " +

+						"] " +

+					"}, "

+					+ "{ " +

+					"\"Attribute\": [ " +

+						"{ " +

+							"\"Id\" : \"subject-id\", " +

+							"\"Value\" : \"Arless\" " +

+						"}, " +

+						"{ " +

+							"\"Id\" : \"location\", " +

+							"\"Value\" : \"Somewhere\" " +

+						"} " +

+					"] " +

+					"}, "

+					+ "{ " +

+					"\"Attribute\": [ " +

+						"{ " +

+							"\"Id\" : \"subject-id\", " +

+							"\"Value\" : \"Barry\" " +

+						"}, " +

+						"{ " +

+							"\"Id\" : \"location\", " +

+							"\"Value\" : \"Elsewhere\" " +

+						"} " +

+					"] " +

+					"} "

+				+ "]"

+				+ " }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Arless}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Somewhere}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Barry}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Elsewhere}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+

+	}

+	

+	

+	

+	

+	

+	

+	

+	

+	

+	// Action ... duplicate all AccessSubject tests...

+	// test Action

+	@Test

+	public void testActionRequest() {

+		

+		// Action absent

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: [ \"aValue\", \"aValue\", \"aValue\" ] " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// Action as normal element under Category (with CategoryId==subject category id)

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\", \"Attribute\" : [{" +

+	    			"\"Id\" : \"document-id\", " +

+	    			"\"Value\"	: \"aValue\" " +

+					"}] } ] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// multiple Actions under Category

+		try {

+			request = JSONRequest.load("{\"Request\" : {\"Category\": ["

+					+ "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\", \"Attribute\" : [{" +

+	    				"\"Id\" : \"document-id\", " +

+	    				"\"Value\"	: [ \"aValue\", \"aValue\", \"aValue\" ] " +

+					"}] }, "

+					+ "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\", \"Attribute\" : [{" +

+	    				"\"Id\" : \"document-id\", " +

+	    				"\"Value\"	: \"aValue\"" +

+					"}] } "

+					+ "] }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// Action present both as element within Category and as separate Action element at same level as Category

+		try {

+			request = JSONRequest.load("{\"Request\" : {"

+					+ "\"Category\": ["

+						+ "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\", \"Attribute\" : [{" +

+		    				"\"Id\" : \"document-id\", " +

+		    				"\"Value\"	: [ \"aValue\", \"aValue\", \"aValue\" ] " +

+						"}] }, "

+						+ "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\", \"Attribute\" : [{" +

+		    				"\"Id\" : \"document-id\", " +

+		    				"\"Value\"	: \"aValue\"" +

+						"}] } "

+						+ "]," +

+					"\"Action\" : { " +

+						"\"Attribute\": [ " +

+							"{ " +

+								"\"Id\" : \"subject-id\", " +

+								"\"Value\" : \"Andreas\" " +

+							"}, " +

+							"{ " +

+								"\"Id\" : \"location\", " +

+								"\"Value\" : \"Gamla Stan\" " +

+							"} " +

+						"] " +

+					"} " 

+				+ " }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// Action present, no other Category element

+		try {

+			request = JSONRequest.load("{\"Request\" : {"

+					+ 

+					"\"Action\" : { " +

+						"\"Attribute\": [ " +

+							"{ " +

+								"\"Id\" : \"subject-id\", " +

+								"\"Value\" : \"Andreas\" " +

+							"}, " +

+							"{ " +

+								"\"Id\" : \"location\", " +

+								"\"Value\" : \"Gamla Stan\" " +

+							"} " +

+						"] " +

+					"} " 

+				+ " }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// Action present, 1/multiple other Category element also present

+		try {

+			request = JSONRequest.load("{\"Request\" : {"

+					+ "\"Category\": ["

+						+ "{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +

+		    				"\"Id\" : \"document-id\", " +

+		    				"\"Value\"	: \"aValue\"" +

+						"}] } "

+						+ "]," +

+					"\"Action\" : { " +

+						"\"Attribute\": [ " +

+							"{ " +

+								"\"Id\" : \"subject-id\", " +

+								"\"Value\" : \"Andreas\" " +

+							"}, " +

+							"{ " +

+								"\"Id\" : \"location\", " +

+								"\"Value\" : \"Gamla Stan\" " +

+							"} " +

+						"] " +

+					"} " 

+				+ " }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// 2 Actions - duplicates fail

+		try {

+			request = JSONRequest.load("{\"Request\" : {"

+					+ 

+					"\"Action\" : { " +

+						"\"Attribute\": [ " +

+							"{ " +

+								"\"Id\" : \"subject-id\", " +

+								"\"Value\" : \"Andreas\" " +

+							"}, " +

+							"{ " +

+								"\"Id\" : \"location\", " +

+								"\"Value\" : \"Gamla Stan\" " +

+							"} " +

+						"] " +

+					"} " 

+					+ 

+					"\"Action\" : { " +

+						"\"Attribute\": [ " +

+							"{ " +

+								"\"Id\" : \"subject-id\", " +

+								"\"Value\" : \"Andreas\" " +

+							"}, " +

+							"{ " +

+								"\"Id\" : \"location\", " +

+								"\"Value\" : \"Gamla Stan\" " +

+							"} " +

+						"] " +

+					"} " 

+				+ " }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// Action with correct Category value

+		try {

+			request = JSONRequest.load("{\"Request\" : {"

+					+ 

+					"\"Action\" : { " +

+						"\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:action\" ," +

+						"\"Attribute\": [ " +

+							"{ " +

+								"\"Id\" : \"subject-id\", " +

+								"\"Value\" : \"Andreas\" " +

+							"}, " +

+							"{ " +

+								"\"Id\" : \"location\", " +

+								"\"Value\" : \"Gamla Stan\" " +

+							"} " +

+						"] " +

+					"} " 

+				+ " }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString());

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// Action with wrong Category value

+		try {

+			request = JSONRequest.load("{\"Request\" : {"

+					+ 

+					"\"Action\" : { " +

+						"\"CategoryId\" : \"notthesubject\" ," +

+						"\"Attribute\": [ " +

+							"{ " +

+								"\"Id\" : \"subject-id\", " +

+								"\"Value\" : \"Andreas\" " +

+							"}, " +

+							"{ " +

+								"\"Id\" : \"location\", " +

+								"\"Value\" : \"Gamla Stan\" " +

+							"} " +

+						"] " +

+					"} " 

+				+ " }}");

+			fail("Operation should throw exception");

+		} catch (JSONStructureException e) {

+			// correct response

+		} catch (Exception e) {

+			fail ("Failed convert from JSON to object: " + e);

+		}

+		

+		// Action with array of sub-object Actions (Multi Decision)

+		try {

+			request = JSONRequest.load("{\"Request\" : {"

+					+ 

+					"\"Action\" : ["

+					+ "{ " +

+						"\"Attribute\": [ " +

+							"{ " +

+								"\"Id\" : \"subject-id\", " +

+								"\"Value\" : \"Andreas\" " +

+							"}, " +

+							"{ " +

+								"\"Id\" : \"location\", " +

+								"\"Value\" : \"Gamla Stan\" " +

+							"} " +

+						"] " +

+					"}, "

+					+ "{ " +

+					"\"Attribute\": [ " +

+						"{ " +

+							"\"Id\" : \"subject-id\", " +

+							"\"Value\" : \"Arless\" " +

+						"}, " +

+						"{ " +

+							"\"Id\" : \"location\", " +

+							"\"Value\" : \"Somewhere\" " +

+						"} " +

+					"] " +

+					"}, "

+					+ "{ " +

+					"\"Attribute\": [ " +

+						"{ " +

+							"\"Id\" : \"subject-id\", " +

+							"\"Value\" : \"Barry\" " +

+						"}, " +

+						"{ " +

+							"\"Id\" : \"location\", " +

+							"\"Value\" : \"Elsewhere\" " +

+						"} " +

+					"] " +

+					"} "

+				+ "]"

+				+ " }}");

+			assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Arless}],includeInResults=false}{attributeId=