You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@openaz.apache.org by pd...@apache.org on 2015/04/13 17:38:32 UTC

[32/51] [partial] incubator-openaz git commit: Initial seed of merged of AT&T and JP Morgan code

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagIsIn.java
----------------------------------------------------------------------
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;
+	}
+
+	
+	
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagOneAndOnly.java
----------------------------------------------------------------------
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);
+	}
+
+
+	
+	
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagSize.java
----------------------------------------------------------------------
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);
+	}
+
+	
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBase.java
----------------------------------------------------------------------
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;
+	}
+	
+	
+	
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison.java
----------------------------------------------------------------------
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));
+
+	}
+
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic.java
----------------------------------------------------------------------
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; 
+	}
+	
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionEquality.java
----------------------------------------------------------------------
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;
+		}
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag.java
----------------------------------------------------------------------
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);
+		}
+	}
+	
+	
+	
+	
+	
+	
+	
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHomogeneousSimple.java
----------------------------------------------------------------------
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;
+	}
+	
+	
+	
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical.java
----------------------------------------------------------------------
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));
+
+	}
+
+	
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionNumberTypeConversion.java
----------------------------------------------------------------------
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;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRFC822NameMatch.java
----------------------------------------------------------------------
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;
+			}
+		}
+
+	}
+
+}