diff --git a/LogParser/pom.xml b/LogParser/pom.xml
index d8cef17..b638faf 100644
--- a/LogParser/pom.xml
+++ b/LogParser/pom.xml
@@ -36,16 +36,11 @@
             <artifactId>h2</artifactId>
             <version>1.4.193</version>
         </dependency>
-        <dependency>
-			<groupId>mysql</groupId>
-			<artifactId>mysql-connector-java</artifactId>
-			<version>5.1.30</version>
-		</dependency>
 		<dependency>
-			<groupId>org.mariadb.jdbc</groupId>
-			<artifactId>mariadb-java-client</artifactId>
-			<version>1.2.3</version>
-		</dependency>  
+            <groupId>org.mariadb.jdbc</groupId>
+            <artifactId>mariadb-java-client</artifactId>
+            <version>2.1.1</version>
+        </dependency> 
 		<dependency>
 			<groupId>org.onap.policy.common</groupId>
 			<artifactId>ONAP-Logging</artifactId>
diff --git a/ONAP-PAP-REST/pom.xml b/ONAP-PAP-REST/pom.xml
index dc94992..d2d84db 100644
--- a/ONAP-PAP-REST/pom.xml
+++ b/ONAP-PAP-REST/pom.xml
@@ -207,12 +207,11 @@
 			<artifactId>eclipselink</artifactId>
 			<version>2.6.0</version>
 		</dependency>
-
 		<dependency>
-			<groupId>mysql</groupId>
-			<artifactId>mysql-connector-java</artifactId>
-			<version>5.1.30</version>
-		</dependency>
+            <groupId>org.mariadb.jdbc</groupId>
+            <artifactId>mariadb-java-client</artifactId>
+            <version>2.1.1</version>
+        </dependency>
 		<dependency>
 			<groupId>org.springframework</groupId>
 			<artifactId>spring-mock</artifactId>
diff --git a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/PolicyDBDao.java b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/PolicyDBDao.java
index 7c46990..483418c 100644
--- a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/PolicyDBDao.java
+++ b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/PolicyDBDao.java
@@ -2156,7 +2156,7 @@
 				String prefix = null;
 				if (policy.policyAdapter.getPolicyType().equalsIgnoreCase("Config")) {
 
-					prefix = configPath.substring(configPath.indexOf(policyScope+".")+policyScope.concat(".").length(), configPath.indexOf(policy.policyAdapter.getPolicyName()));
+					prefix = configPath.substring(configPath.indexOf(policyScope+".")+policyScope.concat(".").length(), configPath.lastIndexOf(policy.policyAdapter.getPolicyName()));
 					if(isNullOrEmpty(policy.policyAdapter.getConfigBodyData())){
 						String configData = "";
 						try{
diff --git a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/daoimpl/CommonClassDaoImpl.java b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/daoimpl/CommonClassDaoImpl.java
index e651446..5d2b7f6 100644
--- a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/daoimpl/CommonClassDaoImpl.java
+++ b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/daoimpl/CommonClassDaoImpl.java
@@ -448,4 +448,8 @@
 		return null;
 	}
 
+    public static void setSessionfactory(SessionFactory sessionfactory) {
+        sessionFactory = sessionfactory;
+    }
+
 }
\ No newline at end of file
diff --git a/ONAP-PAP-REST/src/main/resources/META-INF/generatedCreate.ddl b/ONAP-PAP-REST/src/main/resources/META-INF/generatedCreate.ddl
deleted file mode 100644
index c12949a..0000000
--- a/ONAP-PAP-REST/src/main/resources/META-INF/generatedCreate.ddl
+++ /dev/null
@@ -1,119 +0,0 @@
-CREATE TABLE PolicyEntity (policyId BIGINT NOT NULL, created_by VARCHAR(255) NOT NULL, created_date TIMESTAMP, deleted BOOLEAN NOT NULL, description VARCHAR(2048) NOT NULL, modified_by VARCHAR(255) NOT NULL, modified_date TIMESTAMP NOT NULL, policyData TEXT, policyName VARCHAR(255) NOT NULL, policyVersion INTEGER, scope VARCHAR(255) NOT NULL, version INTEGER, actionBodyId BIGINT, configurationDataId BIGINT, PRIMARY KEY (policyId))
-CREATE TABLE ConfigurationDataEntity (configurationDataId BIGINT NOT NULL, configBody TEXT, configType VARCHAR(255) NOT NULL, configurationName VARCHAR(255) NOT NULL, created_by VARCHAR(255) NOT NULL, created_date TIMESTAMP, deleted BOOLEAN NOT NULL, description VARCHAR(2048) NOT NULL, modified_by VARCHAR(255) NOT NULL, modified_date TIMESTAMP NOT NULL, version INTEGER, PRIMARY KEY (configurationDataId))
-CREATE TABLE PolicyDBDaoEntity (policyDBDaoUrl VARCHAR NOT NULL, created_date TIMESTAMP, description VARCHAR(2048) NOT NULL, modified_date TIMESTAMP NOT NULL, password VARCHAR, username VARCHAR, PRIMARY KEY (policyDBDaoUrl))
-CREATE TABLE GroupEntity (groupKey BIGINT NOT NULL, created_by VARCHAR(255) NOT NULL, created_date TIMESTAMP, defaultGroup BOOLEAN NOT NULL, deleted BOOLEAN NOT NULL, description VARCHAR(2048) NOT NULL, groupId VARCHAR NOT NULL, groupName VARCHAR(255) NOT NULL, modified_by VARCHAR(255) NOT NULL, modified_date TIMESTAMP NOT NULL, version INTEGER, PRIMARY KEY (groupKey))
-CREATE TABLE PdpEntity (pdpKey BIGINT NOT NULL, created_by VARCHAR(255) NOT NULL, created_date TIMESTAMP, deleted BOOLEAN NOT NULL, description VARCHAR(2048) NOT NULL, jmxPort INTEGER NOT NULL, modified_by VARCHAR(255) NOT NULL, modified_date TIMESTAMP NOT NULL, pdpId VARCHAR(255) NOT NULL, pdpName VARCHAR(255) NOT NULL, groupKey BIGINT, PRIMARY KEY (pdpKey))
-CREATE TABLE ActionBodyEntity (actionBodyId BIGINT NOT NULL, actionBody TEXT, actionBodyName VARCHAR(255) NOT NULL, created_by VARCHAR(255) NOT NULL, created_date TIMESTAMP, deleted BOOLEAN NOT NULL, modified_by VARCHAR(255) NOT NULL, modified_date TIMESTAMP NOT NULL, version INTEGER, PRIMARY KEY (actionBodyId))
-CREATE TABLE DatabaseLockEntity (lock_key INTEGER NOT NULL, PRIMARY KEY (lock_key))
-CREATE TABLE PolicyVersion (id INTEGER NOT NULL, ACTIVE_VERSION INTEGER, CREATED_BY VARCHAR(45) NOT NULL, created_date TIMESTAMP NOT NULL, HIGHEST_VERSION INTEGER, modified_by VARCHAR(45) NOT NULL, modified_date TIMESTAMP NOT NULL, POLICY_NAME VARCHAR(255) NOT NULL, PRIMARY KEY (id))
-CREATE TABLE POLICYSCORE (id INTEGER NOT NULL, POLICY_NAME VARCHAR NOT NULL, POLICY_SCORE VARCHAR, VERSIONEXTENSION VARCHAR NOT NULL, PRIMARY KEY (id))
-CREATE TABLE FunctionDefinition (id INTEGER NOT NULL, arg_lb INTEGER NOT NULL, arg_ub INTEGER NOT NULL, ho_arg_lb INTEGER, ho_arg_ub INTEGER, ho_primitive CHAR, is_bag_return INTEGER NOT NULL, is_higher_order INTEGER NOT NULL, short_name VARCHAR(64) NOT NULL, xacml_id VARCHAR(255) NOT NULL, return_datatype INTEGER, PRIMARY KEY (id))
-CREATE TABLE Attribute (id INTEGER NOT NULL, ATTRIBUTE_VALUE VARCHAR, created_date TIMESTAMP, description VARCHAR(2048), is_designator CHAR NOT NULL, modified_date TIMESTAMP NOT NULL, PRIORITY VARCHAR, selector_path VARCHAR(2048), xacml_id VARCHAR NOT NULL UNIQUE, category INTEGER, constraint_type INTEGER, datatype INTEGER, created_by VARCHAR(45), modified_by VARCHAR(45), PRIMARY KEY (id))
-CREATE TABLE Category (id INTEGER NOT NULL, grouping VARCHAR(64) NOT NULL, is_standard CHAR NOT NULL, short_name VARCHAR(64) NOT NULL, xacml_id VARCHAR(255) NOT NULL UNIQUE, PRIMARY KEY (id))
-CREATE TABLE ConstraintType (id INTEGER NOT NULL, constraint_type VARCHAR(64) NOT NULL, description VARCHAR(255) NOT NULL, PRIMARY KEY (id))
-CREATE TABLE ConstraintValues (id INTEGER NOT NULL, property VARCHAR, value VARCHAR, attribute_id INTEGER, PRIMARY KEY (id))
-CREATE TABLE Datatype (id INTEGER NOT NULL, is_standard CHAR NOT NULL, short_name VARCHAR(64) NOT NULL, xacml_id VARCHAR(255) NOT NULL UNIQUE, PRIMARY KEY (id))
-CREATE TABLE FunctionArguments (id INTEGER NOT NULL, arg_index INTEGER NOT NULL, is_bag INTEGER NOT NULL, datatype_id INTEGER, function_id INTEGER, PRIMARY KEY (id))
-CREATE TABLE UserInfo (loginid VARCHAR(45) NOT NULL, name VARCHAR NOT NULL UNIQUE, PRIMARY KEY (loginid))
-CREATE TABLE ActionPolicyDict (id INTEGER NOT NULL, ATTRIBUTE_NAME VARCHAR NOT NULL, Body VARCHAR, created_date TIMESTAMP, description VARCHAR(2048), Headers VARCHAR, Method VARCHAR NOT NULL, modified_date TIMESTAMP NOT NULL, Type VARCHAR NOT NULL, URL VARCHAR NOT NULL, created_by VARCHAR(45), modified_by VARCHAR(45), PRIMARY KEY (id))
-CREATE TABLE DecisionSettings (id INTEGER NOT NULL, created_date TIMESTAMP, description VARCHAR(2048), modified_date TIMESTAMP NOT NULL, PRIORITY VARCHAR, xacml_id VARCHAR NOT NULL UNIQUE, datatype INTEGER, created_by VARCHAR(45), modified_by VARCHAR(45), PRIMARY KEY (id))
-CREATE TABLE MicroServiceModels (id INTEGER NOT NULL, annotation VARCHAR(2000) NOT NULL, attributes VARCHAR(255) NOT NULL, dependency VARCHAR(2048), description VARCHAR(2048), enumValues VARCHAR(2000) NOT NULL, modelName VARCHAR NOT NULL UNIQUE, ref_attributes VARCHAR(255) NOT NULL, sub_attributes VARCHAR(2000) NOT NULL, version VARCHAR(2000) NOT NULL, imported_by VARCHAR(45), PRIMARY KEY (id))
-CREATE TABLE actionlist (id INTEGER NOT NULL, actionname VARCHAR NOT NULL, description VARCHAR, PRIMARY KEY (id))
-CREATE TABLE AddressGroup (id INTEGER NOT NULL, description VARCHAR, name VARCHAR NOT NULL, prefixlist VARCHAR, PRIMARY KEY (id))
-CREATE TABLE AttributeAssignment (id INTEGER NOT NULL, attribute_id INTEGER, expression VARCHAR NOT NULL, OBADVICE_id INTEGER, PRIMARY KEY (id))
-CREATE TABLE BRMSParamTemplate (id INTEGER NOT NULL, created_date TIMESTAMP, description VARCHAR(2048), rule LONGVARCHAR NOT NULL, param_template_name VARCHAR NOT NULL UNIQUE, created_by VARCHAR(45), PRIMARY KEY (id))
-CREATE TABLE ClosedLoopD2Services (id INTEGER NOT NULL, created_date TIMESTAMP, description VARCHAR(2048), modified_date TIMESTAMP NOT NULL, service_Name VARCHAR NOT NULL UNIQUE, created_by VARCHAR(45), modified_by VARCHAR(45), PRIMARY KEY (id))
-CREATE TABLE ClosedLoopSite (id INTEGER NOT NULL, created_date TIMESTAMP, description VARCHAR(2048), modified_date TIMESTAMP NOT NULL, site_Name VARCHAR NOT NULL UNIQUE, created_by VARCHAR(45), modified_by VARCHAR(45), PRIMARY KEY (id))
-CREATE TABLE DCAEUsers (id INTEGER NOT NULL, description  VARCHAR, name VARCHAR NOT NULL, PRIMARY KEY (id))
-CREATE TABLE DCAEuuid (id INTEGER NOT NULL, description VARCHAR, name VARCHAR NOT NULL, PRIMARY KEY (id))
-CREATE TABLE DescriptiveScope (Id INTEGER NOT NULL, created_date TIMESTAMP, description VARCHAR(2048), scopename VARCHAR NOT NULL, modified_date TIMESTAMP NOT NULL, search VARCHAR, created_by VARCHAR(45), modified_by VARCHAR(45), PRIMARY KEY (Id))
-CREATE TABLE OnapName (id INTEGER NOT NULL, created_date TIMESTAMP, description VARCHAR(2048), modified_date TIMESTAMP NOT NULL, onap_Name VARCHAR NOT NULL UNIQUE, created_by VARCHAR(45), modified_by VARCHAR(45), PRIMARY KEY (id))
-CREATE TABLE EnforcingType (id INTEGER NOT NULL, connectionQuery VARCHAR(255) NOT NULL, enforcingType VARCHAR NOT NULL UNIQUE, script VARCHAR(255) NOT NULL, valueQuery VARCHAR(255) NOT NULL, PRIMARY KEY (id))
-CREATE TABLE GlobalRoleSettings (role VARCHAR(45) NOT NULL, lockdown BOOLEAN, PRIMARY KEY (role))
-CREATE TABLE GroupPolicyScopeList (id INTEGER NOT NULL, description VARCHAR, groupList VARCHAR, name VARCHAR NOT NULL, PRIMARY KEY (id))
-CREATE TABLE GroupServiceList (id INTEGER NOT NULL, name VARCHAR NOT NULL, serviceList  VARCHAR, PRIMARY KEY (id))
-CREATE TABLE MicroServiceConfigName (id INTEGER NOT NULL, description  VARCHAR, name VARCHAR NOT NULL, PRIMARY KEY (id))
-CREATE TABLE MicroServiceLocation (id INTEGER NOT NULL, description  VARCHAR, name VARCHAR NOT NULL, PRIMARY KEY (id))
-CREATE TABLE Obadvice (id INTEGER NOT NULL, created_by VARCHAR(255) NOT NULL, created_date TIMESTAMP NOT NULL, description VARCHAR(2048), fulfill_on VARCHAR(32), modified_by VARCHAR(255) NOT NULL, modified_date TIMESTAMP NOT NULL, type VARCHAR NOT NULL, xacml_id VARCHAR(255) NOT NULL, PRIMARY KEY (id))
-CREATE TABLE ObadviceExpressions (id INTEGER NOT NULL, type VARCHAR NOT NULL, obadvice_id INTEGER, attribute_id INTEGER, PRIMARY KEY (id))
-CREATE TABLE PEPOptions (Id INTEGER NOT NULL, Actions VARCHAR, created_date TIMESTAMP, description VARCHAR(2048), modified_date TIMESTAMP NOT NULL, PEP_NAME VARCHAR NOT NULL, created_by VARCHAR(45), modified_by VARCHAR(45), PRIMARY KEY (Id))
-CREATE TABLE PIPConfigParams (id INTEGER NOT NULL, PARAM_DEFAULT VARCHAR(2048), PARAM_NAME VARCHAR(1024) NOT NULL, PARAM_VALUE VARCHAR(2048) NOT NULL, REQUIRED CHAR NOT NULL, PIP_ID INTEGER, PRIMARY KEY (id))
-CREATE TABLE PIPConfiguration (id INTEGER NOT NULL, CLASSNAME VARCHAR(2048) NOT NULL, CREATED_BY VARCHAR(255) NOT NULL, CREATED_DATE TIMESTAMP NOT NULL, DESCRIPTION VARCHAR(2048), ISSUER VARCHAR(1024), MODIFIED_BY VARCHAR(255) NOT NULL, MODIFIED_DATE TIMESTAMP NOT NULL, NAME VARCHAR(255) NOT NULL, READ_ONLY CHAR NOT NULL, REQUIRES_RESOLVER CHAR NOT NULL, TYPE INTEGER, PRIMARY KEY (id))
-CREATE TABLE PIPResolver (id INTEGER NOT NULL, CLASSNAME VARCHAR(2048) NOT NULL, CREATED_BY VARCHAR(255) NOT NULL, CREATED_DATE TIMESTAMP NOT NULL, DESCRIPTION VARCHAR(2048), ISSUER VARCHAR(1024), MODIFIED_BY VARCHAR(255) NOT NULL, MODIFIED_DATE TIMESTAMP NOT NULL, NAME VARCHAR(255) NOT NULL, READ_ONLY CHAR NOT NULL, PIP_ID INTEGER, PRIMARY KEY (id))
-CREATE TABLE PIPResolverParams (id INTEGER NOT NULL, PARAM_DEFAULT VARCHAR(2048), PARAM_NAME VARCHAR(1024) NOT NULL, PARAM_VALUE VARCHAR(2048) NOT NULL, REQUIRED CHAR NOT NULL, ID_RESOLVER INTEGER, PRIMARY KEY (id))
-CREATE TABLE PIPType (id INTEGER NOT NULL, type VARCHAR(45) NOT NULL, PRIMARY KEY (id))
-CREATE TABLE PolicyAlgorithms (id INTEGER NOT NULL, is_standard CHAR NOT NULL, short_name VARCHAR(64) NOT NULL, xacml_id VARCHAR(255) NOT NULL UNIQUE, PRIMARY KEY (id))
-CREATE TABLE policy_manangement (id INTEGER NOT NULL, CONFIG_NAME VARCHAR(45) NOT NULL, CREATE_DATE_TIME TIMESTAMP NOT NULL, CREATED_BY VARCHAR(45) NOT NULL, ONAP_NAME VARCHAR(45) NOT NULL, POLICY_NAME VARCHAR(45) NOT NULL, scope VARCHAR(45) NOT NULL, UPDATE_DATE_TIME TIMESTAMP NOT NULL, UPDATED_BY VARCHAR(45) NOT NULL, XML CLOB NOT NULL, PRIMARY KEY (id))
-CREATE TABLE PolicyScopeService (id INTEGER NOT NULL, description  VARCHAR, name VARCHAR NOT NULL, PRIMARY KEY (id))
-CREATE TABLE PolicyScopeType (id INTEGER NOT NULL, description  VARCHAR, name VARCHAR NOT NULL, PRIMARY KEY (id))
-CREATE TABLE PolicyScopeResource (id INTEGER NOT NULL, description  VARCHAR, name VARCHAR NOT NULL, PRIMARY KEY (id))
-CREATE TABLE PolicyScopeClosedLoop (id INTEGER NOT NULL, description  VARCHAR, name VARCHAR NOT NULL, PRIMARY KEY (id))
-CREATE TABLE portlist (id INTEGER NOT NULL, description VARCHAR, portname VARCHAR NOT NULL, PRIMARY KEY (id))
-CREATE TABLE protocollist (id INTEGER NOT NULL, description VARCHAR, protocolname VARCHAR NOT NULL, PRIMARY KEY (id))
-CREATE TABLE RemoteCatalogValues (id INTEGER NOT NULL, name VARCHAR NOT NULL, value VARCHAR, PRIMARY KEY (id))
-CREATE TABLE roles (id INTEGER NOT NULL, role VARCHAR(45) NOT NULL, scope VARCHAR(45), loginid VARCHAR(45), PRIMARY KEY (id))
-CREATE TABLE RuleAlgorithms (id INTEGER NOT NULL, is_standard CHAR NOT NULL, short_name VARCHAR(64) NOT NULL, xacml_id VARCHAR(255) NOT NULL UNIQUE, PRIMARY KEY (id))
-CREATE TABLE securityzone (id INTEGER NOT NULL, name VARCHAR NOT NULL, value VARCHAR, PRIMARY KEY (id))
-CREATE TABLE servicegroup (id INTEGER NOT NULL, appprotocol  VARCHAR, description VARCHAR, name VARCHAR NOT NULL, ports VARCHAR, transportprotocol VARCHAR, type VARCHAR, PRIMARY KEY (id))
-CREATE TABLE SystemLogDB (id INTEGER NOT NULL, date TIMESTAMP NOT NULL, description VARCHAR(2048), logtype VARCHAR(255) NOT NULL, remote VARCHAR(255) NOT NULL, system VARCHAR(255) NOT NULL, type VARCHAR NOT NULL, PRIMARY KEY (id))
-CREATE TABLE TERM (id INTEGER NOT NULL, action VARCHAR, created_date TIMESTAMP, destIPList VARCHAR, destPortList VARCHAR, fromzone VARCHAR, modified_date TIMESTAMP NOT NULL, portList VARCHAR, protocolList VARCHAR, srcIPList VARCHAR, srcPortList VARCHAR, description VARCHAR, termName VARCHAR NOT NULL, tozone VARCHAR, created_by VARCHAR(45), modified_by VARCHAR(45), PRIMARY KEY (id))
-CREATE TABLE VarbindDictionary (Id INTEGER NOT NULL, created_date TIMESTAMP, modified_date TIMESTAMP NOT NULL, varbind_Description VARCHAR(2048), varbind_Name VARCHAR NOT NULL UNIQUE, varbind_oid VARCHAR NOT NULL, created_by VARCHAR(45), modified_by VARCHAR(45), PRIMARY KEY (Id))
-CREATE TABLE VMType (id INTEGER NOT NULL, description VARCHAR, name VARCHAR NOT NULL, PRIMARY KEY (id))
-CREATE TABLE VNFType (id INTEGER NOT NULL, created_date TIMESTAMP, description VARCHAR(2048), modified_date TIMESTAMP NOT NULL, vnf_type VARCHAR NOT NULL UNIQUE, created_by VARCHAR(45), modified_by VARCHAR(45), PRIMARY KEY (id))
-CREATE TABLE VSCLAction (id INTEGER NOT NULL, created_date TIMESTAMP, description VARCHAR(2048), modified_date TIMESTAMP NOT NULL, vscl_action VARCHAR NOT NULL UNIQUE, created_by VARCHAR(45), modified_by VARCHAR(45), PRIMARY KEY (id))
-CREATE TABLE zone (id INTEGER NOT NULL, zonename VARCHAR NOT NULL, zonevalue VARCHAR, PRIMARY KEY (id))
-CREATE TABLE BackUpMonitorEntity (id INTEGER NOT NULL, flag VARCHAR NOT NULL, notification_record LONGVARCHAR, resource_name VARCHAR NOT NULL UNIQUE, node_name VARCHAR NOT NULL, last_seen TIMESTAMP, PRIMARY KEY (id))
-CREATE TABLE StateManagementEntity (id BIGINT NOT NULL, adminState VARCHAR(20) NOT NULL, availStatus VARCHAR(20) NOT NULL, created_Date TIMESTAMP, modifiedDate TIMESTAMP NOT NULL, opState VARCHAR(20) NOT NULL, resourceName VARCHAR(100) NOT NULL UNIQUE, standbyStatus VARCHAR(20) NOT NULL, PRIMARY KEY (id))
-CREATE TABLE ForwardProgressEntity (forwardProgressId BIGINT NOT NULL, created_date TIMESTAMP, fpc_count BIGINT NOT NULL, last_updated TIMESTAMP, resourceName VARCHAR(100) NOT NULL UNIQUE, PRIMARY KEY (forwardProgressId))
-CREATE TABLE ResourceRegistrationEntity (ResourceRegistrationId BIGINT NOT NULL, created_date TIMESTAMP, last_updated TIMESTAMP, nodeType VARCHAR(50), resourceName VARCHAR(100) NOT NULL UNIQUE, resourceUrl VARCHAR(255) NOT NULL UNIQUE, site VARCHAR(50), PRIMARY KEY (ResourceRegistrationId))
-CREATE TABLE IntegrityAuditEntity (id BIGINT NOT NULL, createdDate TIMESTAMP, designated BOOLEAN, jdbcDriver VARCHAR NOT NULL, jdbcPassword VARCHAR NOT NULL, jdbcUrl VARCHAR NOT NULL, jdbcUser VARCHAR NOT NULL, lastUpdated TIMESTAMP, nodeType VARCHAR, persistenceUnit VARCHAR NOT NULL, resourceName VARCHAR NOT NULL UNIQUE, site VARCHAR, PRIMARY KEY (id))
-CREATE TABLE PolicyGroupEntity (groupKey BIGINT NOT NULL, policyId BIGINT NOT NULL, PRIMARY KEY (groupKey, policyId))
-ALTER TABLE PolicyEntity ADD CONSTRAINT FK_PolicyEntity_configurationDataId FOREIGN KEY (configurationDataId) REFERENCES ConfigurationDataEntity (configurationDataId)
-ALTER TABLE PolicyEntity ADD CONSTRAINT FK_PolicyEntity_actionBodyId FOREIGN KEY (actionBodyId) REFERENCES ActionBodyEntity (actionBodyId)
-ALTER TABLE PdpEntity ADD CONSTRAINT FK_PdpEntity_groupKey FOREIGN KEY (groupKey) REFERENCES GroupEntity (groupKey)
-ALTER TABLE FunctionDefinition ADD CONSTRAINT FK_FunctionDefinition_return_datatype FOREIGN KEY (return_datatype) REFERENCES Datatype (id)
-ALTER TABLE Attribute ADD CONSTRAINT FK_Attribute_category FOREIGN KEY (category) REFERENCES Category (id)
-ALTER TABLE Attribute ADD CONSTRAINT FK_Attribute_constraint_type FOREIGN KEY (constraint_type) REFERENCES ConstraintType (id)
-ALTER TABLE Attribute ADD CONSTRAINT FK_Attribute_created_by FOREIGN KEY (created_by) REFERENCES UserInfo (loginid)
-ALTER TABLE Attribute ADD CONSTRAINT FK_Attribute_modified_by FOREIGN KEY (modified_by) REFERENCES UserInfo (loginid)
-ALTER TABLE Attribute ADD CONSTRAINT FK_Attribute_datatype FOREIGN KEY (datatype) REFERENCES Datatype (id)
-ALTER TABLE ConstraintValues ADD CONSTRAINT FK_ConstraintValues_attribute_id FOREIGN KEY (attribute_id) REFERENCES Attribute (id)
-ALTER TABLE FunctionArguments ADD CONSTRAINT FK_FunctionArguments_function_id FOREIGN KEY (function_id) REFERENCES FunctionDefinition (id)
-ALTER TABLE FunctionArguments ADD CONSTRAINT FK_FunctionArguments_datatype_id FOREIGN KEY (datatype_id) REFERENCES Datatype (id)
-ALTER TABLE ActionPolicyDict ADD CONSTRAINT FK_ActionPolicyDict_modified_by FOREIGN KEY (modified_by) REFERENCES UserInfo (loginid)
-ALTER TABLE ActionPolicyDict ADD CONSTRAINT FK_ActionPolicyDict_created_by FOREIGN KEY (created_by) REFERENCES UserInfo (loginid)
-ALTER TABLE DecisionSettings ADD CONSTRAINT FK_DecisionSettings_created_by FOREIGN KEY (created_by) REFERENCES UserInfo (loginid)
-ALTER TABLE DecisionSettings ADD CONSTRAINT FK_DecisionSettings_datatype FOREIGN KEY (datatype) REFERENCES Datatype (id)
-ALTER TABLE DecisionSettings ADD CONSTRAINT FK_DecisionSettings_modified_by FOREIGN KEY (modified_by) REFERENCES UserInfo (loginid)
-ALTER TABLE MicroServiceModels ADD CONSTRAINT FK_MicroServiceModels_imported_by FOREIGN KEY (imported_by) REFERENCES UserInfo (loginid)
-ALTER TABLE AttributeAssignment ADD CONSTRAINT FK_AttributeAssignment_OBADVICE_id FOREIGN KEY (OBADVICE_id) REFERENCES Obadvice (id)
-ALTER TABLE BRMSParamTemplate ADD CONSTRAINT FK_BRMSParamTemplate_created_by FOREIGN KEY (created_by) REFERENCES UserInfo (loginid)
-ALTER TABLE ClosedLoopD2Services ADD CONSTRAINT FK_ClosedLoopD2Services_modified_by FOREIGN KEY (modified_by) REFERENCES UserInfo (loginid)
-ALTER TABLE ClosedLoopD2Services ADD CONSTRAINT FK_ClosedLoopD2Services_created_by FOREIGN KEY (created_by) REFERENCES UserInfo (loginid)
-ALTER TABLE ClosedLoopSite ADD CONSTRAINT FK_ClosedLoopSite_modified_by FOREIGN KEY (modified_by) REFERENCES UserInfo (loginid)
-ALTER TABLE ClosedLoopSite ADD CONSTRAINT FK_ClosedLoopSite_created_by FOREIGN KEY (created_by) REFERENCES UserInfo (loginid)
-ALTER TABLE DescriptiveScope ADD CONSTRAINT FK_DescriptiveScope_created_by FOREIGN KEY (created_by) REFERENCES UserInfo (loginid)
-ALTER TABLE DescriptiveScope ADD CONSTRAINT FK_DescriptiveScope_modified_by FOREIGN KEY (modified_by) REFERENCES UserInfo (loginid)
-ALTER TABLE OnapName ADD CONSTRAINT FK_OnapName_modified_by FOREIGN KEY (modified_by) REFERENCES UserInfo (loginid)
-ALTER TABLE OnapName ADD CONSTRAINT FK_OnapName_created_by FOREIGN KEY (created_by) REFERENCES UserInfo (loginid)
-ALTER TABLE ObadviceExpressions ADD CONSTRAINT FK_ObadviceExpressions_obadvice_id FOREIGN KEY (obadvice_id) REFERENCES Obadvice (id)
-ALTER TABLE ObadviceExpressions ADD CONSTRAINT FK_ObadviceExpressions_attribute_id FOREIGN KEY (attribute_id) REFERENCES Attribute (id)
-ALTER TABLE PEPOptions ADD CONSTRAINT FK_PEPOptions_modified_by FOREIGN KEY (modified_by) REFERENCES UserInfo (loginid)
-ALTER TABLE PEPOptions ADD CONSTRAINT FK_PEPOptions_created_by FOREIGN KEY (created_by) REFERENCES UserInfo (loginid)
-ALTER TABLE PIPConfigParams ADD CONSTRAINT FK_PIPConfigParams_PIP_ID FOREIGN KEY (PIP_ID) REFERENCES PIPConfiguration (id)
-ALTER TABLE PIPConfiguration ADD CONSTRAINT FK_PIPConfiguration_TYPE FOREIGN KEY (TYPE) REFERENCES PIPType (id)
-ALTER TABLE PIPResolver ADD CONSTRAINT FK_PIPResolver_PIP_ID FOREIGN KEY (PIP_ID) REFERENCES PIPConfiguration (id)
-ALTER TABLE PIPResolverParams ADD CONSTRAINT FK_PIPResolverParams_ID_RESOLVER FOREIGN KEY (ID_RESOLVER) REFERENCES PIPResolver (id)
-ALTER TABLE roles ADD CONSTRAINT FK_roles_loginid FOREIGN KEY (loginid) REFERENCES UserInfo (loginid)
-ALTER TABLE TERM ADD CONSTRAINT FK_TERM_modified_by FOREIGN KEY (modified_by) REFERENCES UserInfo (loginid)
-ALTER TABLE TERM ADD CONSTRAINT FK_TERM_created_by FOREIGN KEY (created_by) REFERENCES UserInfo (loginid)
-ALTER TABLE VarbindDictionary ADD CONSTRAINT FK_VarbindDictionary_modified_by FOREIGN KEY (modified_by) REFERENCES UserInfo (loginid)
-ALTER TABLE VarbindDictionary ADD CONSTRAINT FK_VarbindDictionary_created_by FOREIGN KEY (created_by) REFERENCES UserInfo (loginid)
-ALTER TABLE VNFType ADD CONSTRAINT FK_VNFType_modified_by FOREIGN KEY (modified_by) REFERENCES UserInfo (loginid)
-ALTER TABLE VNFType ADD CONSTRAINT FK_VNFType_created_by FOREIGN KEY (created_by) REFERENCES UserInfo (loginid)
-ALTER TABLE VSCLAction ADD CONSTRAINT FK_VSCLAction_modified_by FOREIGN KEY (modified_by) REFERENCES UserInfo (loginid)
-ALTER TABLE VSCLAction ADD CONSTRAINT FK_VSCLAction_created_by FOREIGN KEY (created_by) REFERENCES UserInfo (loginid)
-ALTER TABLE PolicyGroupEntity ADD CONSTRAINT FK_PolicyGroupEntity_policyId FOREIGN KEY (policyId) REFERENCES PolicyEntity (policyId)
-ALTER TABLE PolicyGroupEntity ADD CONSTRAINT FK_PolicyGroupEntity_groupKey FOREIGN KEY (groupKey) REFERENCES GroupEntity (groupKey)
-CREATE TABLE SEQUENCE (SEQ_NAME VARCHAR(50) NOT NULL, SEQ_COUNT NUMERIC(38), PRIMARY KEY (SEQ_NAME))
-INSERT INTO SEQUENCE(SEQ_NAME, SEQ_COUNT) values ('SEQ_GEN', 0)
diff --git a/ONAP-PAP-REST/src/main/resources/META-INF/generatedDrop.ddl b/ONAP-PAP-REST/src/main/resources/META-INF/generatedDrop.ddl
deleted file mode 100644
index ce1769a..0000000
--- a/ONAP-PAP-REST/src/main/resources/META-INF/generatedDrop.ddl
+++ /dev/null
@@ -1,118 +0,0 @@
-ALTER TABLE PolicyEntity DROP CONSTRAINT FK_PolicyEntity_configurationDataId
-ALTER TABLE PolicyEntity DROP CONSTRAINT FK_PolicyEntity_actionBodyId
-ALTER TABLE PdpEntity DROP CONSTRAINT FK_PdpEntity_groupKey
-ALTER TABLE FunctionDefinition DROP CONSTRAINT FK_FunctionDefinition_return_datatype
-ALTER TABLE Attribute DROP CONSTRAINT FK_Attribute_category
-ALTER TABLE Attribute DROP CONSTRAINT FK_Attribute_constraint_type
-ALTER TABLE Attribute DROP CONSTRAINT FK_Attribute_created_by
-ALTER TABLE Attribute DROP CONSTRAINT FK_Attribute_modified_by
-ALTER TABLE Attribute DROP CONSTRAINT FK_Attribute_datatype
-ALTER TABLE ConstraintValues DROP CONSTRAINT FK_ConstraintValues_attribute_id
-ALTER TABLE FunctionArguments DROP CONSTRAINT FK_FunctionArguments_function_id
-ALTER TABLE FunctionArguments DROP CONSTRAINT FK_FunctionArguments_datatype_id
-ALTER TABLE ActionPolicyDict DROP CONSTRAINT FK_ActionPolicyDict_modified_by
-ALTER TABLE ActionPolicyDict DROP CONSTRAINT FK_ActionPolicyDict_created_by
-ALTER TABLE DecisionSettings DROP CONSTRAINT FK_DecisionSettings_created_by
-ALTER TABLE DecisionSettings DROP CONSTRAINT FK_DecisionSettings_datatype
-ALTER TABLE DecisionSettings DROP CONSTRAINT FK_DecisionSettings_modified_by
-ALTER TABLE MicroServiceModels DROP CONSTRAINT FK_MicroServiceModels_imported_by
-ALTER TABLE AttributeAssignment DROP CONSTRAINT FK_AttributeAssignment_OBADVICE_id
-ALTER TABLE BRMSParamTemplate DROP CONSTRAINT FK_BRMSParamTemplate_created_by
-ALTER TABLE ClosedLoopD2Services DROP CONSTRAINT FK_ClosedLoopD2Services_modified_by
-ALTER TABLE ClosedLoopD2Services DROP CONSTRAINT FK_ClosedLoopD2Services_created_by
-ALTER TABLE ClosedLoopSite DROP CONSTRAINT FK_ClosedLoopSite_modified_by
-ALTER TABLE ClosedLoopSite DROP CONSTRAINT FK_ClosedLoopSite_created_by
-ALTER TABLE DescriptiveScope DROP CONSTRAINT FK_DescriptiveScope_created_by
-ALTER TABLE DescriptiveScope DROP CONSTRAINT FK_DescriptiveScope_modified_by
-ALTER TABLE OnapName DROP CONSTRAINT FK_OnapName_modified_by
-ALTER TABLE OnapName DROP CONSTRAINT FK_OnapName_created_by
-ALTER TABLE ObadviceExpressions DROP CONSTRAINT FK_ObadviceExpressions_obadvice_id
-ALTER TABLE ObadviceExpressions DROP CONSTRAINT FK_ObadviceExpressions_attribute_id
-ALTER TABLE PEPOptions DROP CONSTRAINT FK_PEPOptions_modified_by
-ALTER TABLE PEPOptions DROP CONSTRAINT FK_PEPOptions_created_by
-ALTER TABLE PIPConfigParams DROP CONSTRAINT FK_PIPConfigParams_PIP_ID
-ALTER TABLE PIPConfiguration DROP CONSTRAINT FK_PIPConfiguration_TYPE
-ALTER TABLE PIPResolver DROP CONSTRAINT FK_PIPResolver_PIP_ID
-ALTER TABLE PIPResolverParams DROP CONSTRAINT FK_PIPResolverParams_ID_RESOLVER
-ALTER TABLE roles DROP CONSTRAINT FK_roles_loginid
-ALTER TABLE TERM DROP CONSTRAINT FK_TERM_modified_by
-ALTER TABLE TERM DROP CONSTRAINT FK_TERM_created_by
-ALTER TABLE VarbindDictionary DROP CONSTRAINT FK_VarbindDictionary_modified_by
-ALTER TABLE VarbindDictionary DROP CONSTRAINT FK_VarbindDictionary_created_by
-ALTER TABLE VNFType DROP CONSTRAINT FK_VNFType_modified_by
-ALTER TABLE VNFType DROP CONSTRAINT FK_VNFType_created_by
-ALTER TABLE VSCLAction DROP CONSTRAINT FK_VSCLAction_modified_by
-ALTER TABLE VSCLAction DROP CONSTRAINT FK_VSCLAction_created_by
-ALTER TABLE PolicyGroupEntity DROP CONSTRAINT FK_PolicyGroupEntity_policyId
-ALTER TABLE PolicyGroupEntity DROP CONSTRAINT FK_PolicyGroupEntity_groupKey
-DROP TABLE PolicyEntity
-DROP TABLE ConfigurationDataEntity
-DROP TABLE PolicyDBDaoEntity
-DROP TABLE GroupEntity
-DROP TABLE PdpEntity
-DROP TABLE ActionBodyEntity
-DROP TABLE DatabaseLockEntity
-DROP TABLE PolicyVersion
-DROP TABLE POLICYSCORE
-DROP TABLE FunctionDefinition
-DROP TABLE Attribute
-DROP TABLE Category
-DROP TABLE ConstraintType
-DROP TABLE ConstraintValues
-DROP TABLE Datatype
-DROP TABLE FunctionArguments
-DROP TABLE UserInfo
-DROP TABLE ActionPolicyDict
-DROP TABLE DecisionSettings
-DROP TABLE MicroServiceModels
-DROP TABLE actionlist
-DROP TABLE AddressGroup
-DROP TABLE AttributeAssignment
-DROP TABLE BRMSParamTemplate
-DROP TABLE ClosedLoopD2Services
-DROP TABLE ClosedLoopSite
-DROP TABLE DCAEUsers
-DROP TABLE DCAEuuid
-DROP TABLE DescriptiveScope
-DROP TABLE OnapName
-DROP TABLE EnforcingType
-DROP TABLE GlobalRoleSettings
-DROP TABLE GroupPolicyScopeList
-DROP TABLE GroupServiceList
-DROP TABLE MicroServiceConfigName
-DROP TABLE MicroServiceLocation
-DROP TABLE Obadvice
-DROP TABLE ObadviceExpressions
-DROP TABLE PEPOptions
-DROP TABLE PIPConfigParams
-DROP TABLE PIPConfiguration
-DROP TABLE PIPResolver
-DROP TABLE PIPResolverParams
-DROP TABLE PIPType
-DROP TABLE PolicyAlgorithms
-DROP TABLE policy_manangement
-DROP TABLE PolicyScopeService
-DROP TABLE PolicyScopeType
-DROP TABLE PolicyScopeResource
-DROP TABLE PolicyScopeClosedLoop
-DROP TABLE portlist
-DROP TABLE protocollist
-DROP TABLE RemoteCatalogValues
-DROP TABLE roles
-DROP TABLE RuleAlgorithms
-DROP TABLE securityzone
-DROP TABLE servicegroup
-DROP TABLE SystemLogDB
-DROP TABLE TERM
-DROP TABLE VarbindDictionary
-DROP TABLE VMType
-DROP TABLE VNFType
-DROP TABLE VSCLAction
-DROP TABLE zone
-DROP TABLE BackUpMonitorEntity
-DROP TABLE StateManagementEntity
-DROP TABLE ForwardProgressEntity
-DROP TABLE ResourceRegistrationEntity
-DROP TABLE IntegrityAuditEntity
-DROP TABLE PolicyGroupEntity
-DELETE FROM SEQUENCE WHERE SEQ_NAME = 'SEQ_GEN'
diff --git a/ONAP-PAP-REST/src/main/resources/META-INF/persistence.xml b/ONAP-PAP-REST/src/main/resources/META-INF/persistence.xml
index b0a76c4..7be9501 100644
--- a/ONAP-PAP-REST/src/main/resources/META-INF/persistence.xml
+++ b/ONAP-PAP-REST/src/main/resources/META-INF/persistence.xml
@@ -190,8 +190,8 @@
             <property name="javax.persistence.jdbc.user" value="sa"/>
             <property name="javax.persistence.jdbc.password" value=""/>
             <property name="javax.persistence.schema-generation.scripts.action" value="drop-and-create"/>
-            <property name="javax.persistence.schema-generation.scripts.create-target" value="./src/main/resources/META-INF/generatedCreate.ddl"/>
-            <property name="javax.persistence.schema-generation.scripts.drop-target" value="./src/main/resources/META-INF/generatedDrop.ddl"/>
+            <property name="javax.persistence.schema-generation.scripts.create-target" value="./src/test/resources/generatedCreate.ddl"/>
+            <property name="javax.persistence.schema-generation.scripts.drop-target" value="./src/test/resources/generatedDrop.ddl"/>
             <property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
 			<property name="javax.persistence.schema-generation.create-source" value="metadata-then-script"/>
 			<property name="javax.persistence.schema-generation.drop-source" value="script"/>
diff --git a/ONAP-PAP-REST/src/test/java/org/onap/policy/pap/test/XACMLPAPTest.java b/ONAP-PAP-REST/src/test/java/org/onap/policy/pap/test/XACMLPAPTest.java
new file mode 100644
index 0000000..f110c5b
--- /dev/null
+++ b/ONAP-PAP-REST/src/test/java/org/onap/policy/pap/test/XACMLPAPTest.java
@@ -0,0 +1,161 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.pap.test;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Properties;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.tomcat.dbcp.dbcp2.BasicDataSource;
+import org.hibernate.SessionFactory;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.onap.policy.pap.xacml.rest.XACMLPapServlet;
+import org.onap.policy.pap.xacml.rest.daoimpl.CommonClassDaoImpl;
+import org.onap.policy.pap.xacml.rest.policycontroller.PolicyCreation;
+import org.onap.policy.utils.PolicyUtils;
+import org.onap.policy.xacml.std.pap.StdPAPPolicy;
+import org.springframework.mock.web.MockHttpServletResponse;
+import org.springframework.mock.web.MockServletConfig;
+import org.springframework.orm.hibernate4.LocalSessionFactoryBuilder;
+
+import com.mockrunner.mock.web.MockServletInputStream;
+
+
+public class XACMLPAPTest {
+
+    private static final String ENVIRONMENT_HEADER = "Environment";
+    private List<String> headers = new ArrayList<>();
+    private HttpServletRequest httpServletRequest;
+    private HttpServletResponse httpServletResponse;
+    private ServletOutputStream mockOutput;
+    private ServletConfig servletConfig;
+    private XACMLPapServlet pap;
+    private SessionFactory sessionFactory;
+
+    @Before
+    public void setUp() throws ServletException {
+        httpServletRequest = Mockito.mock(HttpServletRequest.class);
+        httpServletResponse = Mockito.mock(MockHttpServletResponse.class);
+        Mockito.when(httpServletRequest.getHeaderNames()).thenReturn(Collections.enumeration(headers));
+        Mockito.when(httpServletRequest.getAttributeNames()).thenReturn(Collections.enumeration(headers));
+
+        servletConfig = Mockito.mock(MockServletConfig.class);
+        System.setProperty("com.sun.management.jmxremote.port", "9993");
+        Mockito.when(servletConfig.getInitParameterNames()).thenReturn(Collections.enumeration(headers));
+        Mockito.when(servletConfig.getInitParameter("XACML_PROPERTIES_NAME"))
+                .thenReturn("src/test/resources/xacml.pap.properties");
+        pap = new XACMLPapServlet();
+        pap.init(servletConfig);
+    }
+    
+    @Test
+    public void testFirwallCreatePolicy() throws IOException, ServletException, SQLException {
+        httpServletRequest = Mockito.mock(HttpServletRequest.class);
+        String json = "";
+        Mockito.when(httpServletRequest.getHeader(ENVIRONMENT_HEADER)).thenReturn("DEVL");
+        Mockito.when(httpServletRequest.getMethod()).thenReturn("PUT");
+        Mockito.when(httpServletRequest.getParameter("apiflag")).thenReturn("api");
+        Mockito.when(httpServletRequest.getParameter("operation")).thenReturn("create");
+        Mockito.when(httpServletRequest.getParameter("policyType")).thenReturn("Config");
+        StdPAPPolicy newPAPPolicy = new StdPAPPolicy("Firewall Config", "test", "testDescription", "Test", false, "test", json, 0, 
+                "5","default", "false", "");
+        MockServletInputStream mockInput = new MockServletInputStream(PolicyUtils.objectToJsonString(newPAPPolicy).getBytes());
+        Mockito.when(httpServletRequest.getInputStream()).thenReturn(mockInput);
+        
+        // set DBDao
+        setDBDao();
+        pap.service(httpServletRequest, httpServletResponse);
+        
+        Mockito.verify(httpServletResponse).setStatus(HttpServletResponse.SC_OK);
+        Mockito.verify(httpServletResponse).addHeader("successMapKey", "success");
+        Mockito.verify(httpServletResponse).addHeader("policyName", "test.Config_FW_test.1.xml");
+        
+    }
+    
+    
+
+    private void setDBDao() throws SQLException {
+        BasicDataSource dataSource = new BasicDataSource();
+        dataSource.setDriverClassName("org.h2.Driver");
+        // In-memory DB for testing
+        dataSource.setUrl("jdbc:h2:mem:test");
+        dataSource.setUsername("sa");
+        dataSource.setPassword("");
+        LocalSessionFactoryBuilder sessionBuilder = new LocalSessionFactoryBuilder(dataSource);
+        sessionBuilder.scanPackages("org.onap.*", "com.*");
+
+        Properties properties = new Properties();
+        properties.put("hibernate.show_sql", "false");
+        properties.put("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
+        properties.put("hibernate.hbm2ddl.auto", "drop");
+        properties.put("hibernate.hbm2ddl.auto", "create");
+
+        sessionBuilder.addProperties(properties);
+        sessionFactory = sessionBuilder.buildSessionFactory();
+
+        // Set up dao with SessionFactory
+        CommonClassDaoImpl.setSessionfactory(sessionFactory);
+        PolicyCreation.setCommonClassDao(new CommonClassDaoImpl());
+    }
+
+    @Test
+    public void testDummy() throws ServletException, IOException {
+
+        Mockito.when(httpServletRequest.getMethod()).thenReturn("POST");
+        mockOutput = Mockito.mock(ServletOutputStream.class);
+
+        try {
+            Mockito.when(httpServletResponse.getOutputStream()).thenReturn(mockOutput);
+        } catch (IOException e) {
+            fail();
+        }
+
+        try {
+            pap.service(httpServletRequest, httpServletResponse);
+            assertTrue(true);
+        } catch (Exception e) {
+            fail();
+        }
+    }
+    
+    @After
+    public void destroy(){
+        if(sessionFactory!=null){
+            sessionFactory.close();
+        }
+        pap.destroy();
+    }
+}
diff --git a/ONAP-PAP-REST/src/test/java/org/onap/policy/pap/xacml/rest/components/ActionPolicyTest.java b/ONAP-PAP-REST/src/test/java/org/onap/policy/pap/xacml/rest/components/ActionPolicyTest.java
index 3adb94c..b93cca3 100644
--- a/ONAP-PAP-REST/src/test/java/org/onap/policy/pap/xacml/rest/components/ActionPolicyTest.java
+++ b/ONAP-PAP-REST/src/test/java/org/onap/policy/pap/xacml/rest/components/ActionPolicyTest.java
@@ -57,7 +57,7 @@
 	@Before
 	public void setUp() throws Exception {
 		logger.info("setUp: Entering");
-		System.setProperty(XACMLProperties.XACML_PROPERTIES_NAME,"xacml.pap.properties");
+		System.setProperty(XACMLProperties.XACML_PROPERTIES_NAME,"src/test/resources/xacml.pap.properties");
 
 		dynamicRuleAlgorithmLabels.add("test");
 		dynamicRuleAlgorithmField1.add("testField1");
diff --git a/ONAP-PAP-REST/src/test/java/org/onap/policy/pap/xacml/rest/components/DecisionPolicyTest.java b/ONAP-PAP-REST/src/test/java/org/onap/policy/pap/xacml/rest/components/DecisionPolicyTest.java
index 6d1d446..3854ab9 100644
--- a/ONAP-PAP-REST/src/test/java/org/onap/policy/pap/xacml/rest/components/DecisionPolicyTest.java
+++ b/ONAP-PAP-REST/src/test/java/org/onap/policy/pap/xacml/rest/components/DecisionPolicyTest.java
@@ -65,7 +65,7 @@
 	@Before
 	public void setUp() throws Exception {
 		logger.info("setUp: Entering");
-		System.setProperty(XACMLProperties.XACML_PROPERTIES_NAME,"xacml.pap.properties");
+		System.setProperty(XACMLProperties.XACML_PROPERTIES_NAME,"src/test/resources/xacml.pap.properties");
 
 		policyAdapter.setPolicyName("Test.Decision_junitTest.1.xml");
 		policyAdapter.setPolicyDescription("testing");
diff --git a/ONAP-PAP-REST/src/test/java/org/onap/policy/pap/xacml/rest/components/FirewallConfigPolicyTest.java b/ONAP-PAP-REST/src/test/java/org/onap/policy/pap/xacml/rest/components/FirewallConfigPolicyTest.java
index aed09ce..1a97d7f 100644
--- a/ONAP-PAP-REST/src/test/java/org/onap/policy/pap/xacml/rest/components/FirewallConfigPolicyTest.java
+++ b/ONAP-PAP-REST/src/test/java/org/onap/policy/pap/xacml/rest/components/FirewallConfigPolicyTest.java
@@ -54,7 +54,7 @@
 	@Before
 	public void setUp() throws Exception {
 		logger.info("setup: enter");
-		System.setProperty(XACMLProperties.XACML_PROPERTIES_NAME,"xacml.pap.properties");
+		System.setProperty(XACMLProperties.XACML_PROPERTIES_NAME,"src/test/resources/xacml.pap.properties");
 
 		policyAdapter.setPolicyName("FWjunitTest");
 		policyAdapter.setPolicyDescription("test");
diff --git a/ONAP-PAP-REST/src/test/java/org/onap/policy/pap/xacml/rest/components/PolicyDBDaoTest.java b/ONAP-PAP-REST/src/test/java/org/onap/policy/pap/xacml/rest/components/PolicyDBDaoTest.java
index 14afa01..bba2afa 100644
--- a/ONAP-PAP-REST/src/test/java/org/onap/policy/pap/xacml/rest/components/PolicyDBDaoTest.java
+++ b/ONAP-PAP-REST/src/test/java/org/onap/policy/pap/xacml/rest/components/PolicyDBDaoTest.java
@@ -68,7 +68,7 @@
 	EntityManagerFactory emf;
 	@Before
 	public void init(){
-		System.setProperty(XACMLProperties.XACML_PROPERTIES_NAME,"xacml.pap.properties");
+	    System.setProperty(XACMLProperties.XACML_PROPERTIES_NAME,"src/test/resources/xacml.pap.properties");
 		emf = Persistence.createEntityManagerFactory("testPapPU");
 		EntityManager em = emf.createEntityManager();
 		em.getTransaction().begin();
diff --git a/ONAP-PAP-REST/src/test/resources/xacml.pap.properties b/ONAP-PAP-REST/src/test/resources/xacml.pap.properties
new file mode 100644
index 0000000..f886435
--- /dev/null
+++ b/ONAP-PAP-REST/src/test/resources/xacml.pap.properties
@@ -0,0 +1,161 @@
+###
+# ============LICENSE_START=======================================================
+# ONAP-PAP-REST
+# ================================================================================
+# Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# 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.
+# ============LICENSE_END=========================================================
+###
+#=====================================================================================#
+#================The Below Properties are default, shouldn't change them==============#
+#=====================================================================================#
+#
+# This is our factory that will create our engine
+#
+xacml.PAP.papEngineFactory=org.onap.policy.xacml.std.pap.StdEngineFactory
+# Dictionary and Policy Implementation Classes Properties
+dictionary.impl.className=org.onap.policy.pap.xacml.rest.handler.DictionaryHandlerImpl
+savePolicy.impl.className=org.onap.policy.pap.xacml.rest.handler.SavePolicyHandler
+pushPolicy.impl.className=org.onap.policy.pap.xacml.rest.handler.PushPolicyHandler
+deletePolicy.impl.className=org.onap.policy.pap.xacml.rest.handler.DeleteHandler
+
+#=====================================================================================#
+#===============The Below Properties will be changed based on Environment=============#
+#=====================================================================================#
+#
+# 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:8070/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=100000
+#
+# Heartbeat connection timeout (in milliseconds)
+#
+xacml.rest.pap.heartbeat.timeout=100000
+
+# new Property Please mention your PAP-REST webapps Location here. 
+xacml.rest.config.webapps=src/test/resources/webapps/
+
+#Turn the audit on to synchronize the DB/file system
+#xacml.rest.pap.run.audit.flag=true
+#Turn the audit off to not synchronize the DB/file system
+#xacml.rest.pap.run.audit.flag=false
+xacml.rest.pap.run.audit.flag=true
+
+#Audit will synchronize the file system to match the contents of the DB
+#xacml.rest.pap.filesystem.audit=true
+#Audit will synchronize the DB to match the contents of the file system 
+#xacml.rest.pap.filesystem.audit=false
+xacml.rest.pap.filesystem.audit=false
+xacm.xcor.required.pattern=1,1
+# id
+xacml.rest.pap.userid=testpap
+# pass
+xacml.rest.pap.password=alpha123
+# pdps file
+xacml.rest.pdp.idfile=test.properties
+
+#Properties for db access
+#properties for MySql xacml database:  PLEASE DO NOT REMOVE... NEEDED FOR APIs
+javax.persistence.jdbc.driver=org.h2.Driver
+javax.persistence.jdbc.url=jdbc:h2:file:./sql/xacmlTest
+javax.persistence.jdbc.user=sa
+javax.persistence.jdbc.password=
+
+#Time in ms which a Policy DB transaction will wait to get the transaction lock object
+xacml.rest.pap.transaction.waitms=500000
+	
+#Policy DB transaction timeout in ms after it has obtained the transaction lock object
+xacml.rest.pap.transaction.timeoutms=500000
+
+#Policy Audit timeout in ms after it has obtained the transaction lock object
+xacml.rest.pap.audit.timeoutms=500000
+
+#controls how long the pap will wait before giving up when sending notifications to other paps
+xacml.rest.pap.notify.timeoutms=10000
+
+#the number of times an incoming policy update notification will be tried to be processed (or until it succeeds)
+xacml.rest.pap.incomingnotification.tries=4
+
+#***Properties for IntegrityMonitor integration defined in XACMLRestProperties.java***
+
+#The name of the PAP.  Must be unique across the system
+xacml.rest.pap.resource.name=site_1.pap_1
+
+#***Properties for IntegrityMonitor integration defined in IntegrityMonitorProperties.java***
+
+#Interval between forward progress counter updates in seconds
+fp_monitor_interval=30
+
+#Number of forward progress counter failures before failover
+failed_counter_threshold=3
+
+#Interval in seconds between test transactions if there is no other traffic
+test_trans_interval=10
+
+#Interval in seconds between updates of the forward progress counter in the DB
+write_fpc_interval=5
+
+#Name of the site 
+site_name=site_1
+
+#Node type. Can take values of: pdp-xacml, pdp-drools, pap, pap-admin, logparser, brms-gateway, 
+#astra-gateway, elk-server 
+node_type=pap
+
+#Dependency groups are groups of resources upon which a node operational state is dependent upon (dependency_groups). 
+#Each group is a comma-separated list of resource names and groups are separated by a semicolon. A group may contain
+#one or more members.
+dependency_groups=site_1.logparser_1;site_1.adminconsole_1;site_1.elk_1
+
+# The (optional) period of time in seconds between executions of the integrity audit.
+# Value < 0 : Audit does not run (default value if property is not present = -1)
+# Value = 0 : Audit runs continuously
+# Value > 0 : The period of time in seconds between execution of the audit on a particular node
+integrity_audit_period_seconds=-1
+
+ENVIRONMENT=DEVL
+
+#
+#PolicySafetyChecker properties
+#
+#Turn safetyChecker on/off
+xacml.rest.pap.safetychecker=on
+PDP_URL1 = http://localhost:8082/pdp/, testpdp, alpha456
+CLIENT_ID=
+CLIENT_KEY=
+
+#Micro Service Model Properties
+xacml.policy.msOnapName=http://org.onap
+xacml.policy.msPolicyName=http://org.onap.policy
\ No newline at end of file
diff --git a/ONAP-PDP-REST/pom.xml b/ONAP-PDP-REST/pom.xml
index 64c036a..a2f7f72 100644
--- a/ONAP-PDP-REST/pom.xml
+++ b/ONAP-PDP-REST/pom.xml
@@ -80,15 +80,10 @@
 			<version>19.0</version>
 		</dependency>
 		<dependency>
-			<groupId>mysql</groupId>
-			<artifactId>mysql-connector-java</artifactId>
-			<version>5.1.30</version>
-		</dependency>
-		<dependency>
-			<groupId>org.mariadb.jdbc</groupId>
-			<artifactId>mariadb-java-client</artifactId>
-			<version>1.2.3</version>
-		</dependency>
+            <groupId>org.mariadb.jdbc</groupId>
+            <artifactId>mariadb-java-client</artifactId>
+            <version>2.1.1</version>
+        </dependency>
 		<dependency>
 			<groupId>postgresql</groupId>
 			<artifactId>postgresql</artifactId>
diff --git a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionAccessPermittedTest.java b/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionAccessPermittedTest.java
deleted file mode 100644
index 4abfd99..0000000
--- a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionAccessPermittedTest.java
+++ /dev/null
@@ -1,521 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * ONAP-PDP
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.policy.pdp.test;
-
-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.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import javax.xml.namespace.NamespaceContext;
-
-import org.junit.Ignore;
-
-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 com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionAccessPermitted;
-
-/**
- * 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.
- * 
- *
- */
-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<>();
-	
-	
-	
-	// 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/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionArithmeticTest.java b/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionArithmeticTest.java
deleted file mode 100644
index 56e79cf..0000000
--- a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionArithmeticTest.java
+++ /dev/null
@@ -1,717 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * ONAP-PDP
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.policy.pdp.test;
-
-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;
-import com.att.research.xacmlatt.pdp.std.functions.*;
-
-/**
- * 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
- * 
- *
- */
-public class FunctionDefinitionArithmeticTest {
-
-	/*
-	 * variables useful in the following tests
-	 */
-	List<FunctionArgument> arguments = new ArrayList<>();
-	
-	@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/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionBagIsInTest.java b/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionBagIsInTest.java
deleted file mode 100644
index 09fd95f..0000000
--- a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionBagIsInTest.java
+++ /dev/null
@@ -1,221 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * ONAP-PDP
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.policy.pdp.test;
-
-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;
-import com.att.research.xacmlatt.pdp.std.functions.*;
-
-/**
- * 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
- * 
- *
- */
-public class FunctionDefinitionBagIsInTest {
-
-
-	/*
-	 * variables useful in the following tests
-	 */
-	List<FunctionArgument> arguments = new ArrayList<>();
-	
-	
-	@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(java.lang.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(java.lang.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(java.lang.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(java.lang.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/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionBagOneAndOnlyTest.java b/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionBagOneAndOnlyTest.java
deleted file mode 100644
index 192747a..0000000
--- a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionBagOneAndOnlyTest.java
+++ /dev/null
@@ -1,224 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * ONAP-PDP
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.policy.pdp.test;
-
-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;
-import com.att.research.xacmlatt.pdp.std.functions.*;
-
-/**
- * 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
- * 
- *
- */
-public class FunctionDefinitionBagOneAndOnlyTest {
-
-
-	/*
-	 * variables useful in the following tests
-	 */
-	List<FunctionArgument> arguments = new ArrayList<>();
-	
-	
-	@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(java.lang.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(java.lang.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/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionBagSizeTest.java b/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionBagSizeTest.java
deleted file mode 100644
index f2bcbc5..0000000
--- a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionBagSizeTest.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * ONAP-PDP
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.policy.pdp.test;
-
-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;
-import com.att.research.xacmlatt.pdp.std.functions.*;
-
-/**
- * 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
- * 
- *
- */
-public class FunctionDefinitionBagSizeTest {
-
-
-	/*
-	 * variables useful in the following tests
-	 */
-	List<FunctionArgument> arguments = new ArrayList<>();
-	
-	
-	@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(java.math.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(java.math.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(java.math.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(java.math.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/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionBagTest.java b/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionBagTest.java
deleted file mode 100644
index d96bd27..0000000
--- a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionBagTest.java
+++ /dev/null
@@ -1,547 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * ONAP-PDP
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.policy.pdp.test;
-
-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;
-import com.att.research.xacmlatt.pdp.std.functions.*;
-
-/**
- * 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
- * 
- *
- */
-public class FunctionDefinitionBagTest {
-
-
-	/*
-	 * variables useful in the following tests
-	 */
-	List<FunctionArgument> arguments = new ArrayList<>();
-	
-	
-	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/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionBaseTest.java b/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionBaseTest.java
deleted file mode 100644
index 334226c..0000000
--- a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionBaseTest.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * ONAP-PDP
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.policy.pdp.test;
-
-
-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;
-import com.att.research.xacmlatt.pdp.std.functions.*;
-
-/**
- * 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
- * 
- *
- */
-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/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionComparisonTest.java b/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionComparisonTest.java
deleted file mode 100644
index 4cd5585..0000000
--- a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionComparisonTest.java
+++ /dev/null
@@ -1,1366 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * ONAP-PDP
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.policy.pdp.test;
-
-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;
-import com.att.research.xacmlatt.pdp.std.functions.*;
-
-/**
- * Test FunctionDefinitionComparison
- * 
- * TO RUN - use jUnit
- * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test
- * 
- *
- */
-public class FunctionDefinitionComparisonTest {
-
-	/*
-	 * variables useful in the following tests
-	 */
-	List<FunctionArgument> arguments = new ArrayList<>();
-	
-	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);
-	}
-
-
-
-}
diff --git a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionDateTimeArithmeticTest.java b/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionDateTimeArithmeticTest.java
deleted file mode 100644
index 809733e..0000000
--- a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionDateTimeArithmeticTest.java
+++ /dev/null
@@ -1,1602 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * ONAP-PDP
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.policy.pdp.test;
-
-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;
-import com.att.research.xacmlatt.pdp.std.functions.*;
-
-/**
- * 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
- * 
- *
- */
-public class FunctionDefinitionDateTimeArithmeticTest {
-
-
-	/*
-	 * variables useful in the following tests
-	 */
-	List<FunctionArgument> arguments = new ArrayList<>();
-	
-	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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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(com.att.research.xacml.std.datatypes.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/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionEqualityTest.java b/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionEqualityTest.java
deleted file mode 100644
index 9a94ef6..0000000
--- a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionEqualityTest.java
+++ /dev/null
@@ -1,1192 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * ONAP-PDP
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.policy.pdp.test;
-
-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;
-import com.att.research.xacmlatt.pdp.std.functions.*;
-
-/**
- * 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.
- * 
- *
- */
-public class FunctionDefinitionEqualityTest {
-
-	/*
-	 * variables useful in the following tests
-	 */
-	List<FunctionArgument> arguments = new ArrayList<>();
-	
-	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/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionHigherOrderBagTest.java b/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionHigherOrderBagTest.java
deleted file mode 100644
index 95a83d7..0000000
--- a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionHigherOrderBagTest.java
+++ /dev/null
@@ -1,2193 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * ONAP-PDP
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.policy.pdp.test;
-
-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;
-import com.att.research.xacmlatt.pdp.std.functions.*;
-
-/**
- * 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
- * 
- *
- */
-public class FunctionDefinitionHigherOrderBagTest {
-
-
-	/*
-	 * variables useful in the following tests
-	 */
-	List<FunctionArgument> arguments = new ArrayList<>();
-	
-	
-	
-	//
-	// 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/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionHomogeneousSimpleTest.java b/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionHomogeneousSimpleTest.java
deleted file mode 100644
index c72bfab..0000000
--- a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionHomogeneousSimpleTest.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * ONAP-PDP
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-
-
-package org.onap.policy.pdp.test;
-
-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;
-import com.att.research.xacmlatt.pdp.std.functions.*;
-
-/**
- * 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
- * 
- *
- */
-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<>();
-		List<FunctionArgument> listFunctionArguments = new ArrayList<>();
-		
-		// 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/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionLogicalTest.java b/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionLogicalTest.java
deleted file mode 100644
index 1778dd1..0000000
--- a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionLogicalTest.java
+++ /dev/null
@@ -1,422 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * ONAP-PDP
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.policy.pdp.test;
-
-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;
-import com.att.research.xacmlatt.pdp.std.functions.*;
-
-/**
- * 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
- * 
- *
- */
-public class FunctionDefinitionLogicalTest {
-
-	/*
-	 * variables useful in the following tests
-	 */
-	List<FunctionArgument> arguments = new ArrayList<>();
-	
-	// 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/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionNumberTypeConversionTest.java b/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionNumberTypeConversionTest.java
deleted file mode 100644
index 471025e..0000000
--- a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionNumberTypeConversionTest.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * ONAP-PDP
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.policy.pdp.test;
-
-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;
-import com.att.research.xacmlatt.pdp.std.functions.*;
-
-/**
- * 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
- * 
- *
- */
-public class FunctionDefinitionNumberTypeConversionTest {
-	
-	/*
-	 * variables useful in the following tests
-	 */
-	List<FunctionArgument> arguments = new ArrayList<>();
-	
-	@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/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionRegexpMatchTest.java b/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionRegexpMatchTest.java
deleted file mode 100644
index c631e1e..0000000
--- a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionRegexpMatchTest.java
+++ /dev/null
@@ -1,511 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * ONAP-PDP
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.policy.pdp.test;
-
-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;
-import com.att.research.xacmlatt.pdp.std.functions.*;
-
-/**
- * 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
- * 
- *
- */
-public class FunctionDefinitionRegexpMatchTest {
-
-
-	/*
-	 * variables useful in the following tests
-	 */
-	List<FunctionArgument> arguments = new ArrayList<>();
-	
-	
-	@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(java.lang.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(java.lang.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(java.lang.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(java.lang.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("10.123.13.14");
-			addr2 = IPAddress.newInstance("10.12.13.14");
-		} 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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionSetTest.java b/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionSetTest.java
deleted file mode 100644
index 8f22c82..0000000
--- a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionSetTest.java
+++ /dev/null
@@ -1,1903 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * ONAP-PDP
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.policy.pdp.test;
-
-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;
-import com.att.research.xacmlatt.pdp.std.functions.*;
-
-/**
- * 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
- * 
- *
- */
-public class FunctionDefinitionSetTest {
-
-
-	/*
-	 * variables useful in the following tests
-	 */
-	List<FunctionArgument> arguments = new ArrayList<>();
-	
-	
-	
-	//
-	// 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/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionSpecialMatchTest.java b/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionSpecialMatchTest.java
deleted file mode 100644
index e4c6851..0000000
--- a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionSpecialMatchTest.java
+++ /dev/null
@@ -1,487 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * ONAP-PDP
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.policy.pdp.test;
-
-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;
-import com.att.research.xacmlatt.pdp.std.functions.*;
-
-/**
- * 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
- * 
- *
- */
-public class FunctionDefinitionSpecialMatchTest {
-	
-	/*
-	 * variables useful in the following tests
-	 */
-	List<FunctionArgument> arguments = new ArrayList<>();
-	
-	@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/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionStringConversionTest.java b/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionStringConversionTest.java
deleted file mode 100644
index 3268266..0000000
--- a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionStringConversionTest.java
+++ /dev/null
@@ -1,2504 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * ONAP-PDP
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.policy.pdp.test;
-
-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;
-import com.att.research.xacmlatt.pdp.std.functions.*;
-
-/**
- * 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
- * 
- *
- */
-public class FunctionDefinitionStringConversionTest {
-	
-	/*
-	 * variables useful in the following tests
-	 */
-	List<FunctionArgument> arguments = new ArrayList<>();
-	
-	
-	/**
-	 * 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/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionStringEqualIgnoreCaseTest.java b/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionStringEqualIgnoreCaseTest.java
deleted file mode 100644
index 9c5c8a1..0000000
--- a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionStringEqualIgnoreCaseTest.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * ONAP-PDP
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.policy.pdp.test;
-
-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;
-import com.att.research.xacmlatt.pdp.std.functions.*;
-
-/**
- * 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
- * 
- *
- */
-public class FunctionDefinitionStringEqualIgnoreCaseTest {
-
-	/*
-	 * variables useful in the following tests
-	 */
-	List<FunctionArgument> arguments = new ArrayList<>();
-	
-	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/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionStringFunctionsTest.java b/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionStringFunctionsTest.java
deleted file mode 100644
index c6cba9f..0000000
--- a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionStringFunctionsTest.java
+++ /dev/null
@@ -1,1497 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * ONAP-PDP
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.policy.pdp.test;
-
-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;
-import com.att.research.xacmlatt.pdp.std.functions.*;
-
-/**
- * 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
- * 
- *
- */
-public class FunctionDefinitionStringFunctionsTest {
-
-
-	/*
-	 * variables useful in the following tests
-	 */
-	List<FunctionArgument> arguments = new ArrayList<>();
-	
-	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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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(java.lang.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/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionStringNormalizeTest.java b/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionStringNormalizeTest.java
deleted file mode 100644
index 2631be0..0000000
--- a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionStringNormalizeTest.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * ONAP-PDP
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.policy.pdp.test;
-
-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;
-import com.att.research.xacmlatt.pdp.std.functions.*;
-
-/**
- * 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
- * 
- *
- */
-public class FunctionDefinitionStringNormalizeTest {
-	
-	/*
-	 * variables useful in the following tests
-	 */
-	List<FunctionArgument> arguments = new ArrayList<>();
-	
-	@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/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionURIStringConcatenateTest.java b/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionURIStringConcatenateTest.java
deleted file mode 100644
index 63ae207..0000000
--- a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionURIStringConcatenateTest.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * ONAP-PDP
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.policy.pdp.test;
-
-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;
-import com.att.research.xacmlatt.pdp.std.functions.*;
-
-/**
- * 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
- * 
- *
- */
-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<>();
-	
-
-	@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(java.net.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(java.net.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(java.net.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/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionXPathTest.java b/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionXPathTest.java
deleted file mode 100644
index b174c42..0000000
--- a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/FunctionDefinitionXPathTest.java
+++ /dev/null
@@ -1,1127 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * ONAP-PDP
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.policy.pdp.test;
-
-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;
-import com.att.research.xacmlatt.pdp.std.functions.*;
-
-/**
- * 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
- * 
- *
- */
-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/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/PDPTest.java b/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/PDPTest.java
deleted file mode 100644
index 6442d7a..0000000
--- a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/PDPTest.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * ONAP-PDP
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.policy.pdp.test;
-
-
-import static org.junit.Assert.assertNull;
-//import static org.junit.Assert.fail;
-
-import org.junit.Test; 
-
-public class PDPTest {
-		
-	@Test
-	public void testDummy() {
-		assertNull(null);
-	}
-	
-}
diff --git a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/TestRunner.java b/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/TestRunner.java
deleted file mode 100644
index b131964..0000000
--- a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/TestRunner.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * ONAP-PDP
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.policy.pdp.test;
-
-import org.junit.runner.JUnitCore;
-import org.junit.runner.Result;
-import org.junit.runner.notification.Failure;
-
-public class TestRunner {
-	private static Result results;
-
-	public static void main(String[] args) {
-		Result result = JUnitCore.runClasses(PDPTest.class);
-		for(Failure failure: result.getFailures()) {
-			System.out.println("Failed Test: " + failure.toString());
-		}
-		results = null;
-		if(result.wasSuccessful()) {
-			System.out.println("Test Results... ");
-			System.out.println("Stats:  \nRun Time: " + (results.getRunTime()+result.getRunTime()) + "\nTotal Tests:" + results.getRunCount()+ result.getRunCount()
-					+ "\nFailures: " + results.getFailureCount()+ result.getFailureCount());
-			System.exit(1);
-		}
-		System.out.println("Tests Failed...");
-		System.out.println("Stats:  \nRun Time: " + result.getRunTime() + "\nTests:" + result.getRunCount()
-				+ "\nFailures: " + result.getFailureCount());
-	}
-}
diff --git a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/conformance/Conformance.java b/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/conformance/Conformance.java
deleted file mode 100644
index d7af8b0..0000000
--- a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/conformance/Conformance.java
+++ /dev/null
@@ -1,634 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * ONAP-PDP
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.policy.pdp.test.conformance;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-
-import com.att.research.xacml.api.Advice;
-import com.att.research.xacml.api.Attribute;
-import com.att.research.xacml.api.AttributeAssignment;
-import com.att.research.xacml.api.AttributeCategory;
-import com.att.research.xacml.api.AttributeValue;
-import com.att.research.xacml.api.IdReference;
-import com.att.research.xacml.api.Obligation;
-import com.att.research.xacml.api.Response;
-import com.att.research.xacml.api.Result;
-
-/**
- * Conformance is an application that runs a <code>ConformanceTestSet</code> and dumps results comparing the actual and
- * expected results.
- * 
- * TO RUN in Eclipse:
- * This is run as a Java Application.
- * You must first create a Run/Debug Configuration: 
- * 		Under the Argument tab, in Program Arguments you must set the -i or --input command line argument.
- *	 	You should also direct the output to a file using -o or --output. (default is Console)
- *		See the init() method in this file for other useful arguments.
- * 		Example for a Windows machine:
- * 			-i testsets/conformance/xacml3.0-ct-v.0.4
- * 			-o \Users\yourLogin\Downloads\conformance.txt
- * 		You must also set the VM arguments:
- * 			-Dxacml.properties=testsets/conformance/xacml.properties .
- * 			-Dlog4j.configuration=.\logging.properties
- * 
- * @version $Revision: 1.2 $
- */
-public class Conformance {
-	private ConformanceScopeResolver scopeResolver;
-	private ConformanceTestEngine testEngine;
-	private ConformanceTestSet testSet			= new ConformanceTestSet();
-	private File outputFile;
-	private PrintWriter outputFileWriter;
-	
-	private List<String> testNamesToRun = new ArrayList<String>();
-	
-	private boolean verbose;
-	private boolean failuresOnly;
-	private boolean strict;
-	private boolean stopOnFirstError;
-	
-	private int testsRun;
-	private int decisionsMatch;
-	private int statusCodesMatch;
-	private int attributesMatch;
-	private int policyIdsMatch;
-	private int policySetIdsMatch;
-	private int associatedAdviceMatch;
-	private int obligationsMatch;
-	private int unknownFunctions;
-	
-	
-
-	
-	protected synchronized ConformanceScopeResolver getScopeResolver() {
-		if (this.scopeResolver == null) {
-			this.scopeResolver	= new ConformanceScopeResolver();
-			
-			/*
-			 * TODO:
-			 * Add the known scopes for the 2.0 conformance test.  This could be made more general by allowing loading
-			 * from a properties file eventually.
-			 */
-			try {
-				URI ID_SCOPE_ROOT	= new URI("urn:root");
-				URI ID_SCOPE_CHILD1	= new URI("urn:root:child1");
-				URI ID_SCOPE_CHILD2	= new URI("urn:root:child2");
-				URI ID_SCOPE_C1D1	= new URI("urn:root:child1:descendant1");
-				URI ID_SCOPE_C1D2	= new URI("urn:root:child1:descendant2");
-				URI ID_SCOPE_C2D1	= new URI("urn:root:child2:descendant1");
-				URI ID_SCOPE_C2D2	= new URI("urn:root:child2:descendant2");
-				
-				this.scopeResolver.add(ID_SCOPE_ROOT, ID_SCOPE_CHILD1);
-				this.scopeResolver.add(ID_SCOPE_CHILD1, ID_SCOPE_C1D1);
-				this.scopeResolver.add(ID_SCOPE_CHILD1, ID_SCOPE_C1D2);
-				this.scopeResolver.add(ID_SCOPE_ROOT, ID_SCOPE_CHILD2);
-				this.scopeResolver.add(ID_SCOPE_CHILD2, ID_SCOPE_C2D1);
-				this.scopeResolver.add(ID_SCOPE_CHILD2, ID_SCOPE_C2D2);
-			} catch (Exception ex) {
-				ex.printStackTrace(System.err);
-			}
-			
-		}
-		return this.scopeResolver;
-	}
-	
-	private void close() throws IOException {
-		if (this.outputFileWriter != null) {
-			this.outputFileWriter.close();
-		}
-	}
-	
-	private boolean init(String[] args) {
-		boolean lenientRequests	= true;
-		boolean lenientPolicies	= false;
-		// default is to not run any non-first-time iterations
-		int iterations			= -1;
-		String testSetDirectoryNames = "";
-		for (int i = 0 ; i < args.length ; ) {
-			
-			if (args[i].equals("-h") || args[i].equals("--help") || args[i].equals("-help")) {
-				printHelp();
-				return false;
-			}
-			
-			
-			// where the XML Request/Response files are located
-			if (args[i].equals("-i") || args[i].equals("--input")) {
-				i++;
-				while (i < args.length && !args[i].startsWith("-")) {
-					testSetDirectoryNames += " " + args[i];
-					try {
-						testSet.addConformanceTestSet(ConformanceTestSet.loadDirectory(new File(args[i])));
-					} catch (Exception ex) {
-						ex.printStackTrace(System.err);
-						return false;
-					}
-					i++;
-				}
-
-			// File path name where output will be put - default is stdout == Console
-			} else if (args[i].equals("-o") || args[i].equals("--output")) {
-				if (i+1 < args.length) {
-					this.outputFile	= new File(args[i+1]);
-					i	+= 2;
-				} else {
-					System.err.println("Missing argument to " + args[i] + " command line option");
-					return false;
-				}
-			// A list of specific test names (e.g.: -t IIA001 IIA007 IIIE301) - default is to run all tests
-			} else if (args[i].equals("-t") || args[i].equals("--tests")) {
-				i++;
-				while (i < args.length && !args[i].startsWith("-")) {
-					testNamesToRun.add(args[i]);
-					i++;
-				}
-				if (testNamesToRun.size() == 0) {
-					System.err.println("Missing test names after -t or --tests argument");
-					return false;
-				}
-			// Include full details in the response, both the expected reqsponse (from file) and the actual response
-			} else if (args[i].equals("-v") || args[i].equals("--verbose")) {
-				this.verbose	= true;
-				i++;
-			// Report only failures (success is silent)
-			} else if (args[i].equals("-f") || args[i].equals("--failures")) {
-				this.failuresOnly	= true;
-				i++;
-			// When set, the XML must not contain extra attibutes/elements.  Default is "lenient" where unexpected entries are ignored
-			} else if (args[i].equals("-s") || args[i].equals("--strict")) {
-				this.strict	= true;
-				i++;
-			// (self explanatory)
-			} else if (args[i].equals("--stop-on-error")) {
-				this.stopOnFirstError	= true;
-				i++;
-			} else if (args[i].equals("--lenient")) {
-				lenientPolicies	= true;
-				lenientRequests	= true;
-				i++;
-			} else if (args[i].equals("--lenient-policies")) {
-				lenientPolicies	= true;
-				i++;
-			} else if (args[i].equals("--lenient-requests")) {
-				lenientRequests	= true;
-				i++;
-			} else if (args[i].equals("--strict-policies")) {
-				lenientPolicies	= false;
-				i++;
-			} else if (args[i].equals("--strict-requests")) {
-				lenientRequests	= false;
-				i++;
-			} else if (args[i].equals("--iterations")) {
-				// this is a count of how many ADDITIONAL times the decide() should be called.
-				// The first time decide() is called it takes a long time to set up,
-				// so to get an accurate number for how fast a single Request is handled we need to ignore the time for the first run
-				// and timings for 1 or more non-first-time calls to decide().
-				if (i+1 < args.length) {
-					try {
-						iterations	= Integer.parseInt(args[i+1]);
-						i	+= 2;
-					} catch (NumberFormatException ex) {
-						System.err.println("Invalid iteration count '" + args[i+1] + "'");
-						return false;
-					}
-				} else {
-					System.err.println("Missing argument to " + args[i] + " command line option");
-					return false;					
-				}
-				if (iterations < 1) {
-					System.err.println("Cannot use --iterations " + iterations + ".  Must use an integer greater than 0");
-					return false;
-				}
-			} else {
-				System.err.println("Unknown command line option " + args[i]);
-				return false;
-			}
-		}
-	
-		this.testEngine	= new ConformanceTestEngine(this.getScopeResolver(), lenientRequests, lenientPolicies, iterations);
-
-		if (testSetDirectoryNames.length() == 0) {
-			System.err.println("No test set directory given (need -i or --iniput command line option)");
-			return false;
-		}
-		if (testSet.getListConformanceTests().size() == 0) {
-			System.err.println("No tests in given directories: " + testSetDirectoryNames);
-		}
-		
-		if (testNamesToRun.size() > 0) {
-			String s = "";
-			for (String name : testNamesToRun) {
-				s += ", " + name;
-			}
-			System.out.println("Tests limited to: " + s.substring(1));
-		}
-		
-		if (this.outputFile == null) {
-			this.outputFileWriter	= new PrintWriter(System.out);
-		} else {
-			try {
-				this.outputFileWriter	= new PrintWriter(new FileOutputStream(this.outputFile));
-			} catch (IOException ex) {
-				System.err.println("Cannot open " + this.outputFile.getAbsolutePath() + " for writing.");
-				return false;
-			}
-		}
-		
-		return true;
-	}
-	
-	private void printHelp() {
-		System.out.println("usage: Conformance --input <tests_directory> OPTIONS");
-		System.out.println("");
-		System.out.println(" -f, --failures		Only include failed tests in the output.  \n"+
-							"			Default is to include all test's results in the output file.");
-		System.out.println("");
-		System.out.println(" -h, --help		Prints help.");
-			
-		System.out.println("");
-		System.out.println(" -i, --input <dir>	Directory containing the XML Request/Response files.  \n"+
-							"			This may be multiple space-separated directory paths.  REQUIRED");
-		
-		System.out.println("");
-		System.out.println(" --iterations		The number of times to run through the set of tests in the input directory.");
-		
-		System.out.println("");
-		System.out.println(" --lenient		Allow both Requests and Policies to have unexpected elements, no data in <Content>, etc. \n"+
-							"			Default is to not allow anything that is not explicitly listed in the XACML spec.");
-		
-		System.out.println("");
-		System.out.println(" --lenient-policies	Allow Policies to have unexpected elements, no data in <Content>, etc.  \n" +
-							"			Default is to not allow anything that is not explicitly listed in the XACML spec.");
-		
-		System.out.println("");
-		System.out.println(" --lenient-requests	Allow Requests to have unexpected elements, no data in <Content>, etc.  \n" +
-							"			Default is to not allow anything that is not explicitly listed in the XACML spec.");
-		
-		System.out.println("");
-		System.out.println(" -o, --output <dir>	Directory where the output results file will be put.");
-		
-		System.out.println("");
-		System.out.println(" -s, --strict		Check both the Decision and all other parts of the Response (Attributes, Obligations and Advice). \n "+
-							"			Default is to check just the Decision.");
-		
-		System.out.println("");
-		System.out.println(" --stop-on-error	Stop running conformance tests the first time one fails.  Default is to continue through all tests.");
-
-		System.out.println("");
-		System.out.println(" --strict-policies	Require Policies to have no unexpected elements, data in <Content>, etc.  \n" +
-							"			This is the default, but can be used to override Policies when option --lenient is used.");
-		
-		System.out.println("");
-		System.out.println(" --strict-requests	Require Requests to have no unexpected elements, data in <Content>, etc.  \n" +
-							"			This is the default, but can be used to override Requests when option --lenient is used.");
-		
-		System.out.println("");
-		System.out.println(" -t, --tests <list of test names>	A space-separated list of specific tests to be run. \n" +
-							"			These are just the names of the tests as in 'IIA001 IIC178'.  \n" +
-							"			Default is to run all tests in the input directory.");
-		
-		System.out.println("");
-		System.out.println(" -v, --verbose 		The entire expected and actual Response objects in the output.  \n"+
-							"			Default is just a summary line.");
-		
-	}
-	
-	private boolean failed(ConformanceTestResult conformanceTestResult) {
-		ResponseMatchResult responseMatchResult	= conformanceTestResult.getResponseMatchResult();
-		if (responseMatchResult == null) {
-			return true;
-		}
-		if (!responseMatchResult.decisionsMatch() || !responseMatchResult.statusCodesMatch()) {
-			return true;
-		} else if (this.strict) {
-			if (!responseMatchResult.associatedAdviceMatches() ||
-				!responseMatchResult.attributesMatch() ||
-				!responseMatchResult.obligationsMatch() ||
-				!responseMatchResult.policyIdentifiersMatch() ||
-				!responseMatchResult.policySetIdentifiersMatch()
-					) {
-				return true;
-			}
-		}
-		return false;
-	}
-	
-	private void dump(AttributeAssignment attributeAssignment) {
-		this.outputFileWriter.println("\t\t\t\tAttributeAssignment:");
-		if (attributeAssignment.getCategory() != null) {
-			this.outputFileWriter.println("\t\t\t\t\tCategory: " + attributeAssignment.getCategory().stringValue());
-		}
-		if (attributeAssignment.getAttributeId() != null) {
-			this.outputFileWriter.println("\t\t\t\t\tAttributeId: " + attributeAssignment.getAttributeId().stringValue());
-		}
-		if (attributeAssignment.getDataTypeId() != null) {
-			this.outputFileWriter.println("\t\t\t\t\tDataType: " + attributeAssignment.getDataTypeId().stringValue());
-		}
-		if (attributeAssignment.getIssuer() != null) {
-			this.outputFileWriter.println("\t\t\t\t\tIssuer: " + attributeAssignment.getIssuer());
-		}
-		if (attributeAssignment.getAttributeValue() != null && attributeAssignment.getAttributeValue().getValue() != null) {
-			this.outputFileWriter.println("\t\t\t\t\tValue: " + attributeAssignment.getAttributeValue().getValue().toString());
-		}
-	}
-	
-	private void dump(Attribute attribute) {
-		this.outputFileWriter.println("\t\t\t\t\tAttribute: " + (attribute.getAttributeId() == null ? "" : attribute.getAttributeId().stringValue()));
-		if (attribute.getIssuer() != null) {
-			this.outputFileWriter.println("\t\t\t\t\t\tIssuer: " + attribute.getIssuer());
-		}
-		Iterator<AttributeValue<?>> iterAttributeValues	= attribute.getValues().iterator();
-		if (iterAttributeValues.hasNext()) {
-			this.outputFileWriter.println("\t\t\t\t\t\tValues: ");
-			while (iterAttributeValues.hasNext()) {
-				this.outputFileWriter.print("\t\t\t\t\t\t\t");
-				AttributeValue<?> attributeValue	= iterAttributeValues.next();
-				if (attributeValue.getDataTypeId() != null) {
-					this.outputFileWriter.print("DataType: " + attributeValue.getDataTypeId().stringValue() + " ");
-				}
-				if (attributeValue.getValue() != null) {
-					this.outputFileWriter.print("Value: " + attributeValue.getValue().toString());
-				}
-				this.outputFileWriter.println();
-			}
-		}
-	}
-	
-	private void dump(AttributeCategory attributeCategory) {
-		this.outputFileWriter.println("\t\t\tAttributeCategory: " + (attributeCategory.getCategory() == null ? "" : attributeCategory.getCategory().stringValue()));
-		Collection<Attribute> listAttributes	= attributeCategory.getAttributes();
-		if (listAttributes.size() > 0) {
-			this.outputFileWriter.println("\t\t\t\tAttributes:");
-			for (Attribute attribute: listAttributes) {
-				this.dump(attribute);
-			}
-		}
-	}
-	
-	private void dump(Result result) {
-		this.outputFileWriter.println("\t\t======== Result ==========");
-		this.outputFileWriter.println("\t\tDecision: " + (result.getDecision() == null ? "null" : result.getDecision().name()));
-		if (result.getStatus() == null) {
-			this.outputFileWriter.println("\t\tStatus: null");
-		} else {
-			this.outputFileWriter.println("\t\tStatus:");
-			if (result.getStatus().getStatusCode() != null) {
-				this.outputFileWriter.println("\t\t\tStatusCode: " + result.getStatus().getStatusCode().toString());
-			}
-			if (result.getStatus().getStatusMessage() != null) {
-				this.outputFileWriter.println("\t\t\tStatusMessage: " + result.getStatus().getStatusMessage());
-			}
-			if (result.getStatus().getStatusDetail() != null) {
-				this.outputFileWriter.println("\t\t\tStatusDetail: " + result.getStatus().getStatusDetail().toString());
-			}
-		}
-		Collection<Advice> listAdvice	= result.getAssociatedAdvice();
-		if (listAdvice.size() > 0) {
-			this.outputFileWriter.println("\t\tAdvice:");
-			for (Advice advice : listAdvice) {
-				if (advice.getId() != null) {
-					this.outputFileWriter.println("\t\t\tId: " + advice.getId().stringValue());
-				}
-				Collection<AttributeAssignment> attributeAssignments	= advice.getAttributeAssignments();
-				if (attributeAssignments.size() > 0) {
-					this.outputFileWriter.println("\t\t\tAttributeAssignments:");
-					for (AttributeAssignment attributeAssignment: attributeAssignments) {
-						this.dump(attributeAssignment);
-					}
-				}				
-			}
-		}
-		Collection<Obligation> listObligations	= result.getObligations();
-		if (listObligations.size() > 0) {
-			for (Obligation obligation: listObligations) {
-				if (obligation.getId() != null) {
-					this.outputFileWriter.println("\t\t\tId: " + obligation.getId().stringValue());
-				}
-				Collection<AttributeAssignment> attributeAssignments	= obligation.getAttributeAssignments();
-				if (attributeAssignments.size() > 0) {
-					this.outputFileWriter.println("\t\t\tAttributeAssignments:");
-					for (AttributeAssignment attributeAssignment : attributeAssignments) {
-						this.dump(attributeAssignment);
-					}
-				}				
-			}
-		}
-		Collection<AttributeCategory> listAttributeCategories	= result.getAttributes();
-		if (listAttributeCategories.size() > 0) {
-			this.outputFileWriter.println("\t\tAttributes:");
-			for (AttributeCategory attributeCategory : listAttributeCategories) {
-				this.dump(attributeCategory);
-			}
-		}
-		Collection<IdReference> listIdReferences;
-		if ((listIdReferences = result.getPolicyIdentifiers()).size() > 0) {
-			this.outputFileWriter.println("\t\tPolicyIds:");
-			for (IdReference idReference : listIdReferences) {
-				this.outputFileWriter.println("\t\t\t" + idReference.toString());				
-			}
-		}
-		if ((listIdReferences = result.getPolicySetIdentifiers()).size() > 0) {
-			this.outputFileWriter.println("\t\tPolicySetIds:");
-			for (IdReference idReference : listIdReferences) {
-				this.outputFileWriter.println("\t\t\t" + idReference.toString());				
-			}
-		}
-	}
-	
-	private void dump(String label, Response response) {
-		this.outputFileWriter.println("\t========== " + label + "==========");
-		if (response == null) {
-			this.outputFileWriter.println("null");
-			return;
-		}
-		
-		for (Result result : response.getResults()) {
-			this.dump(result);
-		}
-	}
-	
-	private void dump(ConformanceTestResult conformanceTestResult) {
-		
-		ResponseMatchResult responseMatchResult	= conformanceTestResult.getResponseMatchResult();
-		if (this.verbose) {
-			this.outputFileWriter.println("========== Test " + conformanceTestResult.getConformanceTest().getTestName() + " ==========");
-			this.dump("Expected Response", conformanceTestResult.getExpectedResponse());
-			this.dump("Actual Response", conformanceTestResult.getActualResponse());
-			if (responseMatchResult != null) {
-				this.outputFileWriter.println("\t========== Matching ==========");
-				this.outputFileWriter.println("\tDecisions Match? " + responseMatchResult.decisionsMatch());
-				this.outputFileWriter.println("\tStatus Codes Match? " + responseMatchResult.statusCodesMatch());
-				this.outputFileWriter.println("\tAttributes Match? " + responseMatchResult.attributesMatch());
-				this.outputFileWriter.println("\tPolicyIds Match? " + responseMatchResult.policyIdentifiersMatch());
-				this.outputFileWriter.println("\tPolicySetIds Match? " + responseMatchResult.policySetIdentifiersMatch());
-				this.outputFileWriter.println("\tAssociated Advice Match? " + responseMatchResult.associatedAdviceMatches());
-				this.outputFileWriter.println("\tObligations Match? " + responseMatchResult.obligationsMatch());
-				this.outputFileWriter.println("========== End ==========");				
-			}
-		} else {
-			String testName	= conformanceTestResult.getConformanceTest().getTestName();
-			if (responseMatchResult != null) {
-				Iterator<ResultMatchResult> iterResultMatches	= responseMatchResult.getResultMatchResults();
-				if (iterResultMatches == null || !iterResultMatches.hasNext()) {
-					this.outputFileWriter.println(testName);
-				} else {
-					while (iterResultMatches.hasNext()) {
-						ResultMatchResult resultMatchResult	= iterResultMatches.next();
-						this.outputFileWriter.printf("%s,%s,%s,%s,%s,%s,%s,%s,%d,%d\n",
-								testName,
-								resultMatchResult.decisionsMatch(),
-								resultMatchResult.statusCodesMatch(),
-								resultMatchResult.attributesMatch(),
-								resultMatchResult.policyIdentifiersMatch(),
-								resultMatchResult.policySetIdentifiersMatch(),
-								resultMatchResult.associatedAdviceMatches(),
-								resultMatchResult.obligationsMatch(),
-								conformanceTestResult.getFirstCallTime(),
-								conformanceTestResult.getAverageTotalLoopTime()
-								);
-					}
-				}
-			}
-		}
-		this.outputFileWriter.flush();
-	}
-	
-	private boolean run(ConformanceTest conformanceTest) throws Exception {
-		this.testsRun++;
-		ConformanceTestResult conformanceTestResult	= this.testEngine.run(conformanceTest);
-		boolean bFailed								= true;
-		if (conformanceTestResult != null) {
-			ResponseMatchResult responseMatchResult	= conformanceTestResult.getResponseMatchResult();
-			if (responseMatchResult != null) {
-				if (responseMatchResult.decisionsMatch()) {
-					this.decisionsMatch++;
-					this.statusCodesMatch	+= (responseMatchResult.statusCodesMatch() ? 1 : 0);
-					this.attributesMatch	+= (responseMatchResult.attributesMatch() ? 1 : 0);
-					this.policyIdsMatch		+= (responseMatchResult.policyIdentifiersMatch() ? 1 : 0);
-					this.policySetIdsMatch	+= (responseMatchResult.policySetIdentifiersMatch() ? 1 : 0);
-					this.associatedAdviceMatch	+= (responseMatchResult.associatedAdviceMatches() ? 1 : 0);
-					this.obligationsMatch		+= (responseMatchResult.obligationsMatch() ? 1 : 0);
-				}
-				this.unknownFunctions		+= (responseMatchResult.unknownFunction() ? 1 : 0);
-				bFailed	= this.failed(conformanceTestResult);
-				if (bFailed || !this.failuresOnly) {
-					this.dump(conformanceTestResult);
-				}
-			} else if (conformanceTestResult.getError() != null) {
-				this.outputFileWriter.println(conformanceTestResult.getError());
-			}
-		}
-		return (!bFailed || !this.stopOnFirstError);
-	}
-	
-	private void run() throws Exception {
-		long tStart	= System.currentTimeMillis();
-		
-		if (!this.verbose) {
-			this.outputFileWriter.println("Test,Decision,Status,Attributes,PolicyIds,PolicySetIds,Advice,Obligations");
-		}
-		Iterator<ConformanceTest> iterConformanceTests	= this.testSet.getConformanceTests();
-		boolean bContinue								= true;
-		while (bContinue && iterConformanceTests.hasNext()) {
-//			bContinue	= this.run(iterConformanceTests.next());
-			ConformanceTest test = iterConformanceTests.next();
-			if (testNamesToRun.size() > 0) {
-				if ( ! testNamesToRun.contains(test.getTestName())) {
-					continue;
-				}
-			}
-			bContinue	= this.run(test);
-		}
-		
-		long tElapsed	= System.currentTimeMillis() - tStart;
-		
-		if (this.verbose) {
-			this.outputFileWriter.println("Tests run = " + this.testsRun);
-			this.outputFileWriter.println("Decisions match = " + this.decisionsMatch);
-			this.outputFileWriter.println("Status Codes match = " + this.statusCodesMatch);
-			this.outputFileWriter.println("Attributes match = " + this.attributesMatch);
-			this.outputFileWriter.println("PolicyIds match = " + this.policyIdsMatch);
-			this.outputFileWriter.println("PolicySetIds match = " + this.policySetIdsMatch);
-			this.outputFileWriter.println("Associated Advice match = " + this.associatedAdviceMatch);
-			this.outputFileWriter.println("Obligations match = " + this.obligationsMatch);
-			this.outputFileWriter.println("Unknown functions = " + this.unknownFunctions);
-		} else {
-			this.outputFileWriter.printf("Total (%d),%d,%d,%d,%d,%d,%d,%d,%d\n",
-					this.testsRun,
-					this.decisionsMatch,
-					this.statusCodesMatch,
-					this.attributesMatch,
-					this.policyIdsMatch,
-					this.policySetIdsMatch,
-					this.associatedAdviceMatch,
-					this.obligationsMatch,
-					this.unknownFunctions);
-		}
-		
-		if (tElapsed > 0) {
-			long tHours		= tElapsed / (60*60*1000);
-			tElapsed		= tElapsed - tHours * 60 * 60 *1000;
-			long tMinutes	= tElapsed / (60*1000);
-			tElapsed		= tElapsed - tMinutes * 60 * 1000;
-			long tSeconds	= tElapsed / 1000;
-			tElapsed		= tElapsed - tSeconds * 1000;
-			
-			this.outputFileWriter.printf("Elapsed time = %02d:%02d:%02d.%03d\n", tHours, tMinutes, tSeconds, tElapsed);
-			this.outputFileWriter.printf("First decide time in nano-seconds %d\n", this.testEngine.getFirstDecideTime());
-			this.outputFileWriter.printf("Total Multiple decide time in nano-seconds %d\n", this.testEngine.getDecideTimeMultiple());
-			
-			this.outputFileWriter.printf("\nAverage First decide time in nano-seconds %d\n", this.testEngine.getAvgFirstDecideTime());
-			this.outputFileWriter.printf("Average decide time after first call in nano-seconds %d\n", this.testEngine.getAvgDecideTimeMultiple());
-		}
-	}
-	
-	public Conformance() {
-	}
-
-	public static void main(String[] args) {
-		Conformance conformance	= new Conformance();
-		try {
-			if (conformance.init(args)) {
-				conformance.run();
-			}
-			
-		} catch (Exception ex) {
-			ex.printStackTrace(System.err);
-			System.exit(1);
-		} finally {
-			try {
-				conformance.close();
-			} catch (IOException ex) {
-				ex.printStackTrace(System.err);
-			}
-		}
-		System.exit(0);
-	}
-
-}
diff --git a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/conformance/ConformancePIPEngine.java b/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/conformance/ConformancePIPEngine.java
deleted file mode 100644
index e810241..0000000
--- a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/conformance/ConformancePIPEngine.java
+++ /dev/null
@@ -1,242 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * ONAP-PDP
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.policy.pdp.test.conformance;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.text.ParseException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-
-import org.onap.policy.common.logging.flexlogger.FlexLogger;
-import org.onap.policy.common.logging.flexlogger.Logger;
-
-import com.att.research.xacml.api.Attribute;
-import com.att.research.xacml.api.AttributeValue;
-import com.att.research.xacml.api.DataType;
-import com.att.research.xacml.api.DataTypeException;
-import com.att.research.xacml.api.DataTypeFactory;
-import com.att.research.xacml.api.Identifier;
-import com.att.research.xacml.api.pip.PIPException;
-import com.att.research.xacml.api.pip.PIPFinder;
-import com.att.research.xacml.api.pip.PIPRequest;
-import com.att.research.xacml.api.pip.PIPResponse;
-import com.att.research.xacml.std.IdentifierImpl;
-import com.att.research.xacml.std.StdMutableAttribute;
-import com.att.research.xacml.std.pip.StdPIPResponse;
-import com.att.research.xacml.std.pip.engines.ConfigurableEngine;
-import com.att.research.xacml.util.FactoryException; 
-
-/**
- * ConformancePIPEngine implements the {@link com.att.research.xacml.api.pip.PIPFinder} interface to find attributes
- * loaded from a text file containing the following fields:
- * 	category-id,attribute-id,datatype-id,issuer,value
- * 
- * @version $Revision: 1.1 $
- */
-public class ConformancePIPEngine implements ConfigurableEngine {
-	public static final String PROP_DESCRIPTION	= ".description";
-	public static final String PROP_FILE		= ".file";
-	
-	private static final Logger logger	= FlexLogger.getLogger(ConformancePIPEngine.class);
-	
-	private String name;
-	private String description;
-	private Map<String,PIPResponse> cache	= new HashMap<>();
-	private List<Attribute> listAttributes	= new ArrayList<>();
-	private DataTypeFactory dataTypeFactory;
-	
-	public ConformancePIPEngine() {
-		
-	}
-	
-	protected DataTypeFactory getDataTypeFactory() throws FactoryException {
-		if (this.dataTypeFactory == null) {
-			this.dataTypeFactory	= DataTypeFactory.newInstance();
-		}
-		return this.dataTypeFactory;
-	}
-	
-	protected static String generateKey(PIPRequest pipRequest) {
-		StringBuilder stringBuilder	= new StringBuilder(pipRequest.getCategory().toString());
-		stringBuilder.append('+');
-		stringBuilder.append(pipRequest.getAttributeId().toString());
-		stringBuilder.append('+');
-		stringBuilder.append(pipRequest.getDataTypeId().toString());
-		String issuer	= pipRequest.getIssuer();
-		if (issuer != null) {
-			stringBuilder.append('+');
-			stringBuilder.append(issuer);
-		}
-		return stringBuilder.toString();
-	}
-	
-	protected void store(String[] fields) throws FactoryException {
-		DataTypeFactory thisDataTypeFactory	= this.getDataTypeFactory();
-		Identifier identifierCategory		= new IdentifierImpl(fields[0]);
-		Identifier identifierAttribute		= new IdentifierImpl(fields[1]);
-		Identifier identifierDataType		= new IdentifierImpl(fields[2]);
-		String issuer						= (fields.length == 5 ? fields[3] : null);
-		String value						= fields[fields.length - 1];
-		
-		DataType<?> dataType				= thisDataTypeFactory.getDataType(identifierDataType);
-		if (dataType == null) {
-			logger.error("Unknown data type " + identifierDataType.stringValue());
-			return;
-		}
-		
-		AttributeValue<?> attributeValue	= null;
-		try {
-			attributeValue	= dataType.createAttributeValue(value);
-		} catch (DataTypeException ex) {
-			throw new FactoryException("DataTypeException creating AttributeValue", ex);
-		}
-		Attribute attribute					= new StdMutableAttribute(identifierCategory, identifierAttribute, attributeValue, issuer, false);
-		this.listAttributes.add(attribute);
-	}
-	
-	public void loadAttributes(File fileAttributes) throws IOException, ParseException, FactoryException {
-		if (fileAttributes != null) {
-			if (!fileAttributes.exists()) {
-				throw new FileNotFoundException("Attributes file " + fileAttributes.getAbsolutePath() + " not found.");
-			} else if (!fileAttributes.canRead()) {
-				throw new IOException("Attributes file " + fileAttributes.getAbsolutePath() + " is not readable.");
-			}
-			
-			BufferedReader bufferedReader	= null;
-			try {
-				bufferedReader	= new BufferedReader(new InputStreamReader(new FileInputStream(fileAttributes)));
-				String line;
-				while ((line = bufferedReader.readLine()) != null) {
-					if (line.length() > 0) {
-						String[] fields	= line.split("[|]",-1);
-						if (fields.length < 4) {
-							logger.warn("Not enough fields in record \"" + line + "\"");
-							continue;
-						}
-						this.store(fields);
-						
-					}
-				}
-			} finally {
-				if (bufferedReader != null) {
-					bufferedReader.close();
-				}
-			}
-		}
-	}
-	
-	protected Attribute findAttribute(PIPRequest pipRequest) {
-		Attribute attributeResult			= null;
-		Iterator<Attribute> iterAttributes	= this.listAttributes.iterator();
-		while ((attributeResult == null) && iterAttributes.hasNext()) {
-			Attribute attributeTest	= iterAttributes.next();
-			if (pipRequest.getCategory().equals(attributeTest.getCategory()) &&
-				pipRequest.getAttributeId().equals(attributeTest.getAttributeId()) &&
-				(pipRequest.getIssuer() == null || pipRequest.getIssuer().equals(attributeTest.getIssuer()))) {
-				attributeResult	= attributeTest;
-			}
-		}
-		return attributeResult;
-	}
-
-	@Override
-	public PIPResponse getAttributes(PIPRequest pipRequest, PIPFinder pipFinder) throws PIPException {
-		String pipRequestKey	= generateKey(pipRequest);
-		PIPResponse pipResponse	= this.cache.get(pipRequestKey);
-		if (pipResponse != null) {
-			return pipResponse;
-		}
-		Attribute attributeMatch	= this.findAttribute(pipRequest);
-		if (attributeMatch == null) {
-			return StdPIPResponse.PIP_RESPONSE_EMPTY;
-		}
-		/*
-		 * Iterate through the values and only return the ones that match the requested data type
-		 */
-		List<AttributeValue<?>> matchingValues	= new ArrayList<>();
-		Iterator<AttributeValue<?>> iterAttributeValues	= attributeMatch.getValues().iterator();
-		while (iterAttributeValues.hasNext()) {
-			AttributeValue<?> attributeValue	= iterAttributeValues.next();
-			if (pipRequest.getDataTypeId().equals(attributeValue.getDataTypeId())) {
-				matchingValues.add(attributeValue);
-			}
-		}
-		if (matchingValues.size() > 0) {
-			Attribute attributeResponse	= new StdMutableAttribute(attributeMatch.getCategory(), attributeMatch.getAttributeId(), matchingValues, attributeMatch.getIssuer(), false);
-			pipResponse					= new StdPIPResponse(attributeResponse);
-			this.cache.put(pipRequestKey, pipResponse);
-		}
-		return pipResponse;
-	}
-
-	@Override
-	public String getName() {
-		return this.name;
-	}
-
-	@Override
-	public String getDescription() {
-		return this.description;
-	}
-
-	@Override
-	public void configure(String id, Properties properties) throws PIPException {
-		this.name	= id;
-		this.description	= properties.getProperty(id + PROP_DESCRIPTION);
-		if (this.description == null) {
-			this.description	= "PIPEngine for the Conformance tests that loads attributes from a CSV file";
-		}
-		String pipFile		= properties.getProperty(id + PROP_FILE);
-		if (pipFile != null) {
-			try {
-				this.loadAttributes(new File(pipFile));
-			} catch (Exception ex) {
-				logger.error("Exception loading PIP file " + pipFile, ex);
-				throw new PIPException("Exception loading PIP file " + pipFile, ex);
-			}
-		}
-	}
-
-	@Override
-	public Collection<PIPRequest> attributesRequired() {
-		return Collections.emptyList();
-	}
-
-	@Override
-	public Collection<PIPRequest> attributesProvided() {
-		//
-		// We could return everything in our list
-		//
-		return Collections.emptyList();
-	}
-
-}
diff --git a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/conformance/ConformanceRepository.java b/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/conformance/ConformanceRepository.java
deleted file mode 100644
index 995537e..0000000
--- a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/conformance/ConformanceRepository.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * ONAP-PDP
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.policy.pdp.test.conformance;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Properties;
-
-import com.att.research.xacml.util.StringUtils;
-import com.att.research.xacml.util.XACMLProperties;
-import com.att.research.xacmlatt.pdp.std.StdPolicyFinderFactory;
-
-/**
- * ConformanceRepository represents one or more policies for a single policy test, which will include one or more root policies, and
- * zero or more referenced policies.
- * 
- * @version $Revision$
- */
-public class ConformanceRepository {
-	private List<File> rootPolicies			= new ArrayList<>();
-	private List<File> referencedPolicies	= new ArrayList<>();
-	
-	private void setXACMLProperty(String propertyName, List<File> listFiles) {
-		Iterator<File> iterFiles			= listFiles.iterator();
-		StringBuilder stringBuilderIdList	= new StringBuilder();
-		while (iterFiles.hasNext()) {
-			File file	= iterFiles.next();
-			if (stringBuilderIdList.length() > 0) {
-				stringBuilderIdList.append(',');
-			}
-			stringBuilderIdList.append(file.getName());
-			
-			XACMLProperties.setProperty(file.getName() + StdPolicyFinderFactory.PROP_FILE, file.getAbsolutePath());
-		}
-		XACMLProperties.setProperty(propertyName, stringBuilderIdList.toString());
-	}
-	
-	public ConformanceRepository() {
-	}
-	
-	public void setXACMLProperties() {
-		if (this.rootPolicies.size() > 0) {
-			this.setXACMLProperty(XACMLProperties.PROP_ROOTPOLICIES, this.rootPolicies);
-		}
-		if (this.referencedPolicies.size() > 0) {
-			this.setXACMLProperty(XACMLProperties.PROP_REFERENCEDPOLICIES, this.referencedPolicies);
-		}
-	}
-	
-	private void loadProperty(File fileDir, Properties properties, String propertyName, List<File> listFiles) {
-		String fileNameList	= properties.getProperty(propertyName);
-		if (fileNameList != null) {
-			String[] fileNameArray	= fileNameList.split("[,]",0);
-			if (fileNameArray != null && fileNameArray.length > 0) {
-				for (String fileName : fileNameArray) {
-					File file	= new File(fileDir, fileName);
-					if (file.exists() && file.canRead()) {
-						listFiles.add(file);
-					}
-				}
-			}
-		}
-	}
-	
-	public void load(File fileRepository) throws IOException {
-		Properties propertiesRepository	= new Properties();
-		try (InputStream is = new FileInputStream(fileRepository)) {
-			propertiesRepository.load(is);
-		}
-		this.loadProperty(fileRepository.getParentFile(), propertiesRepository, XACMLProperties.PROP_ROOTPOLICIES, this.rootPolicies);
-		this.loadProperty(fileRepository.getParentFile(), propertiesRepository, XACMLProperties.PROP_REFERENCEDPOLICIES, this.referencedPolicies);
-	}
-	
-	public void addRootPolicy(File filePolicy) {
-		this.rootPolicies.add(filePolicy);
-	}
-	
-	public boolean hasRootPolicy() {
-		return (this.rootPolicies.size() > 0);
-	}
-	
-	@Override
-	public String toString() {
-		StringBuilder stringBuilder	= new StringBuilder("{");
-		boolean needComma			= false;
-		
-		if (this.rootPolicies != null && this.rootPolicies.size() > 0) {
-			stringBuilder.append("rootPolicies=");
-			stringBuilder.append(StringUtils.toString(this.rootPolicies.iterator()));
-			needComma	= true;
-		}
-		if (this.referencedPolicies != null && this.referencedPolicies.size() > 0) {
-			if (needComma) {
-				stringBuilder.append(',');
-			}
-			stringBuilder.append("referencedPolicies=");
-			stringBuilder.append(StringUtils.toString(this.referencedPolicies.iterator()));
-			needComma	= true;
-		}
-		stringBuilder.append('}');
-		return stringBuilder.toString();
-	}
-	
-}
diff --git a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/conformance/ConformanceScopeResolver.java b/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/conformance/ConformanceScopeResolver.java
deleted file mode 100644
index 6541454..0000000
--- a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/conformance/ConformanceScopeResolver.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * ONAP-PDP
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.policy.pdp.test.conformance;
-
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.onap.policy.common.logging.flexlogger.FlexLogger;
-import org.onap.policy.common.logging.flexlogger.Logger;
-
-import com.att.research.xacml.api.Attribute;
-import com.att.research.xacml.api.AttributeValue;
-import com.att.research.xacml.api.pdp.ScopeQualifier;
-import com.att.research.xacml.api.pdp.ScopeResolver;
-import com.att.research.xacml.api.pdp.ScopeResolverException;
-import com.att.research.xacml.api.pdp.ScopeResolverResult;
-import com.att.research.xacml.std.StdMutableAttribute;
-import com.att.research.xacml.std.StdScopeResolverResult;
-import com.att.research.xacml.std.StdStatus;
-import com.att.research.xacml.std.StdStatusCode;
-import com.att.research.xacml.std.datatypes.DataTypes; 
-
-/**
- * ConformanceScopeResolver implements {@link com.att.research.xacml.pdp.ScopeResolver} for the conformance tests
- * using a fixed set of hierarchical resources defined in a map.
- * 
- * @version $Revision$
- */
-public class ConformanceScopeResolver implements ScopeResolver {
-	private Logger logger									= FlexLogger.getLogger(ConformanceScopeResolver.class);
-	private Map<URI, List<URI>> mapIdentifierToChildren	= new HashMap<>();
-	
-	public ConformanceScopeResolver() {
-	}
-	
-	public void add(URI identifierRoot, URI identifierChild) {
-		List<URI> listChildrenRoot	= this.mapIdentifierToChildren.get(identifierRoot);
-		if (listChildrenRoot == null) {
-			listChildrenRoot	= new ArrayList<>();
-			this.mapIdentifierToChildren.put(identifierRoot, listChildrenRoot);
-		}
-		listChildrenRoot.add(identifierChild);
-	}
-	
-	private void addChildren(Attribute attributeResourceId, URI urnResourceIdValue, boolean bDescendants, List<Attribute> listAttributes) {
-		List<URI> listChildren	= this.mapIdentifierToChildren.get(urnResourceIdValue);
-		if (listChildren != null) {
-			for (URI uriChild : listChildren) {
-				AttributeValue<URI> attributeValueURI	= null;
-				try {
-					attributeValueURI	= DataTypes.DT_ANYURI.createAttributeValue(uriChild);
-					if (attributeValueURI != null) {
-						listAttributes.add(new StdMutableAttribute(attributeResourceId.getCategory(), attributeResourceId.getAttributeId(), attributeValueURI, attributeResourceId.getIssuer(), attributeResourceId.getIncludeInResults()));
-					}
-				} catch (Exception ex) {
-					this.logger.error("Exception converting URI to an AttributeValue");
-				}
-				if (bDescendants) {
-					this.addChildren(attributeResourceId, uriChild, bDescendants, listAttributes);
-				}
-			}
-		}
-	}
-	
-	private void addChildren(Attribute attributeResourceId, boolean bDescendants, List<Attribute> listAttributes) {
-		/*
-		 * Iterate over the values that are URNs
-		 */
-		Iterator<AttributeValue<URI>> iterAttributeValueURNs	= attributeResourceId.findValues(DataTypes.DT_ANYURI);
-		if (iterAttributeValueURNs != null) {
-			while (iterAttributeValueURNs.hasNext()) {
-				this.addChildren(attributeResourceId, iterAttributeValueURNs.next().getValue(), bDescendants, listAttributes);
-			}
-		}
-	}
-	
-	@Override
-	public ScopeResolverResult resolveScope(Attribute attributeResourceId, ScopeQualifier scopeQualifier) throws ScopeResolverException {
-		List<Attribute> listAttributes	= new ArrayList<>();
-		switch(scopeQualifier) {
-		case CHILDREN:
-			listAttributes.add(attributeResourceId);
-			this.addChildren(attributeResourceId, false, listAttributes);
-			break;
-		case DESCENDANTS:
-			listAttributes.add(attributeResourceId);
-			this.addChildren(attributeResourceId, true, listAttributes);
-			break;
-		case IMMEDIATE:
-			listAttributes.add(attributeResourceId);
-			break;
-		default:
-			this.logger.error("Unknown ScopeQualifier: " + scopeQualifier.name());
-			return new StdScopeResolverResult(new StdStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Unknown ScopeQualifier " + scopeQualifier.name()));
-		}
-		return new StdScopeResolverResult(listAttributes);
-	}
-
-}
diff --git a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/conformance/ConformanceTest.java b/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/conformance/ConformanceTest.java
deleted file mode 100644
index a37d1c1..0000000
--- a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/conformance/ConformanceTest.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * ONAP-PDP
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.policy.pdp.test.conformance;
-
-import java.io.File;
-
-/**
- * ConformanceTest represents a collection of XACML files with a root Policy document, optional referenced Policy documents, a Request, and a Response.
- * 
- * @version $Revision: 1.2 $
- */
-public class ConformanceTest {
-	private String testName;
-	private File request;
-	private File response;
-	private ConformanceRepository repository;
-	
-	public ConformanceTest(String name, ConformanceRepository conformanceRepository, File fileRequest, File fileResponse) {
-		this.testName	= name;
-		this.request	= fileRequest;
-		this.response	= fileResponse;
-		this.repository	= conformanceRepository;
-	}
-	
-	public ConformanceTest(String name) {
-		this.testName	= name;
-	}
-	
-	public String getTestName() {
-		return this.testName;
-	}
-	public void setTestName(String s) {
-		this.testName	= s;
-	}
-	public ConformanceRepository getRepository() {
-		if (this.repository == null) {
-			this.repository	= new ConformanceRepository();
-		}
-		return this.repository;
-	}
-	public File getRequest() {
-		return this.request;
-	}
-	public void setRequest(File f) {
-		this.request	= f;
-	}
-	public File getResponse() {
-		return this.response;
-	}
-	public void setResponse(File f) {
-		this.response	= f;
-	}
-	
-	public boolean isComplete() {
-		return this.getTestName() != null && this.getRepository() != null && this.getRepository().hasRootPolicy() && this.getRequest() != null && this.getResponse() != null;
-	}
-	
-	@Override
-	public String toString() {
-		StringBuilder stringBuilder	= new StringBuilder();
-		boolean needColon			= false;
-		if (this.getTestName() != null) {
-			stringBuilder.append(this.getTestName());
-			needColon	= true;
-		}
-		if (this.getRepository() != null) {
-			
-		}
-		if (this.getRequest() != null) {
-			if (needColon) {
-				stringBuilder.append(':');
-			}
-			stringBuilder.append(this.getRequest().getName());
-			needColon	= true;
-		}
-		if (this.getResponse() != null) {
-			if (needColon) {
-				stringBuilder.append(':');
-			}
-			stringBuilder.append(this.getResponse().getName());
-			needColon	= true;
-		}
-		return stringBuilder.toString();
-	}
-
-}
diff --git a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/conformance/ConformanceTestEngine.java b/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/conformance/ConformanceTestEngine.java
deleted file mode 100644
index 91e96cf..0000000
--- a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/conformance/ConformanceTestEngine.java
+++ /dev/null
@@ -1,219 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * ONAP-PDP
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.policy.pdp.test.conformance;
-
-import org.onap.policy.common.logging.flexlogger.FlexLogger;
-import org.onap.policy.common.logging.flexlogger.Logger;
-
-import com.att.research.xacml.api.Request;
-import com.att.research.xacml.api.Response;
-import com.att.research.xacml.api.pdp.PDPEngine;
-import com.att.research.xacml.api.pdp.PDPEngineFactory;
-import com.att.research.xacml.api.pdp.ScopeResolver;
-import com.att.research.xacml.std.dom.DOMProperties;
-import com.att.research.xacml.std.dom.DOMRequest;
-import com.att.research.xacml.std.dom.DOMResponse;
-import com.att.research.xacml.util.FactoryException; 
-
-/**
- * ConformanceTestEngine handles the creation of the PDPEngine for a ConformanceTest instance.
- * 
- * @version $Revision: 1.2 $
- */
-public class ConformanceTestEngine {
-	private Logger logger	= FlexLogger.getLogger(ConformanceTestEngine.class);
-	
-	private PDPEngineFactory pdpEngineFactory;
-	private ScopeResolver scopeResolver;
-	private boolean lenientRequests;
-	private boolean lenientPolicies;
-	private int iterations			= 1;
-	
-	// total of all first calls to decide()
-	private long firstDecideTime;
-	private int numberOfFirstDecides = 0;
-	
-	// total of all non-first-calls to decide()
-	private long decideTimeMultiple;
-	
-	// total of average time each test case uses for a Request
-	// (sum of : for each test case, average of all non-first-call calls to decide() )
-	private long avgDecideTimeMultiple = 0;
-	
-	protected PDPEngineFactory getPDPEngineFactory() throws FactoryException {
-		if (this.pdpEngineFactory == null) {
-			this.pdpEngineFactory	= PDPEngineFactory.newInstance();
-			this.pdpEngineFactory.setScopeResolver(this.scopeResolver);
-		}
-		return this.pdpEngineFactory;
-	}
-	
-	public ConformanceTestEngine(ScopeResolver scopeResolverIn, boolean lenientRequestsIn, boolean lenientPoliciesIn, int iterationsIn) {
-		this.scopeResolver		= scopeResolverIn;
-		this.lenientRequests	= lenientRequestsIn;
-		this.lenientPolicies	= lenientPoliciesIn;
-		this.iterations			= iterationsIn;
-	}
-	
-	public ConformanceTestResult run(ConformanceTest conformanceTest) {
-		if (conformanceTest.getRequest() == null || conformanceTest.getResponse() == null || conformanceTest.getRepository() == null) {
-			logger.error("Incomplete Conformance Test: " + conformanceTest.getTestName());
-		}
-		PDPEngineFactory thisPDPEngineFactory	= null;
-		try {
-			thisPDPEngineFactory	= this.getPDPEngineFactory();
-		} catch (FactoryException ex) {
-			return new ConformanceTestResult(conformanceTest, ex);
-		}
-		
-		ConformanceTestResult conformanceTestResult	= new ConformanceTestResult(conformanceTest, iterations);
-		
-		/*
-		 * Load the request
-		 */
-		Request request			= null;
-		boolean isLenient		= DOMProperties.isLenient();
-		try {
-			DOMProperties.setLenient(this.lenientRequests);
-			try {
-				request		= DOMRequest.load(conformanceTest.getRequest());
-				conformanceTestResult.setRequest(request);
-			} catch (Exception ex) {
-				logger.error("Exception loading Request file " + conformanceTest.getRequest().getAbsolutePath(), ex);
-				conformanceTestResult.setError(ex);
-				return conformanceTestResult;
-				
-			}
-			
-			/*
-			 * Load the expected response
-			 */
-			Response response		= null;
-			try {
-				response	= DOMResponse.load(conformanceTest.getResponse());
-				conformanceTestResult.setExpectedResponse(response);
-			} catch (Exception ex) {
-				logger.error("Exception loading Response file " + conformanceTest.getResponse().getAbsolutePath(), ex);
-				conformanceTestResult.setError(ex);
-				return conformanceTestResult;
-			}
-			
-			/*
-			 * Set up the configuration for the policy finder
-			 */
-			conformanceTest.getRepository().setXACMLProperties();
-			DOMProperties.setLenient(this.lenientPolicies);
-			
-			/*
-			 * Create the engine
-			 */
-			PDPEngine pdpEngine		= null;
-			try {
-				// pdpEngine	= thisPDPEngineFactory.newEngine(conformanceTest.getRootPolicy(), conformanceTest.getReferencedPolicies(), pipFinderEngine);
-				pdpEngine		= thisPDPEngineFactory.newEngine();
-			} catch (Exception ex) {
-				logger.error("Exception getting PDP engine instance", ex);
-				conformanceTestResult.setError(ex);
-				return conformanceTestResult;
-			}
-			if (pdpEngine == null) {
-				logger.error("Null PDP engine");
-				conformanceTestResult.setError(new NullPointerException("Null engine"));
-				return conformanceTestResult;
-			}
-			
-			/*
-			 * Run the request
-			 */
-			long startTime, endTime;
-			long curDecideTime	= this.firstDecideTime;
-			try {
-				startTime	= System.nanoTime();
-				response	= pdpEngine.decide(request);
-				endTime = System.nanoTime();
-//System.out.println(endTime  - startTime);
-				// add to total
-				this.firstDecideTime	+= endTime - startTime;
-				this.numberOfFirstDecides++;
-				// remember just this test
-				conformanceTestResult.setFirstCallTime(endTime - startTime);
-				conformanceTestResult.setActualResponse(response);
-			} catch (Exception ex) {
-				logger.error("Exception in decide", ex);
-				conformanceTestResult.setError(ex);
-				return conformanceTestResult;
-			}
-			if (response == null) {
-				logger.error("Null Response");
-				conformanceTestResult.setError(new NullPointerException("Null Response"));
-				return conformanceTestResult;			
-			}
-			
-			long localLoopTime = 0;
-			try {
-				// if user requested non-first-call calls to decide() to get performance info, run them now.
-				// We can ignore the result since we are only interested in how long they take to process the Request.
-				for (int i = 0 ; i < this.iterations ; i++) {
-					startTime	= System.nanoTime();
-					pdpEngine.decide(request);
-					endTime = System.nanoTime();
-//System.out.println(endTime - startTime);					
-					// add to the global total for all tests
-					this.decideTimeMultiple	+= (endTime - startTime);
-					// remember just this one test's info
-					localLoopTime += (endTime - startTime);
-				}
-			} catch (Exception ex) {
-				logger.error("Exception in iterated decide", ex);
-				return conformanceTestResult;
-			}
-
-			// add to total average for non-first-call times for all test cases
-			avgDecideTimeMultiple += (localLoopTime / iterations);
-//System.out.println("localLoop="+localLoopTime + "   it="+iterations + "   avg=" + (localLoopTime / iterations) );
-			// remember average time for just this test
-			conformanceTestResult.setAverageTotalLoopTime(localLoopTime/iterations);
-			
-			long elapsedDecideTime	= this.firstDecideTime - curDecideTime;
-			logger.info("Decide Time: " + elapsedDecideTime + "ns");
-			
-			return conformanceTestResult;
-		} finally {
-			DOMProperties.setLenient(isLenient);
-		}
-	}
-
-	public long getFirstDecideTime() {
-		return this.firstDecideTime;
-	}
-	
-	public long getDecideTimeMultiple() {
-		return this.decideTimeMultiple;
-	}
-	
-	
-	public long getAvgFirstDecideTime() {
-		return this.firstDecideTime / numberOfFirstDecides;
-	}
-	public long getAvgDecideTimeMultiple() {
-		return this.avgDecideTimeMultiple / numberOfFirstDecides;
-	}
-}
diff --git a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/conformance/ConformanceTestResult.java b/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/conformance/ConformanceTestResult.java
deleted file mode 100644
index 65cfd55..0000000
--- a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/conformance/ConformanceTestResult.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * ONAP-PDP
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.policy.pdp.test.conformance;
-
-import com.att.research.xacml.api.Request;
-import com.att.research.xacml.api.Response;
-
-/**
- * ConformanceTestResult holds all of the objects for a single conformance test run.
- * 
- * @version $Revision: 1.1 $
- */
-public class ConformanceTestResult {
-	private ConformanceTest		conformanceTest;
-	private Request				request;
-	private Response			expectedResponse;
-	private Response			actualResponse;
-	private ResponseMatchResult	responseMatchResult;
-	private Exception			error;
-	
-	// performance timings
-	private long 			firstCallTime;
-	private long 			averageTotalLoopTime;
-	
-	// how many non-first-call times the decide() was called
-	private int iterations;
-	
-	public ConformanceTestResult(ConformanceTest conformanceTestIn, int iterations) {
-		this.conformanceTest	= conformanceTestIn;
-		this.iterations = iterations;
-	}
-	
-	public ConformanceTestResult(ConformanceTest conformanceTestIn, Exception errorIn) {
-		this.conformanceTest	= conformanceTestIn;
-		this.error				= errorIn;
-	}
-	
-	public int getIterations() {
-		return this.iterations;
-	}
-
-	public ConformanceTest getConformanceTest() {
-		return this.conformanceTest;
-	}
-	public void setConformanceTest(ConformanceTest conformanceTestIn) {
-		this.conformanceTest	= conformanceTestIn;
-	}
-	
-	public Request getRequest() {
-		return this.request;
-	}
-	public void setRequest(Request requestIn) {
-		this.request	= requestIn;
-	}
-	
-	public Response getExpectedResponse() {
-		return this.expectedResponse;
-	}
-	public void setExpectedResponse(Response response) {
-		this.expectedResponse		= response;
-		this.responseMatchResult	= null;
-	}
-	
-	public Response getActualResponse() {
-		return this.actualResponse;
-	}
-	public void setActualResponse(Response response) {
-		this.actualResponse		= response;
-		this.responseMatchResult	= null;
-	}
-	
-	public ResponseMatchResult getResponseMatchResult() {
-		if (this.responseMatchResult == null && (this.actualResponse != null && this.expectedResponse != null)) {
-			this.computeResponseMatchResult();
-		}
-		return this.responseMatchResult;
-	}
-	public void computeResponseMatchResult() {
-		if (this.expectedResponse != null && this.actualResponse != null) {
-			this.responseMatchResult	= ResponseMatchResult.newInstance(this.expectedResponse, this.actualResponse);
-		}
-	}
-	public Exception getError() {
-		return this.error;
-	}
-	public void setError(Exception ex) {
-		this.error	= ex;
-	}
-	
-	public long getFirstCallTime() {
-		return firstCallTime;
-	}
-	public void setFirstCallTime(long t) {
-		firstCallTime = t;
-	}
-	public long getAverageTotalLoopTime(){
-		return averageTotalLoopTime;
-	}
-	public void setAverageTotalLoopTime(long t) {
-		averageTotalLoopTime = t;
-	}
-	
-
-}
diff --git a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/conformance/ConformanceTestSet.java b/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/conformance/ConformanceTestSet.java
deleted file mode 100644
index 6fc6e8d..0000000
--- a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/conformance/ConformanceTestSet.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * ONAP-PDP
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.policy.pdp.test.conformance;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.FileVisitResult;
-import java.nio.file.FileVisitor;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.attribute.BasicFileAttributes;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.onap.policy.common.logging.flexlogger.FlexLogger;
-import org.onap.policy.common.logging.flexlogger.Logger; 
-
-/**
- * ConformanceTestSet represents a collection of <code>ConformanceTest</code>s ordered by the test name.  It has methods for
- * scanning a directory to generate an ordered set.
- * 
- * @version $Revision: 1.1 $
- */
-public class ConformanceTestSet {
-	private static final Logger logger						= FlexLogger.getLogger(ConformanceTestSet.class);
-	private List<ConformanceTest> listConformanceTests	= new ArrayList<>();
-	
-	protected List<ConformanceTest> getListConformanceTests() {
-		return this.listConformanceTests;
-	}
-	
-	protected ConformanceTestSet() {
-		
-	}
-	
-	private static String getTestName(String fileName, int itemPos) {
-		return (itemPos == 0 ? "NULL" : fileName.substring(0, itemPos));
-	}
-	
-	private static String getTestName(File file) {
-		String fileName	= file.getName();
-		int itemPos		= fileName.indexOf("Policy");
-		if (itemPos >= 0) {
-			return getTestName(fileName, itemPos);
-		} else if ((itemPos = fileName.indexOf("Request")) >= 0) {
-			return getTestName(fileName, itemPos);
-		} else if ((itemPos = fileName.indexOf("Response")) >= 0) {
-			return getTestName(fileName, itemPos);
-		} else if ((itemPos = fileName.indexOf("Repository")) >= 0) {
-			return getTestName(fileName, itemPos);
-		} else {
-			return null;
-		}
-	}
-	
-	public static ConformanceTestSet loadDirectory(File fileDir) throws IOException {
-		final Map<String,ConformanceTest> mapConformanceTests	= new HashMap<String,ConformanceTest>();
-		
-		Files.walkFileTree(fileDir.toPath(), new FileVisitor<Path>() {
-			@Override
-			public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
-				logger.info("Scanning directory " + dir.getFileName());
-				return FileVisitResult.CONTINUE;
-			}
-
-			@Override
-			public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
-				File fileVisited	= file.toFile();
-				String fileName		= fileVisited.getName();
-				if (fileName.endsWith(".xml") || fileName.endsWith(".properties")) {
-					String testName	= getTestName(fileVisited);
-					if (testName != null) {
-						ConformanceTest conformanceTest	= mapConformanceTests.get(testName);
-						if (conformanceTest == null) {
-							logger.info("Added test " + testName);
-							conformanceTest	= new ConformanceTest(testName);
-							mapConformanceTests.put(testName, conformanceTest);
-						}
-						if (fileName.endsWith("Policy.xml")) {
-							conformanceTest.getRepository().addRootPolicy(fileVisited);
-						} else if (fileName.endsWith("Repository.properties")) {
-							conformanceTest.getRepository().load(fileVisited);
-						} else if (fileName.endsWith("Request.xml")) {
-							conformanceTest.setRequest(fileVisited);
-						} else if (fileName.endsWith("Response.xml")) {
-							conformanceTest.setResponse(fileVisited);
-						}
-					}
-				}
-				return FileVisitResult.CONTINUE;
-			}
-
-			@Override
-			public FileVisitResult visitFileFailed(Path file, IOException exc) 	throws IOException {
-				logger.warn("Skipped " + file.getFileName());
-				return FileVisitResult.CONTINUE;
-			}
-
-			@Override
-			public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
-				return FileVisitResult.CONTINUE;
-			}
-		});
-		
-		/*
-		 * Sort the keyset and pull out the tests that have the required components
-		 */
-		List<String> listTestNames	= new ArrayList<>();
-		listTestNames.addAll(mapConformanceTests.keySet());
-		Collections.sort(listTestNames);
-		
-		ConformanceTestSet conformanceTestSet	= new ConformanceTestSet();
-		Iterator<String> iterTestNames	= listTestNames.iterator();
-		while (iterTestNames.hasNext()) {
-			ConformanceTest	conformanceTest	= mapConformanceTests.get(iterTestNames.next());
-			if (conformanceTest.isComplete()) {
-				conformanceTestSet.addConformanceTest(conformanceTest);
-				logger.debug("Added conformance test " + conformanceTest.getTestName());
-			} else {
-				logger.warn("Incomplete conformance test " + conformanceTest.getTestName());
-			}
-		}
-		
-		return conformanceTestSet;
-		
-	}
-
-	public Iterator<ConformanceTest> getConformanceTests() {
-		return this.listConformanceTests.iterator();
-	}
-	
-	public void addConformanceTest(ConformanceTest conformanceTest) {
-		this.listConformanceTests.add(conformanceTest);
-	}
-	
-	public void addConformanceTestSet(ConformanceTestSet conformanceTestSet) {
-		this.listConformanceTests.addAll(conformanceTestSet.getListConformanceTests());
-	}
-	
-	public static void main(String[] args) {
-		for (String dir : args) {
-			try {
-				ConformanceTestSet conformanceTestSet			= ConformanceTestSet.loadDirectory(new File(dir));
-				Iterator<ConformanceTest> iterConformanceTests	= conformanceTestSet.getConformanceTests();
-				if (iterConformanceTests == null) {
-					System.out.println("No tests found in " + dir);
-				} else {
-					System.out.println("Tests found in " + dir);
-					while (iterConformanceTests.hasNext()) {
-						System.out.println(iterConformanceTests.next().toString());
-					}
-				}
-			} catch (Exception ex) {
-				ex.printStackTrace(System.err);
-			}
-		}
-	}
-}
diff --git a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/conformance/ResponseMatchResult.java b/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/conformance/ResponseMatchResult.java
deleted file mode 100644
index 4c74230..0000000
--- a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/conformance/ResponseMatchResult.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * ONAP-PDP
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.policy.pdp.test.conformance;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-
-import com.att.research.xacml.api.Response;
-import com.att.research.xacml.api.Result;
-
-/**
- * ResponseMatchResult provides information about how a {@link com.att.research.xacml.api.Response} object matches
- * another <code>Response</code> object.
- * 
- * @version $Revision: 1.1 $
- */
-public class ResponseMatchResult {
-	private List<ResultMatchResult>	resultMatchResults	= new ArrayList<>();
-	
-	private boolean bAssociatedAdviceMatches			= true;
-	private boolean bAttributesMatch					= true;
-	private boolean bDecisionsMatch						= true;
-	private boolean bStatusCodesMatch					= true;
-	private boolean bObligationsMatch					= true;
-	private boolean bPolicyIdentifiersMatch				= true;
-	private boolean bPolicySetIdentifiersMatch			= true;
-	private boolean bNumResultsMatch					= true;
-	private boolean bUnknownFunction;
-	
-	protected void addResultMatchResult(ResultMatchResult resultMatchResult) {
-		this.resultMatchResults.add(resultMatchResult);
-		this.bAssociatedAdviceMatches	= resultMatchResult.associatedAdviceMatches() && this.bAssociatedAdviceMatches;
-		this.bAttributesMatch			= resultMatchResult.attributesMatch() && this.bAttributesMatch;
-		this.bDecisionsMatch			= resultMatchResult.decisionsMatch() && this.bDecisionsMatch;
-		this.bStatusCodesMatch			= resultMatchResult.statusCodesMatch() && this.bStatusCodesMatch;
-		this.bObligationsMatch			= resultMatchResult.obligationsMatch() && this.bObligationsMatch;
-		this.bPolicyIdentifiersMatch	= resultMatchResult.policyIdentifiersMatch() && this.bPolicyIdentifiersMatch;
-		this.bPolicySetIdentifiersMatch	= resultMatchResult.policySetIdentifiersMatch() && this.bPolicySetIdentifiersMatch;
-		this.bUnknownFunction			= resultMatchResult.unknownFunction() || this.bUnknownFunction;
-	}
-	
-	protected void setNumResultsMatch(boolean b) {
-		this.bNumResultsMatch	= b;
-	}
-	
-	public ResponseMatchResult() {
-	}
-	
-	public static ResponseMatchResult newInstance(Response response1, Response response2) {
-		ResponseMatchResult responseMatchResult	= new ResponseMatchResult();
-
-		Collection<Result> listResultsResponse1	= response1.getResults();
-		Collection<Result> listResultsResponse2	= response2.getResults();
-		if (listResultsResponse1.size() == 1 && listResultsResponse2.size() == 1) {
-			/*
-			 * Just add a single ResultMatchResult comparing the results in the two responses
-			 */
-			responseMatchResult.addResultMatchResult(ResultMatchResult.newInstance(listResultsResponse1.iterator().next(), listResultsResponse2.iterator().next()));
-		} else {
-			/*
-			 * Iterate over all of the results in the two responses and match them
-			 */
-			Iterator<Result> iterResponse1Results	= listResultsResponse1.iterator();
-			Iterator<Result> iterResponse2Results	= listResultsResponse2.iterator();
-			while ((iterResponse1Results != null && iterResponse1Results.hasNext()) || (iterResponse2Results != null && iterResponse2Results.hasNext())) {
-				Result result1	= (iterResponse1Results != null && iterResponse1Results.hasNext() ? iterResponse1Results.next() : null);
-				Result result2	= (iterResponse2Results != null && iterResponse2Results.hasNext() ? iterResponse2Results.next() : null);
-				if ((result1 == null || result2 == null) && responseMatchResult.numResultsMatch()) {
-					responseMatchResult.setNumResultsMatch(false);
-				}
-				responseMatchResult.addResultMatchResult(ResultMatchResult.newInstance(result1, result2));
-			}
-		}
-		return responseMatchResult;
-	}
-
-	public Iterator<ResultMatchResult> getResultMatchResults() {
-		return this.resultMatchResults.iterator();
-	}
-	
-	public boolean numResultsMatch() {
-		return this.bNumResultsMatch;
-	}
-	
-	public boolean associatedAdviceMatches() {
-		return this.bAssociatedAdviceMatches;
-	}
-	
-	public boolean attributesMatch() {
-		return this.bAttributesMatch;
-	}
-	
-	public boolean decisionsMatch() {
-		return this.bDecisionsMatch;
-	}
-	
-	public boolean obligationsMatch() {
-		return this.bObligationsMatch;
-	}
-	
-	public boolean policyIdentifiersMatch() {
-		return this.bPolicyIdentifiersMatch;
-	}
-	
-	public boolean policySetIdentifiersMatch() {
-		return this.bPolicySetIdentifiersMatch;
-	}
-	
-	public boolean statusCodesMatch() {
-		return this.bStatusCodesMatch;
-	}
-	
-	public boolean unknownFunction() {
-		return this.bUnknownFunction;
-	}
-
-}
diff --git a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/conformance/ResultMatchResult.java b/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/conformance/ResultMatchResult.java
deleted file mode 100644
index fd6bf71..0000000
--- a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/conformance/ResultMatchResult.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * ONAP-PDP
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.policy.pdp.test.conformance;
-
-import com.att.research.xacml.api.Result;
-import com.att.research.xacml.std.StdStatusCode;
-import com.att.research.xacml.util.ListUtil;
-
-/**
- * ResultMatchResult provides information about how well a {@link com.att.research.xacml.api.Result} object matches
- * another <code>Result</code> object.
- * 
- * @version $Revision: 1.1 $
- */
-public class ResultMatchResult {
-	private boolean bAssociatedAdviceMatches	= true;
-	private boolean bAttributesMatch			= true;
-	private boolean bDecisionsMatch				= true;
-	private boolean bObligationsMatch			= true;
-	private boolean bPolicyIdentifiersMatch		= true;
-	private boolean bPolicySetIdentifiersMatch	= true;
-	private boolean bStatusCodesMatch			= true;
-	private boolean bUnknownFunction			= false;
-	
-	protected void setAssociatedAdviceMatches(boolean b) {
-		this.bAssociatedAdviceMatches	= b;
-	}
-	protected void setAttributesMatch(boolean b) {
-		this.bAttributesMatch	= b;
-	}
-	protected void setDecisionsMatch(boolean b) {
-		this.bDecisionsMatch	= b;
-	}
-	protected void setObligationsMatch(boolean b) {
-		this.bObligationsMatch	= b;
-	}
-	protected void setPolicyIdentifiersMatch(boolean b) {
-		this.bPolicyIdentifiersMatch	= b;
-	}
-	protected void setPolicySetIdentifiersMatch(boolean b) {
-		this.bPolicySetIdentifiersMatch	= b;
-	}
-	protected void setStatusCodesMatch(boolean b) {
-		this.bStatusCodesMatch	= b;
-	}
-	protected void setUnknownFunction(boolean b) {
-		this.bUnknownFunction	= b;
-	}
-	
-	public ResultMatchResult() {
-	}
-	
-	public static ResultMatchResult newInstance(Result result1, Result result2) {
-		ResultMatchResult resultMatchResult	= new ResultMatchResult();
-		if (result2 != null && result2.getStatus() != null && 
-			result2.getStatus().getStatusCode().equals(StdStatusCode.STATUS_CODE_PROCESSING_ERROR) && 
-			result2.getStatus().getStatusMessage() != null &&
-			result2.getStatus().getStatusMessage().contains("Unknown Function")
-			) {
-			resultMatchResult.setUnknownFunction(true);
-		}
-		if (result1 == null || result2 == null) {
-			resultMatchResult.setAssociatedAdviceMatches(false);
-			resultMatchResult.setAttributesMatch(false);
-			resultMatchResult.setDecisionsMatch(false);
-			resultMatchResult.setObligationsMatch(false);
-			resultMatchResult.setPolicyIdentifiersMatch(false);
-			resultMatchResult.setPolicySetIdentifiersMatch(false);
-			resultMatchResult.setStatusCodesMatch(false);
-		} else {
-			resultMatchResult.setAssociatedAdviceMatches(ListUtil.equalsAllowNulls(result1.getAssociatedAdvice(), result2.getAssociatedAdvice()));
-			resultMatchResult.setAttributesMatch(ListUtil.equalsAllowNulls(result1.getAttributes(), result2.getAttributes()));
-			resultMatchResult.setDecisionsMatch(result1.getDecision() == result2.getDecision());
-			resultMatchResult.setObligationsMatch(ListUtil.equalsAllowNulls(result1.getObligations(), result2.getObligations()));
-			resultMatchResult.setPolicyIdentifiersMatch(ListUtil.equalsAllowNulls(result1.getPolicyIdentifiers(), result2.getPolicyIdentifiers()));
-			resultMatchResult.setPolicySetIdentifiersMatch(ListUtil.equalsAllowNulls(result1.getPolicySetIdentifiers(), result2.getPolicySetIdentifiers()));
-			if (result1.getStatus() == null || result1.getStatus().getStatusCode() == null || result2.getStatus() == null || result2.getStatus().getStatusCode() == null) {
-				resultMatchResult.setStatusCodesMatch(false);
-			} else {
-				resultMatchResult.setStatusCodesMatch(result1.getStatus().getStatusCode().equals(result2.getStatus().getStatusCode()));
-			}
-		}
-		return resultMatchResult;
-	}
-	
-	public boolean associatedAdviceMatches() {
-		return this.bAssociatedAdviceMatches;
-	}
-	
-	public boolean attributesMatch() {
-		return this.bAttributesMatch;
-	}
-	
-	public boolean decisionsMatch() {
-		return this.bDecisionsMatch;
-	}
-	
-	public boolean obligationsMatch() {
-		return this.bObligationsMatch;
-	}
-	
-	public boolean policyIdentifiersMatch() {
-		return this.bPolicyIdentifiersMatch;
-	}
-	
-	public boolean policySetIdentifiersMatch() {
-		return this.bPolicySetIdentifiersMatch;
-	}
-	
-	public boolean statusCodesMatch() {
-		return this.bStatusCodesMatch;
-	}
-	
-	public boolean unknownFunction() {
-		return this.bUnknownFunction;
-	}
-
-}
diff --git a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/custom/CustomDataTypeFactory.java b/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/custom/CustomDataTypeFactory.java
deleted file mode 100644
index 82a2e3e..0000000
--- a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/custom/CustomDataTypeFactory.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * ONAP-PDP
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.policy.pdp.test.custom;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import com.att.research.xacml.api.DataType;
-import com.att.research.xacml.api.DataTypeFactory;
-import com.att.research.xacml.api.Identifier;
-import com.att.research.xacml.std.datatypes.DataTypes;
-
-public class CustomDataTypeFactory extends DataTypeFactory {
-	private static final Map<Identifier,DataType<?>> mapIdentifiersToDataTypes	= new HashMap<>();
-	private static boolean mapNeedsInit												= true;
-	
-	public static final DataTypePrivateKey				DT_PRIVATEKEY				= DataTypePrivateKey.newInstance();
-	public static final DataTypePublicKey				DT_PUBLICKEY				= DataTypePublicKey.newInstance();
-	
-	private static void registerDataType(DataType<?> dataType) {
-		if (dataType != null && dataType.getId() != null) {
-			mapIdentifiersToDataTypes.put(dataType.getId(), dataType);
-		}
-	}
-	
-	private static void initMap() {
-		if (mapNeedsInit) {
-			synchronized(mapIdentifiersToDataTypes) {
-				if (mapNeedsInit) {
-					registerDataType(DataTypes.DT_ANYURI);
-					registerDataType(DataTypes.DT_BASE64BINARY);
-					registerDataType(DataTypes.DT_BOOLEAN);
-					registerDataType(DataTypes.DT_DATE);
-					registerDataType(DataTypes.DT_DATETIME);
-					registerDataType(DataTypes.DT_DAYTIMEDURATION);
-					registerDataType(DataTypes.DT_DNSNAME);
-					registerDataType(DataTypes.DT_DOUBLE);
-					registerDataType(DataTypes.DT_HEXBINARY);
-					registerDataType(DataTypes.DT_INTEGER);
-					registerDataType(DataTypes.DT_IPADDRESS);
-					registerDataType(DataTypes.DT_RFC822NAME);
-					registerDataType(DataTypes.DT_STRING);
-					registerDataType(DataTypes.DT_TIME);
-					registerDataType(DataTypes.DT_X500NAME);
-					registerDataType(DataTypes.DT_XPATHEXPRESSION);
-					registerDataType(DataTypes.DT_YEARMONTHDURATION);
-					//
-					// These are the custom data types!
-					//
-					registerDataType(DT_PRIVATEKEY);
-					registerDataType(DT_PUBLICKEY);
-					//
-					// Done
-					//
-					mapNeedsInit	= false;
-				}
-			}
-		}
-	}
-
-	public CustomDataTypeFactory() {
-		initMap();
-	}
-
-	@Override
-	public DataType<?> getDataType(Identifier dataTypeId) {
-		return mapIdentifiersToDataTypes.get(dataTypeId);
-	}
-
-}
diff --git a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/custom/CustomFunctionDefinitionFactory.java b/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/custom/CustomFunctionDefinitionFactory.java
deleted file mode 100644
index 017edad..0000000
--- a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/custom/CustomFunctionDefinitionFactory.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * ONAP-PDP
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.policy.pdp.test.custom;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.util.HashMap;
-import java.util.Map;
-
-import com.att.research.xacml.api.Identifier;
-import com.att.research.xacml.std.IdentifierImpl;
-import com.att.research.xacmlatt.pdp.policy.FunctionDefinition;
-import com.att.research.xacmlatt.pdp.policy.FunctionDefinitionFactory;
-import com.att.research.xacmlatt.pdp.std.StdFunctions;
-import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionBagOneAndOnly;
-
-public class CustomFunctionDefinitionFactory extends FunctionDefinitionFactory {
-	private static Map<Identifier,FunctionDefinition> 	mapFunctionDefinitions	= new HashMap<>();
-	private static boolean								needMapInit				= true;
-	
-	public static final Identifier ID_FUNCTION_PRIVATEKEY_ONE_AND_ONLY = new IdentifierImpl("urn:com:att:research:xacml:custom:function:3.0:rsa:privatekey-one-and-only");
-	public static final Identifier ID_FUNCTION_PUBLICKEY_ONE_AND_ONLY = new IdentifierImpl("urn:com:att:research:xacml:custom:function:3.0:rsa:publickey-one-and-only");
-	
-	public static final FunctionDefinition	FD_PRIVATEKEY_ONE_AND_ONLY	= new FunctionDefinitionBagOneAndOnly<PrivateKey>(ID_FUNCTION_PRIVATEKEY_ONE_AND_ONLY, DataTypePrivateKey.newInstance());
-	public static final FunctionDefinition	FD_PUBLICKEY_ONE_AND_ONLY	= new FunctionDefinitionBagOneAndOnly<PublicKey>(ID_FUNCTION_PUBLICKEY_ONE_AND_ONLY, DataTypePublicKey.newInstance());
-
-	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) {
-								
-							}
-						}
-					}
-					//
-					// Our custom function
-					//
-					register(FunctionDefinitionDecrypt.newInstance());
-					register(FD_PRIVATEKEY_ONE_AND_ONLY);
-					register(FD_PUBLICKEY_ONE_AND_ONLY);
-				}
-			}
-		}
-	}
-	
-	public CustomFunctionDefinitionFactory() {
-		initMap();
-	}
-
-	@Override
-	public FunctionDefinition getFunctionDefinition(Identifier functionId) {
-		return mapFunctionDefinitions.get(functionId);
-	}
-
-}
diff --git a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/custom/DataTypePrivateKey.java b/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/custom/DataTypePrivateKey.java
deleted file mode 100644
index 36fd9e7..0000000
--- a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/custom/DataTypePrivateKey.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * ONAP-PDP
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.policy.pdp.test.custom;
-
-import java.security.PrivateKey;
-
-import com.att.research.xacml.api.DataTypeException;
-import com.att.research.xacml.api.Identifier;
-import com.att.research.xacml.std.IdentifierImpl;
-import com.att.research.xacml.std.datatypes.DataTypeBase;
-
-public class DataTypePrivateKey extends DataTypeBase<PrivateKey> {
-	public static final Identifier DT_PRIVATEKEY = new IdentifierImpl("urn:com:att:research:xacml:custom:3.0:rsa:private");
-	private static final DataTypePrivateKey singleInstance = new DataTypePrivateKey();
-	
-	private DataTypePrivateKey() {
-		super(DT_PRIVATEKEY, PrivateKey.class);
-	}
-
-	public static DataTypePrivateKey newInstance() {
-		return singleInstance;
-	}
-	
-	@Override
-	public PrivateKey convert(Object source) throws DataTypeException {
-		if (source == null || (source instanceof PrivateKey) ) {
-			return (PrivateKey) source;
-		} else if (source instanceof byte[]) {
-			return (PrivateKey) source;
-		} else if (source instanceof String) {
-			return (PrivateKey) (Object) ((String) source).getBytes();
-		}
-		throw new DataTypeException(this, "Failed to convert \"" + source.getClass().getCanonicalName());				
-	}
-
-}
diff --git a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/custom/DataTypePublicKey.java b/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/custom/DataTypePublicKey.java
deleted file mode 100644
index b732747..0000000
--- a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/custom/DataTypePublicKey.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * ONAP-PDP
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.policy.pdp.test.custom;
-
-import java.security.PublicKey;
-
-import com.att.research.xacml.api.DataTypeException;
-import com.att.research.xacml.api.Identifier;
-import com.att.research.xacml.std.IdentifierImpl;
-import com.att.research.xacml.std.datatypes.DataTypeBase;
-
-public class DataTypePublicKey extends DataTypeBase<PublicKey> {
-	public static final Identifier DT_PUBLICKEY = new IdentifierImpl("urn:com:att:research:xacml:custom:3.0:rsa:public");
-	private static final DataTypePublicKey singleInstance = new DataTypePublicKey();
-	
-	public DataTypePublicKey() {
-		super(DT_PUBLICKEY, PublicKey.class);
-	}
-	
-	public static DataTypePublicKey newInstance() {
-		return singleInstance;
-	}
-
-	@Override
-	public PublicKey convert(Object source) throws DataTypeException {
-		if (source == null || (source instanceof PublicKey) ) {
-			return (PublicKey) source;
-		} else if (source instanceof byte[]) {
-			return (PublicKey) source;
-		} else if (source instanceof String) {
-			return (PublicKey) (Object) ((String) source).getBytes();
-		}
-		throw new DataTypeException(this, "Failed to convert \"" + source.getClass().getCanonicalName());				
-	}
-
-}
diff --git a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/custom/FunctionDefinitionDecrypt.java b/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/custom/FunctionDefinitionDecrypt.java
deleted file mode 100644
index 6d34e63..0000000
--- a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/custom/FunctionDefinitionDecrypt.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * ONAP-PDP
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.policy.pdp.test.custom;
-
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.util.List;
-
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.NoSuchPaddingException;
-
-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.XACML3;
-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.DataTypeHexBinary;
-import com.att.research.xacml.std.datatypes.DataTypeString;
-import com.att.research.xacml.std.datatypes.HexBinary;
-import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
-import com.att.research.xacmlatt.pdp.policy.ExpressionResult;
-import com.att.research.xacmlatt.pdp.policy.FunctionArgument;
-import com.att.research.xacmlatt.pdp.policy.FunctionDefinition;
-import com.att.research.xacmlatt.pdp.std.functions.ConvertedArgument;
-
-public class FunctionDefinitionDecrypt implements FunctionDefinition {
-	public static final Identifier FD_RSA_DECRYPT = new IdentifierImpl("urn:com:att:research:xacml:custom:function:3.0:rsa:decrypt");
-	private static final FunctionDefinitionDecrypt singleInstance = new FunctionDefinitionDecrypt();
-	
-	public static FunctionDefinitionDecrypt newInstance() {
-		return singleInstance;
-	}
-
-	@Override
-	public Identifier getId() {
-		return FD_RSA_DECRYPT;
-	}
-
-	@Override
-	public Identifier getDataTypeId() {
-		return XACML3.ID_DATATYPE_STRING;
-	}
-
-	@Override
-	public boolean returnsBag() {
-		return 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, "Decrypt failed, expecting 2 arguments."));
-		}
-		//
-		// What is the first argument?
-		//
-		FunctionArgument arg0 = arguments.get(0);
-		if (arg0.isBag()) {
-			//
-			// We don't support bags right now
-			//
-			return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Decrypt failed, not expecting a bag for argument 0."));
-		}
-		if (arg0.getValue().getDataTypeId().equals(XACML3.ID_DATATYPE_HEXBINARY) == false) {
-			//
-			// Should be a String
-			//
-			return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Decrypt failed, expected a Hex Binary for argument 0."));
-		}
-		//
-		// Convert the argument
-		//
-		ConvertedArgument<HexBinary> data = new ConvertedArgument<HexBinary>(arg0, DataTypeHexBinary.newInstance(), false);
-		if (! data.isOk()) {
-			return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Decrypt failed, argument 0 failed to convert to Hex Binary."));
-		}
-		//
-		// Ok - check the 2nd argument
-		//
-		FunctionArgument arg1 = arguments.get(1);
-		if (arg1.isBag()) {
-			//
-			// We don't support bags right now
-			//
-			return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Decrypt failed, not expecting a bag for argument 1."));
-		}
-		if (arg1.getValue().getDataTypeId().equals(DataTypePrivateKey.DT_PRIVATEKEY) ||
-				arg1.getValue().getDataTypeId().equals(DataTypePublicKey.DT_PUBLICKEY)) {
-			//
-			// Ok - let's try to decrypt
-			//
-			Cipher cipher;
-			try {
-				cipher = Cipher.getInstance("RSA");
-				if (arg1.getValue().getDataTypeId().equals(DataTypePrivateKey.DT_PRIVATEKEY)) {
-					//
-					// Using the private key
-					//
-					DataType<PrivateKey> pkDatatype = DataTypePrivateKey.newInstance();
-					ConvertedArgument<PrivateKey> privateKey = new ConvertedArgument<PrivateKey>(arg1, pkDatatype, false);
-					if ( ! privateKey.isOk()) {
-						return ExpressionResult.newError(new StdStatus(privateKey.getStatus().getStatusCode(), "Decrypt: " + privateKey.getStatus().getStatusMessage()));
-					}
-					//
-					// Setup decryption
-					//
-					cipher.init(Cipher.DECRYPT_MODE, privateKey.getValue());
-				} else if (arg1.getValue().getDataTypeId().equals(DataTypePublicKey.DT_PUBLICKEY)) {
-					//
-					// Using the private key
-					//
-					DataType<PublicKey> pkDatatype = DataTypePublicKey.newInstance();
-					ConvertedArgument<PublicKey> publicKey = new ConvertedArgument<PublicKey>(arg1, pkDatatype, false);
-					if ( ! publicKey.isOk()) {
-						return ExpressionResult.newError(new StdStatus(publicKey.getStatus().getStatusCode(), "Decrypt: " + publicKey.getStatus().getStatusMessage()));
-					}
-					//
-					// Setup decryption
-					//
-					cipher.init(Cipher.DECRYPT_MODE, publicKey.getValue());
-				}
-				//
-				// Do the decryption
-				//
-				byte[] decryptedData = cipher.doFinal(data.getValue().getData());
-				String decryptedString = new String(decryptedData);
-				//
-				// All good, return the decrypted string
-				//
-				return ExpressionResult.newSingle(DataTypeString.newInstance().createAttributeValue(decryptedString));
-			} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | DataTypeException e) {
-				return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Decrypt failed: " + e.getLocalizedMessage()));
-			}
-		}		
-		return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Decrypt failed, expecting public/private key datatype for argument 1."));
-	}
-
-}
diff --git a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/custom/TestBase.java b/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/custom/TestBase.java
deleted file mode 100644
index 2ccf156..0000000
--- a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/custom/TestBase.java
+++ /dev/null
@@ -1,1082 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * ONAP-PDP
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.policy.pdp.test.custom;
-
-import java.io.BufferedReader;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.nio.file.FileVisitResult;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.SimpleFileVisitor;
-import java.nio.file.attribute.BasicFileAttributes;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.GnuParser;
-import org.apache.commons.cli.HelpFormatter;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.commons.cli.ParseException;
-import org.apache.commons.io.IOUtils;
-import org.apache.http.entity.ContentType;
-import org.onap.policy.common.logging.flexlogger.FlexLogger;
-import org.onap.policy.common.logging.flexlogger.Logger;
-
-import com.att.research.xacml.api.AttributeValue;
-import com.att.research.xacml.api.DataType;
-import com.att.research.xacml.api.DataTypeException;
-import com.att.research.xacml.api.DataTypeFactory;
-import com.att.research.xacml.api.Decision;
-import com.att.research.xacml.api.Identifier;
-import com.att.research.xacml.api.Request;
-import com.att.research.xacml.api.RequestAttributes;
-import com.att.research.xacml.api.Response;
-import com.att.research.xacml.api.Result;
-import com.att.research.xacml.api.pdp.PDPEngine;
-import com.att.research.xacml.api.pdp.PDPEngineFactory;
-import com.att.research.xacml.api.pdp.PDPException;
-import com.att.research.xacml.api.pep.PEPException;
-import com.att.research.xacml.std.IdentifierImpl;
-import com.att.research.xacml.std.StdAttributeValue;
-import com.att.research.xacml.std.StdMutableAttribute;
-import com.att.research.xacml.std.StdMutableRequest;
-import com.att.research.xacml.std.StdMutableRequestAttributes;
-import com.att.research.xacml.std.dom.DOMRequest;
-import com.att.research.xacml.std.dom.DOMResponse;
-import com.att.research.xacml.std.dom.DOMStructureException;
-import com.att.research.xacml.std.json.JSONRequest;
-import com.att.research.xacml.std.json.JSONResponse;
-import com.att.research.xacml.std.json.JSONStructureException;
-import com.att.research.xacml.util.FactoryException;
-import com.att.research.xacml.util.XACMLProperties;
-import com.google.common.base.Splitter;
-import com.google.common.collect.Lists; 
-
-/**
- * This is a base class for setting up a test environment. Using properties files, it contains the
- * necessary information for 
- * 1. defining and providing attributes
- * 2. defining and instantiating the PDP engine
- * 3. creating PEP requests and calling the PDP engine
- * 
- *
- */
-public class TestBase extends SimpleFileVisitor<Path> {
-	private static final Logger logger	= FlexLogger.getLogger(TestBase.class);
-	
-	public class HelpException extends Exception {
-		private static final long serialVersionUID = 1L;
-		
-	}
-	
-	/**
-	 * This private class holds information for properties defined for attribute
-	 * generation. The user can configure the properties file such that attributes
-	 * can be automatically generated and added into each request.
-	 * 
-	 *
-	 */
-	class Generator {
-		Path file;
-		InputStream is;
-		BufferedReader reader;
-		List<StdMutableAttribute> attributes = new ArrayList<>();
-		
-		public Generator(Path path) {
-			this.file = path;
-		}
-
-		/**
-		 * read - reads in the next line of data
-		 * 
-		 * @return	String - a line from the csv containing attribute data
-		 */
-		public String	read() {
-			String str = null;
-			if (is == null) {
-				try {
-					is = Files.newInputStream(file);
-				} catch (IOException e) {
-					logger.error(e);
-					return null;
-				}
-			}
-			if (reader == null) {
-				reader = new BufferedReader(new InputStreamReader(this.is));
-			}
-			try {
-				str = reader.readLine();
-				if (str == null) {
-					//
-					// No more strings, close up
-					//
-					this.close();
-				}
-				if (logger.isDebugEnabled()) {
-					logger.debug(str);
-				}
-			} catch (IOException e) {
-				logger.error(e);
-			}
-			return str;
-		}
-		
-		public void 	close() {
-			if (this.reader != null) {
-				try {
-					this.reader.close();
-				} catch (IOException idontcare) {
-				} finally {
-					this.reader = null;
-					this.is = null;
-				}
-			}
-		}
-		
-	}
-	
-	public static final String PROP_GENERATOR = "xacml.attribute.generator";
-	
-	public static final String OPTION_HELP = "help";
-	public static final String OPTION_TESTDIR = "dir";
-	public static final String OPTION_TESTREST = "rest";
-	public static final String OPTION_TESTURL = "url";
-	public static final String OPTION_TESTOUTPUT = "output";
-	public static final String OPTION_LOOP = "loop";
-	public static final String OPTION_TESTNUMBERS = "testNumbers";
-
-	public static final String DEFAULT_RESTURL = "https://localhost:8080/pdp/";	// Modified for test purpose. Port no. 8443 to 8080
-	
-	public static Options options = new Options();
-	static {
-		options.addOption(new Option(OPTION_HELP, false, "Prints help."));
-		options.addOption(new Option(OPTION_TESTDIR, true, "Directory path where all the test properties and data are located."));
-		options.addOption(new Option(OPTION_TESTREST, false, "Test against RESTful PDP."));
-		options.addOption(new Option(OPTION_TESTURL, true, "URL to the RESTful PDP. Default is " + DEFAULT_RESTURL));
-		options.addOption(new Option(OPTION_TESTOUTPUT, true, "Specify a different location for dumping responses."));
-		options.addOption(new Option(OPTION_LOOP, true, "Number of times to loop through the tests. Default is 1. A value of -1 runs indefinitely."));
-		options.addOption(new Option(OPTION_TESTNUMBERS, true, "Comma-separated list of numbers found in the names of the test files to be run.  Numbers must exactly match the file name, e.g. '02'.  Used to limit testing to specific set of tests."));
-	}
-	
-	protected String directory = null;
-	protected Path output = null;
-	protected boolean isREST;
-	protected URL restURL = null;
-	protected int loop = 1;
-	protected PDPEngine engine = null;
-	protected List<Generator> generators = new ArrayList<>();
-	protected static DataTypeFactory dataTypeFactory		= null;
-	
-	private long	permits = 0;
-	private long	denies = 0;
-	private long	notapplicables = 0;
-	private long	indeterminates = 0;
-	
-	private long	expectedPermits = 0;
-	private long	expectedDenies = 0;
-	private long	expectedNotApplicables = 0;
-	private long	expectedIndeterminates = 0;
-	
-	private long	generatedpermits = 0;
-	private long	generateddenies = 0;
-	private long	generatednotapplicables = 0;
-	private long	generatedindeterminates = 0;
-	
-	private long	responseMatches = 0;
-	private long	responseNotMatches = 0;
-	
-	private String[]	testNumbersArray = null;
-	
-	protected final Pattern pattern = Pattern.compile("Request[.]\\d+[.](Permit|Deny|NA|Indeterminate|Generate|Unknown)\\.(json|xml)");
-	
-	public static boolean isJSON(Path file) {
-		return file.toString().endsWith(".json");
-	}
-	
-	public static boolean isXML(Path file) {
-		return file.toString().endsWith(".xml");
-	}
-	
-	public TestBase(String[] args) throws ParseException, MalformedURLException, HelpException {
-		//
-		// Finish Initialization
-		//
-		this.restURL = new URL(DEFAULT_RESTURL);
-		//
-		// Parse arguments
-		//
-		this.parseCommands(args);
-	}
-	
-	/**
-	 * Parse in the command line arguments that the following parameters:
-	 * 
-	 * @param args - command line arguments
-	 * @throws ParseException 
-	 * @throws MalformedURLException 
-	 * @throws HelpException 
-	 */
-	protected void parseCommands(String[] args) throws ParseException, MalformedURLException, HelpException {
-		//
-		// Parse the command line options
-		//
-		CommandLine cl;
-		cl = new GnuParser().parse(options, args);
-		//
-		// Check for what we have
-		//
-		if (cl.hasOption(OPTION_HELP)) {
-    		new HelpFormatter().printHelp("Usage: -dir testdirectory OPTIONS",
-    				options);
-    		throw new HelpException();
-		}
-		if (cl.hasOption(OPTION_TESTDIR)) {
-			this.directory = cl.getOptionValue(OPTION_TESTDIR);
-		} else {
-			throw new IllegalArgumentException("You must specify a test directory. -dir path/to/some/where");
-		}
-		if (cl.hasOption(OPTION_TESTREST)) {
-			this.isREST = true;
-		} else {
-			this.isREST = false;
-		}
-		if (cl.hasOption(OPTION_TESTURL)) {
-			this.restURL = new URL(cl.getOptionValue(OPTION_TESTURL));
-		}
-		if (cl.hasOption(OPTION_TESTOUTPUT)) {
-			this.output = Paths.get(cl.getOptionValue(OPTION_TESTOUTPUT));
-		} else {
-			this.output = Paths.get(this.directory, "results");
-		}
-		if (cl.hasOption(OPTION_LOOP)) {
-			this.loop = Integer.parseInt(cl.getOptionValue(OPTION_LOOP));
-		}
-		if (cl.hasOption(OPTION_TESTNUMBERS)) {
-			String testNumberString = cl.getOptionValue(OPTION_TESTNUMBERS);
-			testNumbersArray = testNumberString.split(",");
-			//
-			// reset strings to include dots so they exactly match pattern in file name
-			//
-			for (int i = 0; i < testNumbersArray.length; i++) {
-				testNumbersArray[i] = "." + testNumbersArray[i] + ".";
-			}
-		}
-	}
-	
-	/**
-	 * Using the command line options that were parsed, configures our test instance.
-	 * 
-	 * @throws FactoryException
-	 */
-	protected void configure() throws FactoryException {
-		//
-		// Setup the xacml.properties file
-		//
-		if (this.directory == null) {
-			throw new IllegalArgumentException("Must supply a path to a test directory.");
-		}
-		Path pathDir = Paths.get(this.directory, "xacml.properties");
-		if (Files.notExists(pathDir)) {
-			throw new IllegalArgumentException(pathDir.toString() + " does not exist.");
-		}
-		//
-		// Set it as the System variable so the XACML factories know where the properties are
-		// loaded from.
-		//
-		System.setProperty(XACMLProperties.XACML_PROPERTIES_NAME, pathDir.toString());
-		//
-		// Now we can create the data type factory
-		//
-		dataTypeFactory	= DataTypeFactory.newInstance();
-		//
-		// Load in what generators we are to create
-		//
-		String generators = XACMLProperties.getProperty(PROP_GENERATOR);
-		if (generators != null) {
-			//
-			// Parse the generators
-			//
-			for (String generator : Splitter.on(',').trimResults().omitEmptyStrings().split(generators)) {
-				this.configureGenerator(generator);
-			}
-		}
-		//
-		// If we are embedded, create our engine
-		//
-		if (this.isREST == false) {
-			PDPEngineFactory factory = PDPEngineFactory.newInstance();
-			this.engine = factory.newEngine();
-		}
-		//
-		// Remove all the responses from the results directory
-		//
-		this.removeResults();
-	}
-	
-	/**
-	 * Removes all the Response* files from the results directory.
-	 * 
-	 */
-	public void	removeResults() {
-		try {
-			//
-			// Determine where the results are supposed to be written to
-			//
-			Path resultsPath;
-			if (this.output != null) {
-				resultsPath = this.output;
-			} else {
-				resultsPath = Paths.get(this.directory.toString(), "results");
-			}
-			//
-			// Walk the files
-			//
-			Files.walkFileTree(resultsPath, new SimpleFileVisitor<Path>() {
-
-				@Override
-				public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
-					if (file.getFileName().toString().startsWith("Response")) {
-						Files.delete(file);
-					}
-					return super.visitFile(file, attrs);
-				}				
-			});
-		} catch (IOException e) {
-			logger.error("Failed to removeRequests from " + this.directory + " " + e);
-		}
-	}
-	
-	/**
-	 * Configure's a specific generator instance from the properties file.
-	 * 
-	 * @param generator
-	 */
-	protected void configureGenerator(String generator) {
-		String prefix = PROP_GENERATOR + "." + generator;
-		String file = XACMLProperties.getProperty(prefix + ".file");
-		//
-		// Create a generator object
-		//
-		Generator gen = new Generator(Paths.get(this.directory, file));
-		this.generators.add(gen);
-		//
-		// Grab attributes
-		//
-		String attributes = XACMLProperties.getProperty(prefix + ".attributes");
-		for (String attribute : Splitter.on(',').trimResults().omitEmptyStrings().split(attributes)) {
-			String attributePrefix = prefix + ".attributes." + attribute;
-			//
-			// Create an attribute value. It is simply a placeholder for the field within
-			// the CSV that contains the actual attribute value. It mainly holds the data type
-			//
-			Identifier datatype = new IdentifierImpl(XACMLProperties.getProperty(attributePrefix + ".datatype"));
-			Integer field = Integer.parseInt(XACMLProperties.getProperty(attributePrefix + ".field"));
-			StdAttributeValue<?> value = new StdAttributeValue<>(datatype, field);
-			//
-			// Get the rest of the attribute properties
-			//
-			Identifier category = new IdentifierImpl(XACMLProperties.getProperty(attributePrefix + ".category"));
-			Identifier id = new IdentifierImpl(XACMLProperties.getProperty(attributePrefix + ".id"));
-			String issuer = XACMLProperties.getProperty(attributePrefix + ".issuer");
-			boolean include = Boolean.parseBoolean(XACMLProperties.getProperty(attributePrefix + ".include", "false"));
-			//
-			// Now we have a skeleton attribute
-			//
-			gen.attributes.add(new StdMutableAttribute(category, id, value, issuer, include));
-		}
-	}
-	
-	/**
-	 * This runs() the test instance. It first configure's itself and then walks the
-	 * requests directory issue each request to the PDP engine.
-	 * 
-	 * @throws IOException
-	 * @throws FactoryException 
-	 * 
-	 */
-	public void run() throws IOException, FactoryException {
-		//
-		// Configure ourselves
-		//
-		this.configure();
-		//
-		// Loop and run
-		//
-		int runs = 1;
-		do {
-			long lTimeStart = System.currentTimeMillis();
-			logger.info("Run number: " + runs);
-			//
-			// Walk the request directory
-			//
-			Files.walkFileTree(Paths.get(this.directory.toString(), "requests"), this);
-			long lTimeEnd = System.currentTimeMillis();
-			logger.info("Run elapsed time: " + (lTimeEnd - lTimeStart) + "ms");
-			//
-			// Dump the stats
-			//
-			this.dumpStats();
-			this.resetStats();
-			//
-			// Increment
-			//
-			runs++;
-		} while ((this.loop == -1 ? true : runs <= this.loop));
-	}
-	
-	@Override
-	public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
-		//
-		// Sanity check the file name
-		//
-		Matcher matcher = this.pattern.matcher(file.getFileName().toString());
-		if (matcher.matches()) {
-			//
-			// if user has limited which files to use, check that here
-			//
-			if (testNumbersArray != null) {
-				String fileNameString = file.getFileName().toString();
-				boolean found = false;
-				for (String numberString : testNumbersArray) {
-					if (fileNameString.contains(numberString)) {
-						found = true;
-						break;
-					}
-				}
-				if (found == false) {
-					//
-					// this test is not in the list to be run, so skip it
-					//
-					return super.visitFile(file, attrs);
-				}
-			}
-			try {
-				//
-				// Pull what this request is supposed to be
-				//
-				String group = null;
-				int count = matcher.groupCount();
-				if (count >= 1) {
-					group = matcher.group(count-1);
-				}
-				//
-				// Send it
-				//
-				this.sendRequest(file, group);
-			} catch (Exception e) {
-				logger.error(e);
-				logger.error("Exception Occured"+e);
-			}
-		}
-		return super.visitFile(file, attrs);
-	}
-	
-	/**
-	 * When a request file is encountered, this method is called send the request to the PDP engine. It will also dump
-	 * the response object. If the group equals "Generate", then it will loop and send the request with generated attributes
-	 * until that list is empty.
-	 * 
-	 * @param file - Request file. Eg. Request-01-Permit.json
-	 * @param group - This is the parsed out string of the request file that defines if it is a Permit/Deny/Generate etc.
-	 * @throws Exception
-	 */
-	protected void sendRequest(Path file, String group) throws Exception {
-		logger.info(file.toString());
-		int requestCount = 0;
-		do {
-			//
-			// Generate the request
-			//
-			Request request = this.generateRequest(file, group);
-			//
-			// Was something generated?
-			//
-			if (request == null) {
-				//
-				// Get out of the loop
-				//
-				logger.info("NULL request generated.");
-				break;
-			}
-			logger.info(request);
-			//
-			// Call the PDP
-			//
-			Response response = this.callPDP(request);
-			//
-			// Process the response
-			//
-			this.processResponse(file, request, response, group, requestCount);
-			//
-			// Is this a generated request?
-			//
-			if (group.equals("Generate")) {
-				//
-				// Yes, increment counter and move
-				// on to the next generated request.
-				//
-				requestCount++;
-			} else {
-				//
-				// Nope, exit the loop
-				//
-				break;
-			}
-		} while (group.equals("Generate"));
-	}
-	
-	/**
-	 * Sends the request object to the PDP engine. Either the embedded engine or the RESTful engine.
-	 * 
-	 * @param request - XACML request object
-	 * @return Response - returns the XACML response object
-	 */
-	protected Response callPDP(Request request) {
-		//
-		// Send it to the PDP
-		//
-		Response response = null;
-		if (this.isREST) {
-			try {
-				String jsonString = JSONRequest.toString(request, false);
-				//
-				// Call RESTful PDP
-				//
-				response = this.callRESTfulPDP(new ByteArrayInputStream(jsonString.getBytes()));
-			} catch (Exception e) {
-				logger.error("Error in sending RESTful request: " + e, e);
-			}
-		} else {
-			//
-			// Embedded call to PDP
-			//
-			long lTimeStart = System.currentTimeMillis();
-			try {
-				response = this.engine.decide(request);
-			} catch (PDPException e) {
-				logger.error(e);
-			}
-			long lTimeEnd = System.currentTimeMillis();
-			logger.info("Elapsed Time: " + (lTimeEnd - lTimeStart) + "ms");
-		}
-		return response;
-	}
-	
-	/**
-	 * Reads the request file into a Request object based on its type.
-	 * 
-	 * If the request has "Generate" in its filename, then this function will add
-	 * generated attributes into the request.
-	 * 
-	 * @param file - Request file. Eg. Request-01-Permit.json
-	 * @param group - This is the parsed out string of the request file that defines if it is a Permit/Deny/Generate etc.
-	 * @return
-	 * @throws JSONStructureException
-	 * @throws DOMStructureException
-	 * @throws PEPException
-	 */
-	protected Request generateRequest(Path file, String group) throws JSONStructureException, DOMStructureException, PEPException {
-		//
-		// Convert to a XACML Request Object
-		//
-		Request request = null;
-		if (TestBase.isJSON(file)) {
-			request = JSONRequest.load(file.toFile());
-		} else if (TestBase.isXML(file)) {
-			request = DOMRequest.load(file.toFile());
-		}
-		if (request == null) {
-			throw new PEPException("Invalid Request File: " + file.toString());
-		}
-		//
-		// Only if this request has "Generate"
-		// Request.XX.Generate.[json|xml]
-		//
-		if (group.equals("Generate")) {
-			//
-			// Add attributes to it
-			//
-			request = this.onNextRequest(request);
-		}
-		//
-		// Done
-		//
-		return request;
-	}
-
-	/**
-	 * Called to add in generated attributes into the request.
-	 * 
-	 * @param request
-	 * @return
-	 */
-	protected Request onNextRequest(Request request) {
-		//
-		// If we have no generators, just return
-		//
-		if (this.generators.isEmpty()) {
-			return request;
-		}
-		//
-		// Copy the request attributes
-		//
-		List<StdMutableRequestAttributes> attributes = new ArrayList<>();
-		for (RequestAttributes a : request.getRequestAttributes()) {
-			attributes.add(new StdMutableRequestAttributes(a));
-		}
-		//
-		// Iterate the generators
-		//
-		for (Generator generator : this.generators) {
-			//
-			// Read a row in
-			//
-			String line = generator.read();
-			//
-			// Was something read?
-			//
-			if (line == null) {
-				//
-				// No more rows to read, return null
-				//
-				return null;
-			}
-			//
-			// Split the line
-			//
-			List<String> fields = Lists.newArrayList(Splitter.on(',').trimResults().split(line));
-			//
-			// Now work on the attributes
-			//
-			for (StdMutableAttribute attribute : generator.attributes) {
-				//
-				// Grab the attribute holder, which holds the datatype and field. There should
-				// be only ONE object in the collection.
-				//
-				AttributeValue<?> value = attribute.getValues().iterator().next();
-				Integer field = (Integer) value.getValue();
-				//
-				// Is the field number valid?
-				//
-				if (field >= fields.size()) {
-					logger.error("Not enough fields: " + field + "(" + fields.size() + ")");
-					return null;
-				}
-				//
-				// Determine what datatype it is
-				//
-				DataType<?> dataTypeExtended	= dataTypeFactory.getDataType(value.getDataTypeId());
-				if (dataTypeExtended == null) {
-					logger.error("Failed to determine datatype");
-					return null;
-				}
-				//
-				// Create the attribute value
-				//
-				try {
-					AttributeValue<?> attributeValue = dataTypeExtended.createAttributeValue(fields.get(field));					
-					//
-					// Create the attribute
-					//
-					StdMutableAttribute newAttribute = new StdMutableAttribute(attribute.getCategory(),
-																				attribute.getAttributeId(),
-																				attributeValue,
-																				attribute.getIssuer(),
-																				attribute.getIncludeInResults());
-					boolean added = false;
-					for (StdMutableRequestAttributes a : attributes) {
-						//
-						// Does the category exist?
-						//
-						if (a.getCategory().equals(attribute.getCategory())) {
-							//
-							// Yes - add in the new attribute value
-							//
-							a.add(newAttribute);
-							added = true;
-							break;
-						}
-					}
-					if (added == false) {
-						//
-						// New category - create it and add it in
-						//
-						StdMutableRequestAttributes a = new StdMutableRequestAttributes(); 
-						a.setCategory(newAttribute.getCategory());
-						a.add(newAttribute);
-						attributes.add(a);
-					}
-				} catch (DataTypeException e) {
-					logger.error(e);
-					return null;
-				}
-			}
-		}
-		//
-		// Now form our final request
-		//
-		StdMutableRequest newRequest = new StdMutableRequest();
-		newRequest.setCombinedDecision(request.getCombinedDecision());
-		newRequest.setRequestDefaults(request.getRequestDefaults());
-		newRequest.setReturnPolicyIdList(request.getReturnPolicyIdList());
-		newRequest.setStatus(request.getStatus());
-		for (StdMutableRequestAttributes a : attributes) {
-			newRequest.add(a);
-		}
-		return newRequest;
-	}
-
-	/**
-	 * This makes an HTTP POST call to a running PDP RESTful servlet to get a decision.
-	 * 
-	 * @param file
-	 * @return
-	 */
-	protected Response callRESTfulPDP(InputStream is) {
-		Response response = null;
-		HttpURLConnection connection = null;
-		try {
-
-			//
-			// Open up the connection
-			//
-			connection = (HttpURLConnection) this.restURL.openConnection();
-			connection.setRequestProperty("Content-Type", "application/json");
-			//
-			// Setup our method and headers
-			//
-            connection.setRequestMethod("POST");
-            connection.setUseCaches(false);
-            //
-            // Adding this in. It seems the HttpUrlConnection class does NOT
-            // properly forward our headers for POST re-direction. It does so
-            // for a GET re-direction.
-            //
-            // So we need to handle this ourselves.
-            //
-            connection.setInstanceFollowRedirects(false);
-			connection.setDoOutput(true);
-			connection.setDoInput(true);
-			//
-			// Send the request
-			//
-			try (OutputStream os = connection.getOutputStream()) {
-				IOUtils.copy(is, os);
-			}
-            //
-            // Do the connect
-            //
-            connection.connect();
-            if (connection.getResponseCode() == 200) {
-            	//
-            	// Read the response
-            	//
-        		ContentType contentType = null;
-        		try {
-        			contentType = ContentType.parse(connection.getContentType());
-        			
-        			if (contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_JSON.getMimeType())) {
-                		response = JSONResponse.load(connection.getInputStream());
-        			} else if (contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_XML.getMimeType()) ||
-        					contentType.getMimeType().equalsIgnoreCase("application/xacml+xml") ) {
-                		response = DOMResponse.load(connection.getInputStream());
-        			} else {
-                		logger.error("unknown content-type: " + contentType);
-                	}
-
-                } catch (Exception e) {
-        			String message = "Parsing Content-Type: " + connection.getContentType() + ", error=" + e.getMessage();
-        			logger.error(message, e);
-        		}
-
-            } else {
-            	logger.error(connection.getResponseCode() + " " + connection.getResponseMessage());
-            }
-		} catch (Exception e) {
-			logger.error(e);
-		}
-		
-		return response;
-	}
-	
-	/**
-	 * This processes a response. Saves the response out to disk. If there is a corresponding response file for the request located
-	 * in the "responses" sub-directory, then this method will compare that response file with what the engine returned to see if it
-	 * matched.
-	 * 
-	 * @param requestFile
-	 * @param request
-	 * @param response
-	 * @param group
-	 * @param count
-	 * @throws Exception
-	 */
-	protected void processResponse(Path requestFile, Request request, Response response, String group, int count) throws Exception {
-		//
-		// Construct the output filename
-		//
-		Path responseFile = null;
-		Path resultFile = null;
-		int num = requestFile.getNameCount();
-		if (num < 2) {
-			logger.error("Too few dir's in request filename.");
-			throw new Exception("Too few dir's in request filename. Format should be Request.[0-9]+.{Permit|Deny|NA|Indeterminate}.{json|xml}");
-		}
-		String filename = requestFile.getFileName().toString();
-		if (group.equals("Generate")) {
-			//
-			// Using count variable, construct a filename
-			//
-			//		i.e. Response.03.Generate.{count}.json
-			//
-			filename = "Response" + filename.substring(filename.indexOf('.'), filename.lastIndexOf('.')) + String.format("%03d", count) + filename.substring(filename.lastIndexOf('.'));
-		} else {
-			//
-			// Construct filename
-			//
-			filename = "Response" + filename.substring(filename.indexOf('.'));
-		}
-		//
-		// Determine equivalent response file path
-		//
-		responseFile = Paths.get(requestFile.subpath(0, num - 2).toString(), "responses");
-		if (Files.notExists(responseFile)) {
-			//
-			// Create it
-			//
-			logger.warn(responseFile.toString() + " does NOT exist, creating...");
-			try {
-				Files.createDirectories(responseFile);
-			} catch (IOException e) {
-				logger.error(e);
-				throw new Exception("Cannot proceed without an output directory.");
-			}
-		}
-		responseFile = Paths.get(responseFile.toString(), filename);
-		//
-		// Determine path to write result file
-		//
-		if (this.output != null) {
-			//
-			// User specified an output path
-			//
-			resultFile = this.output;
-		} else {
-			//
-			// Default path
-			//
-			resultFile = Paths.get(requestFile.subpath(0, num - 2).toString(), "results");
-		}
-		//
-		// Check if the path exists
-		//
-		if (Files.notExists(resultFile)) {
-			//
-			// Create it
-			//
-			logger.warn(resultFile.toString() + " does NOT exist, creating...");
-			try {
-				Files.createDirectories(resultFile);
-			} catch (IOException e) {
-				logger.error(e);
-				throw new Exception("Cannot proceed without an output directory.");
-			}
-		}
-		//
-		// Add the filename to the path
-		//
-		resultFile = Paths.get(resultFile.toString(), filename);
-		//
-		// Check if there is an equivalent response in the response
-		// directory. If so, compare our response result with that one.
-		//
-		boolean succeeded = true;
-		if (responseFile != null && Files.exists(responseFile)) {
-			//
-			// Do comparison
-			//
-			Response expectedResponse = null;
-			if (TestBase.isJSON(responseFile)) {
-				expectedResponse = JSONResponse.load(responseFile);
-			} else if (TestBase.isXML(responseFile)) {
-				expectedResponse = DOMResponse.load(responseFile);
-			}
-			if (expectedResponse != null) {
-				//
-				// Do the compare
-				//
-				if (response == null) {
-					logger.error("NULL response returned.");
-					this.responseNotMatches++;
-					succeeded = false;
-				} else {
-					if (response.equals(expectedResponse)) {
-						logger.info("Response matches expected response.");
-						this.responseMatches++;
-					} else {
-						logger.error("Response does not match expected response.");
-						logger.error("Expected: ");
-						logger.error(expectedResponse.toString());
-						this.responseNotMatches++;
-						succeeded = false;
-					}
-				}
-			}
-		}
-		//
-		// Write the response to the result file
-		//
-		logger.info("Request: " + requestFile.getFileName() + " response is: " + (response == null ? "null" : response.toString()));
-		if (resultFile != null && response != null) {
-			if (TestBase.isJSON(resultFile)) {
-				Files.write(resultFile, JSONResponse.toString(response, true).getBytes());
-			} else if (TestBase.isXML(resultFile)) {
-				Files.write(resultFile, DOMResponse.toString(response, true).getBytes());
-			}
-		}
-		//
-		// Stats
-		//		
-		if (group.equals("Permit")) {
-			this.expectedPermits++;
-		} else if (group.equals("Deny")) {
-			this.expectedDenies++;
-		} else if (group.equals("NA")) {
-			this.expectedNotApplicables++;
-		} else if (group.equals("Indeterminate")) {
-			this.expectedIndeterminates++;
-		}
-		if (response != null) {
-			for (Result result : response.getResults()) {
-				Decision decision = result.getDecision();
-				if (group.equals("Generate")) {
-					if (decision.equals(Decision.PERMIT)) {
-						this.generatedpermits++;
-					} else if (decision.equals(Decision.DENY)) {
-						this.generateddenies++;
-					} else if (decision.equals(Decision.NOTAPPLICABLE)) {
-						this.generatednotapplicables++;
-					} else if (decision.equals(Decision.INDETERMINATE)) {
-						this.generatedindeterminates++;
-					}
-					continue;
-				}
-				if (decision.equals(Decision.PERMIT)) {
-					this.permits++;
-					if (group.equals("Permit") == false) {
-						succeeded = false;
-						logger.error("Expected " + group + " got " + decision);
-					}
-				} else if (decision.equals(Decision.DENY)) {
-					this.denies++;
-					if (group.equals("Deny") == false) {
-						succeeded = false;
-						logger.error("Expected " + group + " got " + decision);
-					}
-				} else if (decision.equals(Decision.NOTAPPLICABLE)) {
-					this.notapplicables++;
-					if (group.equals("NA") == false) {
-						succeeded = false;
-						logger.error("Expected " + group + " got " + decision);
-					}
-				} else if (decision.equals(Decision.INDETERMINATE)) {
-					this.indeterminates++;
-					if (group.equals("Indeterminate") == false) {
-						succeeded = false;
-						logger.error("Expected " + group + " got " + decision);
-					}
-				}
-			}
-		}
-		if (succeeded) {
-			logger.info("REQUEST SUCCEEDED");
-		} else {
-			logger.info("REQUEST FAILED");
-		}
-	}
-
-	protected void	dumpStats() {
-		StringBuilder dump = new StringBuilder();
-		dump.append(System.lineSeparator());
-		dump.append("Permits: " + this.permits + " Expected: " + this.expectedPermits);
-		dump.append(System.lineSeparator());
-		dump.append("Denies: " + this.denies + " Expected: " + this.expectedDenies);
-		dump.append(System.lineSeparator());
-		dump.append("NA: " + this.notapplicables + " Expected: " + this.expectedNotApplicables);
-		dump.append(System.lineSeparator());
-		dump.append("Indeterminates: " + this.indeterminates + " Expected: " + this.expectedIndeterminates);
-		dump.append(System.lineSeparator());
-		dump.append("Generated Permits: " + this.generatedpermits);
-		dump.append(System.lineSeparator());
-		dump.append("Generated Denies: " + this.generateddenies);
-		dump.append(System.lineSeparator());
-		dump.append("Generated NA: " + this.generatednotapplicables);
-		dump.append(System.lineSeparator());
-		dump.append("Generated Indeterminates: " + this.generatedindeterminates);
-		dump.append(System.lineSeparator());
-		dump.append("Responses Matched: " + this.responseMatches);
-		dump.append(System.lineSeparator());
-		dump.append("Responses NOT Matched: " + this.responseNotMatches);
-		
-		if (this.permits != this.expectedPermits ||
-			this.denies != this.expectedDenies ||
-			this.notapplicables != this.expectedNotApplicables ||
-			this.indeterminates != this.expectedIndeterminates ||
-			this.responseNotMatches > 0) {
-			logger.error(dump.toString());
-		} else {
-			logger.info(dump.toString());
-		}
-	}
-	
-	protected void	resetStats() {
-		this.permits = 0;
-		this.denies = 0;
-		this.notapplicables = 0;
-		this.indeterminates = 0;
-		this.generatedpermits = 0;
-		this.generateddenies = 0;
-		this.generatednotapplicables = 0;
-		this.generatedindeterminates = 0;
-		this.responseMatches = 0;
-		this.responseNotMatches = 0;
-	}
-
-	public static void main(String[] args) {
-		try {
-			new TestBase(args).run();
-		} catch (ParseException | IOException | FactoryException e) {
-			logger.error(e);
-		} catch (HelpException e) {
-		}		
-	}
-}
diff --git a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/custom/TestCustom.java b/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/custom/TestCustom.java
deleted file mode 100644
index e7a0388..0000000
--- a/ONAP-PDP/src/test/java/org/onap/policy/pdp/test/custom/TestCustom.java
+++ /dev/null
@@ -1,392 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * ONAP-PDP
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.policy.pdp.test.custom;
-
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.net.MalformedURLException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.security.InvalidKeyException;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.NoSuchPaddingException;
-
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.GnuParser;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.ParseException;
-import org.onap.policy.common.logging.flexlogger.FlexLogger;
-import org.onap.policy.common.logging.flexlogger.Logger;
-
-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.Request;
-import com.att.research.xacml.api.RequestAttributes;
-import com.att.research.xacml.api.XACML3;
-import com.att.research.xacml.api.pep.PEPException;
-import com.att.research.xacml.std.IdentifierImpl;
-import com.att.research.xacml.std.StdMutableAttribute;
-import com.att.research.xacml.std.StdMutableRequest;
-import com.att.research.xacml.std.StdMutableRequestAttributes;
-import com.att.research.xacml.std.dom.DOMStructureException;
-import com.att.research.xacml.std.json.JSONStructureException;
-import com.att.research.xacml.util.FactoryException; 
-
-/**
- * TestCustom is an application that tests the extensibility and configurability of the AT&T XACML API.
- * 
- * It creates a custom datatype definition factory that adds in custom data types for RSA
- * PublicKey and PrivateKey.
- * 
- * It creates a custom function definition factory that adds in custom decryption function for decrypting data. It
- * also derives and loads custom functions for the RSA public/private key datatypes for the bag function: one-and-only. 
- * 
- *
- */
-public class TestCustom extends TestBase {
-	private static final Logger logger	= FlexLogger.getLogger(TestCustom.class);
-	
-	//
-	// Our public's
-	//
-	public static final String ALGORITHM = "RSA";
-	public static final String PRIVATEKEY_FILE = "PrivateKey.key";
-	public static final String PUBLICKEY_FILE = "PublicKey.key";
-	
-	public static final String DECRYPTION_INPUT_STRING = "This is the SECRET value!";
-	
-	public static final String DECRYPTION_INPUT_ID = "com:att:research:xacml:test:custom:encrypted-data";
-	//
-	// Our keys
-	//
-	protected PublicKey publicKey = null;
-	protected PrivateKey privateKey = null;
-	//
-	// Our command line parameters
-	//
-	public static final String OPTION_GENERATE = "generate";
-
-	static {
-		options.addOption(new Option(OPTION_GENERATE, false, "Generate a private/public key pair."));
-	}
-	
-	/**
-	 * This function generates the public/private key pair. Should never have to call this again, this was
-	 * called once to generate the keys. They were saved into the testsets/custom/datatype-function sub-directory.
-	 */
-	public void generateKeyPair() {
-		//
-		// Generate a RSA private/public key pair
-		//
-		KeyPairGenerator keyGen;
-		try {
-			keyGen = KeyPairGenerator.getInstance(ALGORITHM);
-		} catch (NoSuchAlgorithmException e) {
-			logger.error("failed to generate keypair: " + e);
-			return;
-		}
-		keyGen.initialize(1024);
-		final KeyPair key = keyGen.generateKeyPair();
-		//
-		// Save the keys to disk
-		//
-		Path file = Paths.get(this.directory, PRIVATEKEY_FILE);
-		try (ObjectOutputStream os = new ObjectOutputStream(Files.newOutputStream(file))) {
-			os.writeObject(key.getPrivate());
-		} catch (IOException e) {
-			logger.error("Exception Occured"+e);
-		}
-		file = Paths.get(this.directory, PUBLICKEY_FILE);
-		try (ObjectOutputStream os = new ObjectOutputStream(Files.newOutputStream(file))) {
-			os.writeObject(key.getPublic());
-		} catch (IOException e) {
-			logger.error("Exception Occured"+e);
-		}
-	}
-
-	public TestCustom(String[] args) throws ParseException, MalformedURLException, HelpException {
-		super(args);
-	}
-	
-	/* (non-Javadoc)
-	 * 
-	 * Simply look for command line option: -generate
-	 * This generates the public/private key. Shouldn't need to call it again, the keys have
-	 * already been generated and saved.
-	 * 
-	 * @see org.onap.policy.pdp.test.TestBase#parseCommands(java.lang.String[])
-	 */
-	@Override
-	protected void parseCommands(String[] args) throws ParseException, MalformedURLException, HelpException {
-		//
-		// Have our parent class parse its options out
-		//
-		super.parseCommands(args);
-		//
-		// Parse the command line options
-		//
-		CommandLine cl;
-		cl = new GnuParser().parse(options, args);
-		if (cl.hasOption(OPTION_GENERATE)) {
-			//
-			// Really only need to do this once to setup the test.
-			//
-			this.generateKeyPair();
-		}
-	}
-
-	/* (non-Javadoc)
-	 * 
-	 * After our parent class configure's itself, all this needs to do is read in
-	 * the public/private key's into objects.
-	 * 
-	 * @see org.onap.policy.pdp.test.TestBase#configure()
-	 */
-	@Override
-	protected void configure() throws FactoryException {
-		//
-		// Have our super do its thing
-		//
-		super.configure();
-		//
-		// Read in the public key
-		//
-		try {
-			this.publicKey = (PublicKey) new ObjectInputStream(Files.newInputStream(Paths.get(this.directory, PUBLICKEY_FILE))).readObject();
-		} catch (ClassNotFoundException | IOException e) {
-			logger.error(e);
-		}
-		//
-		// Read in the private key
-		//
-		try {
-			this.privateKey = (PrivateKey) new ObjectInputStream(Files.newInputStream(Paths.get(this.directory, PRIVATEKEY_FILE))).readObject();
-		} catch (ClassNotFoundException | IOException e) {
-			logger.error(e);
-		}
-	}
-
-	/* (non-Javadoc)
-	 * 
-	 * Here we add 2 attributes into the request: 1) the private key, and 2) a String that was encrypted using the public key.
-	 * 
-	 * The goal is to have the custom decrypt function use the private key to decrypt that string.
-	 * 
-	 * @see org.onap.policy.pdp.test.TestBase#generateRequest(java.nio.file.Path, java.lang.String)
-	 */
-	@Override
-	protected Request generateRequest(Path file, String group) throws JSONStructureException, DOMStructureException, PEPException {
-		//
-		// Have our super class do its work
-		//
-		Request oldRequest = super.generateRequest(file, group);
-		//
-		// Copy the request attributes
-		//
-		List<StdMutableRequestAttributes> attributes = new ArrayList<>();
-		for (RequestAttributes a : oldRequest.getRequestAttributes()) {
-			attributes.add(new StdMutableRequestAttributes(a));
-		}
-		//
-		// We are supplying the private key as an attribute for the decryption function to use:
-		//
-		// (NOTE: Ideally this would be provided by a custom PIP provider, not the PEP)
-		//
-		// ID=com:att:research:xacml:test:custom:privatekey
-		// Issuer=com:att:research:xacml:test:custom
-		// Category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
-		// Datatype=urn:com:att:research:xacml:custom:3.0:rsa:private
-		//
-		DataType<?> dtExtended = dataTypeFactory.getDataType(DataTypePrivateKey.DT_PRIVATEKEY);
-		if (dtExtended == null) {
-			logger.error("Failed to get private key datatype.");
-			return null;
-		}
-		//
-		// Create the attribute value
-		//
-		try {
-			AttributeValue<?> attributeValue = dtExtended.createAttributeValue(this.privateKey);					
-			//
-			// Create the attribute
-			//
-			StdMutableAttribute newAttribute = new StdMutableAttribute(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT,
-																		new IdentifierImpl("com:att:research:xacml:test:custom:privatekey"),
-																		attributeValue,
-																		"com:att:research:xacml:test:custom",
-																		false);
-			boolean added = false;
-			for (StdMutableRequestAttributes a : attributes) {
-				//
-				// Does the category exist?
-				//
-				if (a.getCategory().equals(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT)) {
-					//
-					// Yes - add in the new attribute value
-					//
-					a.add(newAttribute);
-					added = true;
-					break;
-				}
-			}
-			if (added == false) {
-				//
-				// New category - create it and add it in
-				//
-				StdMutableRequestAttributes a = new StdMutableRequestAttributes(); 
-				a.setCategory(newAttribute.getCategory());
-				a.add(newAttribute);
-				attributes.add(a);
-			}
-		} catch (DataTypeException e) {
-			logger.error(e);
-			return null;
-		}
-		//
-		// We are also supplying this attribute which is the secret text encrypted with
-		// the public key.
-		//
-		// ID=com:att:research:xacml:test:custom:encrypted-data
-		// Issuer=
-		// Category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
-		// Datatype=http://www.w3.org/2001/XMLSchema#hexBinary
-		//
-		// Encrypt it
-		//
-		byte[] encryptedData = null;
-		try {
-			Cipher cipher = Cipher.getInstance(ALGORITHM);
-			cipher.init(Cipher.ENCRYPT_MODE, this.publicKey);
-			//
-			// This is just a hack to test a decryption of the wrong value.
-			//
-			if (group.equals("Permit")) {
-				encryptedData = cipher.doFinal(DECRYPTION_INPUT_STRING.getBytes());
-			} else {
-				encryptedData = cipher.doFinal("This is NOT the secret".getBytes());
-			}
-		} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
-			logger.error(e);
-			return null;
-		}
-		//
-		// Sanity check (for the Permit request)
-		//
-		try {
-			if (group.equals("Permit")) {
-				Cipher cipher = Cipher.getInstance(ALGORITHM);
-				cipher.init(Cipher.DECRYPT_MODE, this.privateKey);
-				byte[] decryptedData = cipher.doFinal(encryptedData);
-				if (new String(decryptedData).equals(DECRYPTION_INPUT_STRING)) {
-					logger.info("Sanity check passed: decrypted the encrypted data.");
-				} else {
-					logger.error("Sanity check failed to decrypt the encrypted data.");
-					return null;
-				}
-			}
-		} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
-			logger.error(e);
-		}
-		//
-		// Get our datatype factory
-		//
-		dtExtended = dataTypeFactory.getDataType(XACML3.ID_DATATYPE_HEXBINARY);
-		if (dtExtended == null) {
-			logger.error("Failed to get hex binary datatype.");
-			return null;
-		}
-		//
-		// Create the attribute value
-		//
-		try {
-			AttributeValue<?> attributeValue = dtExtended.createAttributeValue(encryptedData);					
-			//
-			// Create the attribute
-			//
-			StdMutableAttribute newAttribute = new StdMutableAttribute(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT,
-																		new IdentifierImpl("com:att:research:xacml:test:custom:encrypted-data"),
-																		attributeValue,
-																		null,
-																		false);
-			boolean added = false;
-			for (StdMutableRequestAttributes a : attributes) {
-				//
-				// Does the category exist?
-				//
-				if (a.getCategory().equals(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT)) {
-					//
-					// Yes - add in the new attribute value
-					//
-					a.add(newAttribute);
-					added = true;
-					break;
-				}
-			}
-			if (added == false) {
-				//
-				// New category - create it and add it in
-				//
-				StdMutableRequestAttributes a = new StdMutableRequestAttributes(); 
-				a.setCategory(newAttribute.getCategory());
-				a.add(newAttribute);
-				attributes.add(a);
-			}
-		} catch (DataTypeException e) {
-			logger.error(e);
-			return null;
-		}
-		//
-		// Now form our final request
-		//
-		StdMutableRequest newRequest = new StdMutableRequest();
-		newRequest.setCombinedDecision(oldRequest.getCombinedDecision());
-		newRequest.setRequestDefaults(oldRequest.getRequestDefaults());
-		newRequest.setReturnPolicyIdList(oldRequest.getReturnPolicyIdList());
-		newRequest.setStatus(oldRequest.getStatus());
-		for (StdMutableRequestAttributes a : attributes) {
-			newRequest.add(a);
-		}
-		return newRequest;
-	}
-
-	public static void main(String[] args) {
-		try {
-			new TestCustom(args).run();
-		} catch (ParseException | IOException | FactoryException e) {
-			logger.error(e);
-		} catch (HelpException e) {
-		}		
-	}
-
-}
diff --git a/ONAP-PDP/src/test/java/org/onap/policy/xacml/action/FindActionTest.java b/ONAP-PDP/src/test/java/org/onap/policy/xacml/action/FindActionTest.java
new file mode 100644
index 0000000..e594286
--- /dev/null
+++ b/ONAP-PDP/src/test/java/org/onap/policy/xacml/action/FindActionTest.java
@@ -0,0 +1,136 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP-PDP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.policy.xacml.action;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.policy.xacml.custom.OnapFunctionDefinitionFactory;
+
+import com.att.research.xacml.api.Decision;
+import com.att.research.xacml.api.Request;
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.StdAttributeValue;
+import com.att.research.xacml.std.StdMutableAdvice;
+import com.att.research.xacml.std.StdMutableAttributeAssignment;
+import com.att.research.xacml.std.StdMutableMissingAttributeDetail;
+import com.att.research.xacml.std.StdMutableObligation;
+import com.att.research.xacml.std.StdMutableResponse;
+import com.att.research.xacml.std.StdMutableResult;
+import com.att.research.xacml.std.StdMutableStatus;
+import com.att.research.xacml.std.StdMutableStatusDetail;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.datatypes.DataTypes;
+import com.att.research.xacml.std.json.JSONRequest;
+
+
+public class FindActionTest {
+	
+	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\" " +
+				            "} " +
+				        "} " +
+					"] " +
+				"} " +
+			"} " +
+		"} ";
+	
+	String jsonResponse;
+	
+	Request request;
+	
+	@Before
+	public void setUp() throws Exception {
+		new OnapFunctionDefinitionFactory();
+		request = JSONRequest.load(xPathExampleFromSpec);
+	}
+
+	@Test
+	public final void testRun() {
+		FindAction action = new FindAction();
+		// 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(), "PEPACTION"));
+		mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_INTEGER.getId(), "PDPACTION"));
+		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(), "Test")));
+		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(), "Test")));
+		response.add(result);
+		try {
+			assertTrue(action.run(response, request) != null);
+		} catch (Exception e) {
+			fail("operation failed, e="+e);
+		}
+	}
+
+}
diff --git a/ONAP-PDP/src/test/java/org/onap/policy/xacml/pdp/ONAPPDPEngineFactoryTest.java b/ONAP-PDP/src/test/java/org/onap/policy/xacml/pdp/ONAPPDPEngineFactoryTest.java
new file mode 100644
index 0000000..0c9d246
--- /dev/null
+++ b/ONAP-PDP/src/test/java/org/onap/policy/xacml/pdp/ONAPPDPEngineFactoryTest.java
@@ -0,0 +1,52 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP-PDP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.policy.xacml.pdp;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.Properties;
+
+import org.junit.Test;
+
+public class ONAPPDPEngineFactoryTest {
+
+	@Test
+	public final void testNewEngine() {
+		ONAPPDPEngineFactory pdpEngine = new ONAPPDPEngineFactory();
+		try{
+			assertTrue(pdpEngine.newEngine() != null);
+		}catch (Exception e) {
+			fail("operation failed, e="+e);
+		}
+
+	}
+
+	@Test
+	public final void testNewEngineProperties() {
+		ONAPPDPEngineFactory pdpEngine = new ONAPPDPEngineFactory();
+		Properties properties = new Properties();
+		try{
+			assertTrue(pdpEngine.newEngine(properties) != null);
+		}catch (Exception e) {
+			fail("operation failed, e="+e);
+		}
+	}
+}
diff --git a/ONAP-PDP/src/test/java/org/onap/policy/xacml/pdp/std/functions/PolicyListTest.java b/ONAP-PDP/src/test/java/org/onap/policy/xacml/pdp/std/functions/PolicyListTest.java
new file mode 100644
index 0000000..17f509d
--- /dev/null
+++ b/ONAP-PDP/src/test/java/org/onap/policy/xacml/pdp/std/functions/PolicyListTest.java
@@ -0,0 +1,63 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP-PDP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.policy.xacml.pdp.std.functions;
+
+import static org.junit.Assert.*;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class PolicyListTest {
+
+	@Before
+	public void setUp() throws Exception {
+		PolicyList.addPolicyID("Test");
+	}
+
+	@Test
+	public final void testGetpolicyList() {
+		try{
+			assertTrue(PolicyList.getpolicyList().size() ==1);
+		}catch(Exception e){
+			fail("operation failed, e="+e);
+		}
+	}
+
+	@Test
+	public final void testAddPolicyID() {
+		try{
+			PolicyList.addPolicyID("Test");
+			assertTrue(PolicyList.getpolicyList().size() == 1);
+		}catch(Exception e){
+			fail("operation failed, e="+e);
+		}
+	}
+
+	@Test
+	public final void testClearPolicyList() {
+		try{
+			PolicyList.clearPolicyList();
+			assertTrue(PolicyList.getpolicyList().size() == 0);
+		}catch(Exception e){
+			fail("operation failed, e="+e);
+		}
+	}
+
+}
diff --git a/ONAP-SDK-APP/pom.xml b/ONAP-SDK-APP/pom.xml
index aae25fa..e6ef8ed 100644
--- a/ONAP-SDK-APP/pom.xml
+++ b/ONAP-SDK-APP/pom.xml
@@ -38,6 +38,7 @@
 		<skipassembly>true</skipassembly>
 		<!-- Tests usually require some setup that maven cannot do, so skip. -->
 		<jackson.version>2.6.0</jackson.version>
+ 	    <sonar.exclusions>**/gen/**,**/generated-sources/**,**/yang-gen**,**/pax/**,src/main/webapp/**/*</sonar.exclusions>
 	</properties>
 	<profiles>
 		<!-- disable doclint, a new feature in Java 8, when generating javadoc -->
diff --git a/ONAP-SDK-APP/src/main/webapp/static/fusion/sample/js/jquery.flexslider-min.js b/ONAP-SDK-APP/src/main/webapp/static/fusion/sample/js/jquery.flexslider-min.js
deleted file mode 100644
index 5ad6c37..0000000
--- a/ONAP-SDK-APP/src/main/webapp/static/fusion/sample/js/jquery.flexslider-min.js
+++ /dev/null
@@ -1,5 +0,0 @@
-/*
- * jQuery FlexSlider v2.6.0
- * Copyright 2012 WooThemes
- * Contributing Author: Tyler Smith
- */!function($){var e=!0;$.flexslider=function(t,a){var n=$(t);n.vars=$.extend({},$.flexslider.defaults,a);var i=n.vars.namespace,s=window.navigator&&window.navigator.msPointerEnabled&&window.MSGesture,r=("ontouchstart"in window||s||window.DocumentTouch&&document instanceof DocumentTouch)&&n.vars.touch,o="click touchend MSPointerUp keyup",l="",c,d="vertical"===n.vars.direction,u=n.vars.reverse,v=n.vars.itemWidth>0,p="fade"===n.vars.animation,m=""!==n.vars.asNavFor,f={};$.data(t,"flexslider",n),f={init:function(){n.animating=!1,n.currentSlide=parseInt(n.vars.startAt?n.vars.startAt:0,10),isNaN(n.currentSlide)&&(n.currentSlide=0),n.animatingTo=n.currentSlide,n.atEnd=0===n.currentSlide||n.currentSlide===n.last,n.containerSelector=n.vars.selector.substr(0,n.vars.selector.search(" ")),n.slides=$(n.vars.selector,n),n.container=$(n.containerSelector,n),n.count=n.slides.length,n.syncExists=$(n.vars.sync).length>0,"slide"===n.vars.animation&&(n.vars.animation="swing"),n.prop=d?"top":"marginLeft",n.args={},n.manualPause=!1,n.stopped=!1,n.started=!1,n.startTimeout=null,n.transitions=!n.vars.video&&!p&&n.vars.useCSS&&function(){var e=document.createElement("div"),t=["perspectiveProperty","WebkitPerspective","MozPerspective","OPerspective","msPerspective"];for(var a in t)if(void 0!==e.style[t[a]])return n.pfx=t[a].replace("Perspective","").toLowerCase(),n.prop="-"+n.pfx+"-transform",!0;return!1}(),n.ensureAnimationEnd="",""!==n.vars.controlsContainer&&(n.controlsContainer=$(n.vars.controlsContainer).length>0&&$(n.vars.controlsContainer)),""!==n.vars.manualControls&&(n.manualControls=$(n.vars.manualControls).length>0&&$(n.vars.manualControls)),""!==n.vars.customDirectionNav&&(n.customDirectionNav=2===$(n.vars.customDirectionNav).length&&$(n.vars.customDirectionNav)),n.vars.randomize&&(n.slides.sort(function(){return Math.round(Math.random())-.5}),n.container.empty().append(n.slides)),n.doMath(),n.setup("init"),n.vars.controlNav&&f.controlNav.setup(),n.vars.directionNav&&f.directionNav.setup(),n.vars.keyboard&&(1===$(n.containerSelector).length||n.vars.multipleKeyboard)&&$(document).bind("keyup",function(e){var t=e.keyCode;if(!n.animating&&(39===t||37===t)){var a=39===t?n.getTarget("next"):37===t?n.getTarget("prev"):!1;n.flexAnimate(a,n.vars.pauseOnAction)}}),n.vars.mousewheel&&n.bind("mousewheel",function(e,t,a,i){e.preventDefault();var s=0>t?n.getTarget("next"):n.getTarget("prev");n.flexAnimate(s,n.vars.pauseOnAction)}),n.vars.pausePlay&&f.pausePlay.setup(),n.vars.slideshow&&n.vars.pauseInvisible&&f.pauseInvisible.init(),n.vars.slideshow&&(n.vars.pauseOnHover&&n.hover(function(){n.manualPlay||n.manualPause||n.pause()},function(){n.manualPause||n.manualPlay||n.stopped||n.play()}),n.vars.pauseInvisible&&f.pauseInvisible.isHidden()||(n.vars.initDelay>0?n.startTimeout=setTimeout(n.play,n.vars.initDelay):n.play())),m&&f.asNav.setup(),r&&n.vars.touch&&f.touch(),(!p||p&&n.vars.smoothHeight)&&$(window).bind("resize orientationchange focus",f.resize),n.find("img").attr("draggable","false"),setTimeout(function(){n.vars.start(n)},200)},asNav:{setup:function(){n.asNav=!0,n.animatingTo=Math.floor(n.currentSlide/n.move),n.currentItem=n.currentSlide,n.slides.removeClass(i+"active-slide").eq(n.currentItem).addClass(i+"active-slide"),s?(t._slider=n,n.slides.each(function(){var e=this;e._gesture=new MSGesture,e._gesture.target=e,e.addEventListener("MSPointerDown",function(e){e.preventDefault(),e.currentTarget._gesture&&e.currentTarget._gesture.addPointer(e.pointerId)},!1),e.addEventListener("MSGestureTap",function(e){e.preventDefault();var t=$(this),a=t.index();$(n.vars.asNavFor).data("flexslider").animating||t.hasClass("active")||(n.direction=n.currentItem<a?"next":"prev",n.flexAnimate(a,n.vars.pauseOnAction,!1,!0,!0))})})):n.slides.on(o,function(e){e.preventDefault();var t=$(this),a=t.index(),s=t.offset().left-$(n).scrollLeft();0>=s&&t.hasClass(i+"active-slide")?n.flexAnimate(n.getTarget("prev"),!0):$(n.vars.asNavFor).data("flexslider").animating||t.hasClass(i+"active-slide")||(n.direction=n.currentItem<a?"next":"prev",n.flexAnimate(a,n.vars.pauseOnAction,!1,!0,!0))})}},controlNav:{setup:function(){n.manualControls?f.controlNav.setupManual():f.controlNav.setupPaging()},setupPaging:function(){var e="thumbnails"===n.vars.controlNav?"control-thumbs":"control-paging",t=1,a,s;if(n.controlNavScaffold=$('<ol class="'+i+"control-nav "+i+e+'"></ol>'),n.pagingCount>1)for(var r=0;r<n.pagingCount;r++){if(s=n.slides.eq(r),void 0===s.attr("data-thumb-alt")&&s.attr("data-thumb-alt",""),altText=""!==s.attr("data-thumb-alt")?altText=' alt="'+s.attr("data-thumb-alt")+'"':"",a="thumbnails"===n.vars.controlNav?'<img src="'+s.attr("data-thumb")+'"'+altText+"/>":'<a href="#">'+t+"</a>","thumbnails"===n.vars.controlNav&&!0===n.vars.thumbCaptions){var c=s.attr("data-thumbcaption");""!==c&&void 0!==c&&(a+='<span class="'+i+'caption">'+c+"</span>")}n.controlNavScaffold.append("<li>"+a+"</li>"),t++}n.controlsContainer?$(n.controlsContainer).append(n.controlNavScaffold):n.append(n.controlNavScaffold),f.controlNav.set(),f.controlNav.active(),n.controlNavScaffold.delegate("a, img",o,function(e){if(e.preventDefault(),""===l||l===e.type){var t=$(this),a=n.controlNav.index(t);t.hasClass(i+"active")||(n.direction=a>n.currentSlide?"next":"prev",n.flexAnimate(a,n.vars.pauseOnAction))}""===l&&(l=e.type),f.setToClearWatchedEvent()})},setupManual:function(){n.controlNav=n.manualControls,f.controlNav.active(),n.controlNav.bind(o,function(e){if(e.preventDefault(),""===l||l===e.type){var t=$(this),a=n.controlNav.index(t);t.hasClass(i+"active")||(a>n.currentSlide?n.direction="next":n.direction="prev",n.flexAnimate(a,n.vars.pauseOnAction))}""===l&&(l=e.type),f.setToClearWatchedEvent()})},set:function(){var e="thumbnails"===n.vars.controlNav?"img":"a";n.controlNav=$("."+i+"control-nav li "+e,n.controlsContainer?n.controlsContainer:n)},active:function(){n.controlNav.removeClass(i+"active").eq(n.animatingTo).addClass(i+"active")},update:function(e,t){n.pagingCount>1&&"add"===e?n.controlNavScaffold.append($('<li><a href="#">'+n.count+"</a></li>")):1===n.pagingCount?n.controlNavScaffold.find("li").remove():n.controlNav.eq(t).closest("li").remove(),f.controlNav.set(),n.pagingCount>1&&n.pagingCount!==n.controlNav.length?n.update(t,e):f.controlNav.active()}},directionNav:{setup:function(){var e=$('<ul class="'+i+'direction-nav"><li class="'+i+'nav-prev"><a class="'+i+'prev" href="#">'+n.vars.prevText+'</a></li><li class="'+i+'nav-next"><a class="'+i+'next" href="#">'+n.vars.nextText+"</a></li></ul>");n.customDirectionNav?n.directionNav=n.customDirectionNav:n.controlsContainer?($(n.controlsContainer).append(e),n.directionNav=$("."+i+"direction-nav li a",n.controlsContainer)):(n.append(e),n.directionNav=$("."+i+"direction-nav li a",n)),f.directionNav.update(),n.directionNav.bind(o,function(e){e.preventDefault();var t;(""===l||l===e.type)&&(t=$(this).hasClass(i+"next")?n.getTarget("next"):n.getTarget("prev"),n.flexAnimate(t,n.vars.pauseOnAction)),""===l&&(l=e.type),f.setToClearWatchedEvent()})},update:function(){var e=i+"disabled";1===n.pagingCount?n.directionNav.addClass(e).attr("tabindex","-1"):n.vars.animationLoop?n.directionNav.removeClass(e).removeAttr("tabindex"):0===n.animatingTo?n.directionNav.removeClass(e).filter("."+i+"prev").addClass(e).attr("tabindex","-1"):n.animatingTo===n.last?n.directionNav.removeClass(e).filter("."+i+"next").addClass(e).attr("tabindex","-1"):n.directionNav.removeClass(e).removeAttr("tabindex")}},pausePlay:{setup:function(){var e=$('<div class="'+i+'pauseplay"><a href="#"></a></div>');n.controlsContainer?(n.controlsContainer.append(e),n.pausePlay=$("."+i+"pauseplay a",n.controlsContainer)):(n.append(e),n.pausePlay=$("."+i+"pauseplay a",n)),f.pausePlay.update(n.vars.slideshow?i+"pause":i+"play"),n.pausePlay.bind(o,function(e){e.preventDefault(),(""===l||l===e.type)&&($(this).hasClass(i+"pause")?(n.manualPause=!0,n.manualPlay=!1,n.pause()):(n.manualPause=!1,n.manualPlay=!0,n.play())),""===l&&(l=e.type),f.setToClearWatchedEvent()})},update:function(e){"play"===e?n.pausePlay.removeClass(i+"pause").addClass(i+"play").html(n.vars.playText):n.pausePlay.removeClass(i+"play").addClass(i+"pause").html(n.vars.pauseText)}},touch:function(){function e(e){e.stopPropagation(),n.animating?e.preventDefault():(n.pause(),t._gesture.addPointer(e.pointerId),T=0,c=d?n.h:n.w,f=Number(new Date),l=v&&u&&n.animatingTo===n.last?0:v&&u?n.limit-(n.itemW+n.vars.itemMargin)*n.move*n.animatingTo:v&&n.currentSlide===n.last?n.limit:v?(n.itemW+n.vars.itemMargin)*n.move*n.currentSlide:u?(n.last-n.currentSlide+n.cloneOffset)*c:(n.currentSlide+n.cloneOffset)*c)}function a(e){e.stopPropagation();var a=e.target._slider;if(a){var n=-e.translationX,i=-e.translationY;return T+=d?i:n,m=T,x=d?Math.abs(T)<Math.abs(-n):Math.abs(T)<Math.abs(-i),e.detail===e.MSGESTURE_FLAG_INERTIA?void setImmediate(function(){t._gesture.stop()}):void((!x||Number(new Date)-f>500)&&(e.preventDefault(),!p&&a.transitions&&(a.vars.animationLoop||(m=T/(0===a.currentSlide&&0>T||a.currentSlide===a.last&&T>0?Math.abs(T)/c+2:1)),a.setProps(l+m,"setTouch"))))}}function i(e){e.stopPropagation();var t=e.target._slider;if(t){if(t.animatingTo===t.currentSlide&&!x&&null!==m){var a=u?-m:m,n=a>0?t.getTarget("next"):t.getTarget("prev");t.canAdvance(n)&&(Number(new Date)-f<550&&Math.abs(a)>50||Math.abs(a)>c/2)?t.flexAnimate(n,t.vars.pauseOnAction):p||t.flexAnimate(t.currentSlide,t.vars.pauseOnAction,!0)}r=null,o=null,m=null,l=null,T=0}}var r,o,l,c,m,f,g,h,S,x=!1,y=0,b=0,T=0;s?(t.style.msTouchAction="none",t._gesture=new MSGesture,t._gesture.target=t,t.addEventListener("MSPointerDown",e,!1),t._slider=n,t.addEventListener("MSGestureChange",a,!1),t.addEventListener("MSGestureEnd",i,!1)):(g=function(e){n.animating?e.preventDefault():(window.navigator.msPointerEnabled||1===e.touches.length)&&(n.pause(),c=d?n.h:n.w,f=Number(new Date),y=e.touches[0].pageX,b=e.touches[0].pageY,l=v&&u&&n.animatingTo===n.last?0:v&&u?n.limit-(n.itemW+n.vars.itemMargin)*n.move*n.animatingTo:v&&n.currentSlide===n.last?n.limit:v?(n.itemW+n.vars.itemMargin)*n.move*n.currentSlide:u?(n.last-n.currentSlide+n.cloneOffset)*c:(n.currentSlide+n.cloneOffset)*c,r=d?b:y,o=d?y:b,t.addEventListener("touchmove",h,!1),t.addEventListener("touchend",S,!1))},h=function(e){y=e.touches[0].pageX,b=e.touches[0].pageY,m=d?r-b:r-y,x=d?Math.abs(m)<Math.abs(y-o):Math.abs(m)<Math.abs(b-o);var t=500;(!x||Number(new Date)-f>t)&&(e.preventDefault(),!p&&n.transitions&&(n.vars.animationLoop||(m/=0===n.currentSlide&&0>m||n.currentSlide===n.last&&m>0?Math.abs(m)/c+2:1),n.setProps(l+m,"setTouch")))},S=function(e){if(t.removeEventListener("touchmove",h,!1),n.animatingTo===n.currentSlide&&!x&&null!==m){var a=u?-m:m,i=a>0?n.getTarget("next"):n.getTarget("prev");n.canAdvance(i)&&(Number(new Date)-f<550&&Math.abs(a)>50||Math.abs(a)>c/2)?n.flexAnimate(i,n.vars.pauseOnAction):p||n.flexAnimate(n.currentSlide,n.vars.pauseOnAction,!0)}t.removeEventListener("touchend",S,!1),r=null,o=null,m=null,l=null},t.addEventListener("touchstart",g,!1))},resize:function(){!n.animating&&n.is(":visible")&&(v||n.doMath(),p?f.smoothHeight():v?(n.slides.width(n.computedW),n.update(n.pagingCount),n.setProps()):d?(n.viewport.height(n.h),n.setProps(n.h,"setTotal")):(n.vars.smoothHeight&&f.smoothHeight(),n.newSlides.width(n.computedW),n.setProps(n.computedW,"setTotal")))},smoothHeight:function(e){if(!d||p){var t=p?n:n.viewport;e?t.animate({height:n.slides.eq(n.animatingTo).height()},e):t.height(n.slides.eq(n.animatingTo).height())}},sync:function(e){var t=$(n.vars.sync).data("flexslider"),a=n.animatingTo;switch(e){case"animate":t.flexAnimate(a,n.vars.pauseOnAction,!1,!0);break;case"play":t.playing||t.asNav||t.play();break;case"pause":t.pause()}},uniqueID:function(e){return e.filter("[id]").add(e.find("[id]")).each(function(){var e=$(this);e.attr("id",e.attr("id")+"_clone")}),e},pauseInvisible:{visProp:null,init:function(){var e=f.pauseInvisible.getHiddenProp();if(e){var t=e.replace(/[H|h]idden/,"")+"visibilitychange";document.addEventListener(t,function(){f.pauseInvisible.isHidden()?n.startTimeout?clearTimeout(n.startTimeout):n.pause():n.started?n.play():n.vars.initDelay>0?setTimeout(n.play,n.vars.initDelay):n.play()})}},isHidden:function(){var e=f.pauseInvisible.getHiddenProp();return e?document[e]:!1},getHiddenProp:function(){var e=["webkit","moz","ms","o"];if("hidden"in document)return"hidden";for(var t=0;t<e.length;t++)if(e[t]+"Hidden"in document)return e[t]+"Hidden";return null}},setToClearWatchedEvent:function(){clearTimeout(c),c=setTimeout(function(){l=""},3e3)}},n.flexAnimate=function(e,t,a,s,o){if(n.vars.animationLoop||e===n.currentSlide||(n.direction=e>n.currentSlide?"next":"prev"),m&&1===n.pagingCount&&(n.direction=n.currentItem<e?"next":"prev"),!n.animating&&(n.canAdvance(e,o)||a)&&n.is(":visible")){if(m&&s){var l=$(n.vars.asNavFor).data("flexslider");if(n.atEnd=0===e||e===n.count-1,l.flexAnimate(e,!0,!1,!0,o),n.direction=n.currentItem<e?"next":"prev",l.direction=n.direction,Math.ceil((e+1)/n.visible)-1===n.currentSlide||0===e)return n.currentItem=e,n.slides.removeClass(i+"active-slide").eq(e).addClass(i+"active-slide"),!1;n.currentItem=e,n.slides.removeClass(i+"active-slide").eq(e).addClass(i+"active-slide"),e=Math.floor(e/n.visible)}if(n.animating=!0,n.animatingTo=e,t&&n.pause(),n.vars.before(n),n.syncExists&&!o&&f.sync("animate"),n.vars.controlNav&&f.controlNav.active(),v||n.slides.removeClass(i+"active-slide").eq(e).addClass(i+"active-slide"),n.atEnd=0===e||e===n.last,n.vars.directionNav&&f.directionNav.update(),e===n.last&&(n.vars.end(n),n.vars.animationLoop||n.pause()),p)r?(n.slides.eq(n.currentSlide).css({opacity:0,zIndex:1}),n.slides.eq(e).css({opacity:1,zIndex:2}),n.wrapup(c)):(n.slides.eq(n.currentSlide).css({zIndex:1}).animate({opacity:0},n.vars.animationSpeed,n.vars.easing),n.slides.eq(e).css({zIndex:2}).animate({opacity:1},n.vars.animationSpeed,n.vars.easing,n.wrapup));else{var c=d?n.slides.filter(":first").height():n.computedW,g,h,S;v?(g=n.vars.itemMargin,S=(n.itemW+g)*n.move*n.animatingTo,h=S>n.limit&&1!==n.visible?n.limit:S):h=0===n.currentSlide&&e===n.count-1&&n.vars.animationLoop&&"next"!==n.direction?u?(n.count+n.cloneOffset)*c:0:n.currentSlide===n.last&&0===e&&n.vars.animationLoop&&"prev"!==n.direction?u?0:(n.count+1)*c:u?(n.count-1-e+n.cloneOffset)*c:(e+n.cloneOffset)*c,n.setProps(h,"",n.vars.animationSpeed),n.transitions?(n.vars.animationLoop&&n.atEnd||(n.animating=!1,n.currentSlide=n.animatingTo),n.container.unbind("webkitTransitionEnd transitionend"),n.container.bind("webkitTransitionEnd transitionend",function(){clearTimeout(n.ensureAnimationEnd),n.wrapup(c)}),clearTimeout(n.ensureAnimationEnd),n.ensureAnimationEnd=setTimeout(function(){n.wrapup(c)},n.vars.animationSpeed+100)):n.container.animate(n.args,n.vars.animationSpeed,n.vars.easing,function(){n.wrapup(c)})}n.vars.smoothHeight&&f.smoothHeight(n.vars.animationSpeed)}},n.wrapup=function(e){p||v||(0===n.currentSlide&&n.animatingTo===n.last&&n.vars.animationLoop?n.setProps(e,"jumpEnd"):n.currentSlide===n.last&&0===n.animatingTo&&n.vars.animationLoop&&n.setProps(e,"jumpStart")),n.animating=!1,n.currentSlide=n.animatingTo,n.vars.after(n)},n.animateSlides=function(){!n.animating&&e&&n.flexAnimate(n.getTarget("next"))},n.pause=function(){clearInterval(n.animatedSlides),n.animatedSlides=null,n.playing=!1,n.vars.pausePlay&&f.pausePlay.update("play"),n.syncExists&&f.sync("pause")},n.play=function(){n.playing&&clearInterval(n.animatedSlides),n.animatedSlides=n.animatedSlides||setInterval(n.animateSlides,n.vars.slideshowSpeed),n.started=n.playing=!0,n.vars.pausePlay&&f.pausePlay.update("pause"),n.syncExists&&f.sync("play")},n.stop=function(){n.pause(),n.stopped=!0},n.canAdvance=function(e,t){var a=m?n.pagingCount-1:n.last;return t?!0:m&&n.currentItem===n.count-1&&0===e&&"prev"===n.direction?!0:m&&0===n.currentItem&&e===n.pagingCount-1&&"next"!==n.direction?!1:e!==n.currentSlide||m?n.vars.animationLoop?!0:n.atEnd&&0===n.currentSlide&&e===a&&"next"!==n.direction?!1:n.atEnd&&n.currentSlide===a&&0===e&&"next"===n.direction?!1:!0:!1},n.getTarget=function(e){return n.direction=e,"next"===e?n.currentSlide===n.last?0:n.currentSlide+1:0===n.currentSlide?n.last:n.currentSlide-1},n.setProps=function(e,t,a){var i=function(){var a=e?e:(n.itemW+n.vars.itemMargin)*n.move*n.animatingTo,i=function(){if(v)return"setTouch"===t?e:u&&n.animatingTo===n.last?0:u?n.limit-(n.itemW+n.vars.itemMargin)*n.move*n.animatingTo:n.animatingTo===n.last?n.limit:a;switch(t){case"setTotal":return u?(n.count-1-n.currentSlide+n.cloneOffset)*e:(n.currentSlide+n.cloneOffset)*e;case"setTouch":return u?e:e;case"jumpEnd":return u?e:n.count*e;case"jumpStart":return u?n.count*e:e;default:return e}}();return-1*i+"px"}();n.transitions&&(i=d?"translate3d(0,"+i+",0)":"translate3d("+i+",0,0)",a=void 0!==a?a/1e3+"s":"0s",n.container.css("-"+n.pfx+"-transition-duration",a),n.container.css("transition-duration",a)),n.args[n.prop]=i,(n.transitions||void 0===a)&&n.container.css(n.args),n.container.css("transform",i)},n.setup=function(e){if(p)n.slides.css({width:"100%","float":"left",marginRight:"-100%",position:"relative"}),"init"===e&&(r?n.slides.css({opacity:0,display:"block",webkitTransition:"opacity "+n.vars.animationSpeed/1e3+"s ease",zIndex:1}).eq(n.currentSlide).css({opacity:1,zIndex:2}):0==n.vars.fadeFirstSlide?n.slides.css({opacity:0,display:"block",zIndex:1}).eq(n.currentSlide).css({zIndex:2}).css({opacity:1}):n.slides.css({opacity:0,display:"block",zIndex:1}).eq(n.currentSlide).css({zIndex:2}).animate({opacity:1},n.vars.animationSpeed,n.vars.easing)),n.vars.smoothHeight&&f.smoothHeight();else{var t,a;"init"===e&&(n.viewport=$('<div class="'+i+'viewport"></div>').css({overflow:"hidden",position:"relative"}).appendTo(n).append(n.container),n.cloneCount=0,n.cloneOffset=0,u&&(a=$.makeArray(n.slides).reverse(),n.slides=$(a),n.container.empty().append(n.slides))),n.vars.animationLoop&&!v&&(n.cloneCount=2,n.cloneOffset=1,"init"!==e&&n.container.find(".clone").remove(),n.container.append(f.uniqueID(n.slides.first().clone().addClass("clone")).attr("aria-hidden","true")).prepend(f.uniqueID(n.slides.last().clone().addClass("clone")).attr("aria-hidden","true"))),n.newSlides=$(n.vars.selector,n),t=u?n.count-1-n.currentSlide+n.cloneOffset:n.currentSlide+n.cloneOffset,d&&!v?(n.container.height(200*(n.count+n.cloneCount)+"%").css("position","absolute").width("100%"),setTimeout(function(){n.newSlides.css({display:"block"}),n.doMath(),n.viewport.height(n.h),n.setProps(t*n.h,"init")},"init"===e?100:0)):(n.container.width(200*(n.count+n.cloneCount)+"%"),n.setProps(t*n.computedW,"init"),setTimeout(function(){n.doMath(),n.newSlides.css({width:n.computedW,marginRight:n.computedM,"float":"left",display:"block"}),n.vars.smoothHeight&&f.smoothHeight()},"init"===e?100:0))}v||n.slides.removeClass(i+"active-slide").eq(n.currentSlide).addClass(i+"active-slide"),n.vars.init(n)},n.doMath=function(){var e=n.slides.first(),t=n.vars.itemMargin,a=n.vars.minItems,i=n.vars.maxItems;n.w=void 0===n.viewport?n.width():n.viewport.width(),n.h=e.height(),n.boxPadding=e.outerWidth()-e.width(),v?(n.itemT=n.vars.itemWidth+t,n.itemM=t,n.minW=a?a*n.itemT:n.w,n.maxW=i?i*n.itemT-t:n.w,n.itemW=n.minW>n.w?(n.w-t*(a-1))/a:n.maxW<n.w?(n.w-t*(i-1))/i:n.vars.itemWidth>n.w?n.w:n.vars.itemWidth,n.visible=Math.floor(n.w/n.itemW),n.move=n.vars.move>0&&n.vars.move<n.visible?n.vars.move:n.visible,n.pagingCount=Math.ceil((n.count-n.visible)/n.move+1),n.last=n.pagingCount-1,n.limit=1===n.pagingCount?0:n.vars.itemWidth>n.w?n.itemW*(n.count-1)+t*(n.count-1):(n.itemW+t)*n.count-n.w-t):(n.itemW=n.w,n.itemM=t,n.pagingCount=n.count,n.last=n.count-1),n.computedW=n.itemW-n.boxPadding,n.computedM=n.itemM},n.update=function(e,t){n.doMath(),v||(e<n.currentSlide?n.currentSlide+=1:e<=n.currentSlide&&0!==e&&(n.currentSlide-=1),n.animatingTo=n.currentSlide),n.vars.controlNav&&!n.manualControls&&("add"===t&&!v||n.pagingCount>n.controlNav.length?f.controlNav.update("add"):("remove"===t&&!v||n.pagingCount<n.controlNav.length)&&(v&&n.currentSlide>n.last&&(n.currentSlide-=1,n.animatingTo-=1),f.controlNav.update("remove",n.last))),n.vars.directionNav&&f.directionNav.update()},n.addSlide=function(e,t){var a=$(e);n.count+=1,n.last=n.count-1,d&&u?void 0!==t?n.slides.eq(n.count-t).after(a):n.container.prepend(a):void 0!==t?n.slides.eq(t).before(a):n.container.append(a),n.update(t,"add"),n.slides=$(n.vars.selector+":not(.clone)",n),n.setup(),n.vars.added(n)},n.removeSlide=function(e){var t=isNaN(e)?n.slides.index($(e)):e;n.count-=1,n.last=n.count-1,isNaN(e)?$(e,n.slides).remove():d&&u?n.slides.eq(n.last).remove():n.slides.eq(e).remove(),n.doMath(),n.update(t,"remove"),n.slides=$(n.vars.selector+":not(.clone)",n),n.setup(),n.vars.removed(n)},f.init()},$(window).blur(function(t){e=!1}).focus(function(t){e=!0}),$.flexslider.defaults={namespace:"flex-",selector:".slides > li",animation:"fade",easing:"swing",direction:"horizontal",reverse:!1,animationLoop:!0,smoothHeight:!1,startAt:0,slideshow:!0,slideshowSpeed:7e3,animationSpeed:600,initDelay:0,randomize:!1,fadeFirstSlide:!0,thumbCaptions:!1,pauseOnAction:!0,pauseOnHover:!1,pauseInvisible:!0,useCSS:!0,touch:!0,video:!1,controlNav:!0,directionNav:!0,prevText:"Previous",nextText:"Next",keyboard:!0,multipleKeyboard:!1,mousewheel:!1,pausePlay:!1,pauseText:"Pause",playText:"Play",controlsContainer:"",manualControls:"",customDirectionNav:"",sync:"",asNavFor:"",itemWidth:0,itemMargin:0,minItems:1,maxItems:0,move:0,allowOneSlide:!0,start:function(){},before:function(){},after:function(){},end:function(){},added:function(){},removed:function(){},init:function(){}},$.fn.flexslider=function(e){if(void 0===e&&(e={}),"object"==typeof e)return this.each(function(){var t=$(this),a=e.selector?e.selector:".slides > li",n=t.find(a);1===n.length&&e.allowOneSlide===!0||0===n.length?(n.fadeIn(400),e.start&&e.start(t)):void 0===t.data("flexslider")&&new $.flexslider(this,e)});var t=$(this).data("flexslider");switch(e){case"play":t.play();break;case"pause":t.pause();break;case"stop":t.stop();break;case"next":t.flexAnimate(t.getTarget("next"),!0);break;case"prev":case"previous":t.flexAnimate(t.getTarget("prev"),!0);break;default:"number"==typeof e&&t.flexAnimate(e,!0)}}}(jQuery);
\ No newline at end of file
diff --git a/POLICY-SDK-APP/pom.xml b/POLICY-SDK-APP/pom.xml
index c84fbb7..5adb5d1 100644
--- a/POLICY-SDK-APP/pom.xml
+++ b/POLICY-SDK-APP/pom.xml
@@ -55,6 +55,7 @@
 		<skipassembly>true</skipassembly>
 		<skiptests>false</skiptests>
 		<jackson.version>2.6.0</jackson.version>
+ 	    <sonar.exclusions>**/gen/**,**/generated-sources/**,**/yang-gen**,**/pax/**,src/main/webapp/app/policyApp/CSS/**/*,src/main/webapp/app/policyApp/libs/**/*</sonar.exclusions>		
 	</properties>
 	<dependencies>
 		<dependency>
diff --git a/POLICY-SDK-APP/src/main/java/org/onap/policy/admin/PolicyManagerServlet.java b/POLICY-SDK-APP/src/main/java/org/onap/policy/admin/PolicyManagerServlet.java
index a99d23e..4f42023 100644
--- a/POLICY-SDK-APP/src/main/java/org/onap/policy/admin/PolicyManagerServlet.java
+++ b/POLICY-SDK-APP/src/main/java/org/onap/policy/admin/PolicyManagerServlet.java
@@ -91,6 +91,16 @@
 public class PolicyManagerServlet extends HttpServlet {
 	private static final Logger LOGGER	= FlexLogger.getLogger(PolicyManagerServlet.class);
 	private static final long serialVersionUID = -8453502699403909016L;
+	
+	private static boolean jUnit = false;
+
+	public static boolean isjUnit() {
+		return jUnit;
+	}
+
+	public static void setjUnit(boolean jUnit) {
+		PolicyManagerServlet.jUnit = jUnit;
+	}
 
 	private enum Mode {
 		LIST, RENAME, COPY, DELETE, EDITFILE, ADDFOLDER, DESCRIBEPOLICYFILE, VIEWPOLICY, ADDSUBSCOPE, SWITCHVERSION, EXPORT, SEARCHLIST
@@ -531,7 +541,12 @@
 		SimpleBindings peParams = new SimpleBindings();
 		peParams.put("split_1", split[1]);
 		peParams.put("split_0", split[0]);
-		List<Object> queryData = controller.getDataByQuery(query, peParams);
+		List<Object> queryData = null;
+		if(jUnit){
+			queryData = controller.getDataByQuery(query, null);
+		}else{
+			queryData = controller.getDataByQuery(query, peParams);
+		}
 		if(!queryData.isEmpty()){
 			PolicyEntity entity = (PolicyEntity) queryData.get(0);
 			File temp = null;
@@ -668,7 +683,12 @@
 			params.put("scopeName", scopeName + "%");
 		}
 		PolicyController controller = getPolicyControllerInstance();
-		List<Object> scopesList = controller.getDataByQuery(scopeNamequery, params);
+		List<Object> scopesList = null;
+		if(jUnit){
+			scopesList = controller.getDataByQuery(scopeNamequery, null);
+		}else{
+			scopesList = controller.getDataByQuery(scopeNamequery, params);
+		}
 		return  scopesList;
 	}
 
@@ -687,8 +707,15 @@
 		SimpleBindings params = new SimpleBindings();
 		params.put("scopeName", scopeName + "%");
 		
-		List<Object> activePolicies = controller.getDataByQuery(query, params);
-		List<Object> scopesList = controller.getDataByQuery(scopeNamequery, params);
+		List<Object> activePolicies = null;
+		List<Object> scopesList = null;
+		if(jUnit){
+			activePolicies = controller.getDataByQuery(query, null);
+			scopesList = controller.getDataByQuery(scopeNamequery, null);
+		}else{
+			activePolicies = controller.getDataByQuery(query, params);
+			scopesList = controller.getDataByQuery(scopeNamequery, params);
+		}
 		for(Object list : scopesList){
 			PolicyEditorScopes scopeById = (PolicyEditorScopes) list;
 			String scope = scopeById.getScopeName();
@@ -1394,7 +1421,12 @@
 			SimpleBindings peParams = new SimpleBindings();
 			peParams.put("split_1", split[1]);
 			peParams.put("split_0", split[0]);
-			List<Object> queryData = controller.getDataByQuery(query, peParams);
+			List<Object> queryData = null;
+			if(jUnit){
+				queryData = controller.getDataByQuery(query, null);
+			}else{
+				queryData = controller.getDataByQuery(query, peParams);
+			}
 			PolicyEntity entity = (PolicyEntity) queryData.get(0);
 			InputStream stream = new ByteArrayInputStream(entity.getPolicyData().getBytes(StandardCharsets.UTF_8));
 
diff --git a/POLICY-SDK-APP/src/main/java/org/onap/policy/admin/PolicyUserInfoController.java b/POLICY-SDK-APP/src/main/java/org/onap/policy/admin/PolicyUserInfoController.java
index 65312a9..5020662 100644
--- a/POLICY-SDK-APP/src/main/java/org/onap/policy/admin/PolicyUserInfoController.java
+++ b/POLICY-SDK-APP/src/main/java/org/onap/policy/admin/PolicyUserInfoController.java
@@ -44,7 +44,7 @@
 	private static final Logger LOGGER	= FlexLogger.getLogger(PolicyUserInfoController.class);
 	
 	@RequestMapping(value="/get_PolicyUserInfo", method = RequestMethod.GET)
-	private void getPolicyUserInfo(HttpServletRequest request, HttpServletResponse response){
+	public void getPolicyUserInfo(HttpServletRequest request, HttpServletResponse response){
 		JsonMessage msg = null;
 		try {
 			String userId =  UserUtils.getUserSession(request).getOrgUserId();
diff --git a/POLICY-SDK-APP/src/main/java/org/onap/policy/controller/PolicyController.java b/POLICY-SDK-APP/src/main/java/org/onap/policy/controller/PolicyController.java
index eac06a7..321dc72 100644
--- a/POLICY-SDK-APP/src/main/java/org/onap/policy/controller/PolicyController.java
+++ b/POLICY-SDK-APP/src/main/java/org/onap/policy/controller/PolicyController.java
@@ -143,6 +143,17 @@
 	//WebApp directories
 	private static String configHome;
 	private static String actionHome;
+	
+	private static boolean jUnit = false;
+	
+
+	public static boolean isjUnit() {
+		return jUnit;
+	}
+
+	public static void setjUnit(boolean jUnit) {
+		PolicyController.jUnit = jUnit;
+	}
 
 	@Autowired
 	private PolicyController(CommonClassDao commonClassDao){
@@ -157,7 +168,12 @@
 		Properties prop = new Properties();
 		InputStream input = null;
 		try {
-			input = new FileInputStream("xacml.admin.properties");
+			if(jUnit){
+				File file = new File(new File(".").getCanonicalPath() + File.separator + "src"+ File.separator + "test" + File.separator + "resources" + File.separator + "JSONConfig.json");
+				input = new FileInputStream(file);
+			}else{
+				input = new FileInputStream("xacml.admin.properties");
+			}
 			// load a properties file
 			prop.load(input);
 			//pap url
@@ -350,7 +366,7 @@
 	}
 
 	public static boolean getActivePolicy(String query) {
-		if(commonClassDao.getDataByQuery(query, new SimpleBindings()).size() > 0){
+		if(!commonClassDao.getDataByQuery(query, new SimpleBindings()).isEmpty()){
 			return true;
 		}else{
 			return false;
diff --git a/POLICY-SDK-APP/src/main/java/org/onap/policy/daoImp/SystemLogDbDaoImpl.java b/POLICY-SDK-APP/src/main/java/org/onap/policy/daoImp/SystemLogDbDaoImpl.java
index 4fa64ce..49024ba 100644
--- a/POLICY-SDK-APP/src/main/java/org/onap/policy/daoImp/SystemLogDbDaoImpl.java
+++ b/POLICY-SDK-APP/src/main/java/org/onap/policy/daoImp/SystemLogDbDaoImpl.java
@@ -42,6 +42,17 @@
 @Service("SystemLogDbDao")
 public class SystemLogDbDaoImpl implements SystemLogDbDao {
 	private static final Logger logger = FlexLogger.getLogger(SystemLogDbDaoImpl.class);
+	
+	private static boolean jUnit = false;
+	
+	public static boolean isjUnit() {
+		return jUnit;
+	}
+
+	public static void setjUnit(boolean jUnit) {
+		SystemLogDbDaoImpl.jUnit = jUnit;
+	}
+
 	@SuppressWarnings("unchecked")
 	@Override
 	public List<SystemLogDB> getLoggingData() {
@@ -49,7 +60,12 @@
 		Transaction tx = session.beginTransaction();
 		List<SystemLogDB> system = null;
         try {
-        	String sqlWhere = "date > DATE_SUB(curdate(), INTERVAL 5 DAY) ORDER BY date DESC limit "+PolicyController.getLogTableLimit()+"";
+        	String sqlWhere = null;
+        	if(jUnit){
+        		sqlWhere = "";
+        	}else{
+        		sqlWhere = "date > DATE_SUB(curdate(), INTERVAL 5 DAY) ORDER BY date DESC limit "+PolicyController.getLogTableLimit()+"";
+        	}
         	Criteria cr = session.createCriteria(SystemLogDB.class);
         	cr.add(Restrictions.sqlRestriction(sqlWhere));
             system = cr.list();
@@ -73,7 +89,12 @@
 		Transaction tx = session.beginTransaction();
 		List<SystemLogDB> system = null;
         try {
-        	String sqlWhere = "date > DATE_SUB(curdate(), INTERVAL 5 DAY) and logtype = 'error' ORDER BY date DESC limit "+PolicyController.getSystemAlertTableLimit()+"";
+        	String sqlWhere = null;
+        	if(jUnit){
+        		sqlWhere = "";
+        	}else{
+        		sqlWhere = "date > DATE_SUB(curdate(), INTERVAL 5 DAY) and logtype = 'error' ORDER BY date DESC limit "+PolicyController.getSystemAlertTableLimit()+"";
+        	}
         	Criteria cr = session.createCriteria(SystemLogDB.class);
         	cr.add(Restrictions.sqlRestriction(sqlWhere));
             system = cr.list();
diff --git a/POLICY-SDK-APP/src/test/java/org/onap/policy/admin/PolicyManagerServletTest.java b/POLICY-SDK-APP/src/test/java/org/onap/policy/admin/PolicyManagerServletTest.java
index a034c8a..970b678 100644
--- a/POLICY-SDK-APP/src/test/java/org/onap/policy/admin/PolicyManagerServletTest.java
+++ b/POLICY-SDK-APP/src/test/java/org/onap/policy/admin/PolicyManagerServletTest.java
@@ -28,7 +28,6 @@
 import java.util.Collections;
 import java.util.List;
 
-import javax.script.SimpleBindings;
 import javax.servlet.ServletConfig;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
@@ -147,11 +146,12 @@
 		HttpServletRequest request = mock(HttpServletRequest.class);       
         HttpServletResponse response = mock(HttpServletResponse.class);  
         PolicyController controller = mock(PolicyController.class);
-        
+        PolicyManagerServlet.setjUnit(true);
         BufferedReader reader = new BufferedReader(new StringReader("{params: { mode: 'DESCRIBEPOLICYFILE', path: 'com.Config_SampleTest1206.1.xml'}}"));
         try {
 			when(request.getReader()).thenReturn(reader);
-			when(controller.getDataByQuery("FROM PolicyEntity where policyName = 'Config_SampleTest1206.1.xml' and scope ='com'", new SimpleBindings())).thenReturn(basePolicyData);
+			String query = "FROM PolicyEntity where policyName = :split_1 and scope = :split_0";
+			when(controller.getDataByQuery(query, null)).thenReturn(basePolicyData);
 			servlet.setPolicyController(controller);
 			servlet.doPost(request, response);
 		} catch (Exception e1) {
@@ -168,6 +168,7 @@
 		HttpServletRequest request = mock(HttpServletRequest.class);       
         HttpServletResponse response = mock(HttpServletResponse.class); 
         PolicyController controller = mock(PolicyController.class);
+        PolicyManagerServlet.setjUnit(true);
         List<String> list = new ArrayList<>();
         list.add("{params: { mode: 'LIST', path: '/', onlyFolders: false}}");
         list.add("{params: { mode: 'LIST', path: '/com', onlyFolders: false}}");
@@ -176,9 +177,9 @@
             try {
     			when(request.getReader()).thenReturn(reader);
     			when(controller.getRoles("Test")).thenReturn(rolesdata);
-    			when(controller.getDataByQuery("from PolicyEditorScopes", new SimpleBindings())).thenReturn(policyEditorScopes);
-    			when(controller.getDataByQuery("from PolicyEditorScopes where SCOPENAME like 'com%'", new SimpleBindings())).thenReturn(policyEditorScopes);
-    			when(controller.getDataByQuery("from PolicyVersion where POLICY_NAME like 'com%'", new SimpleBindings())).thenReturn(policyVersion);
+    			when(controller.getDataByQuery("from PolicyEditorScopes", null)).thenReturn(policyEditorScopes);
+    			when(controller.getDataByQuery("from PolicyEditorScopes where SCOPENAME like :scopeName", null)).thenReturn(policyEditorScopes);
+    			when(controller.getDataByQuery("from PolicyVersion where POLICY_NAME like :scopeName", null)).thenReturn(policyVersion);
     			servlet.setPolicyController(controller);
     			servlet.setTestUserId("Test");
     			servlet.doPost(request, response);
@@ -196,6 +197,7 @@
 		HttpServletRequest request = mock(HttpServletRequest.class);       
         HttpServletResponse response = mock(HttpServletResponse.class); 
         PolicyController controller = mock(PolicyController.class);
+        PolicyManagerServlet.setjUnit(true);
         List<String> list = new ArrayList<>();
         list.add("{params: { mode: 'EDITFILE', path: '/com/Config_SampleTest1206.1.xml', onlyFolders: false}}");
         for(int i =0; i < list.size(); i++){
@@ -203,7 +205,7 @@
             try {
     			when(request.getReader()).thenReturn(reader);
     			when(controller.getRoles("Test")).thenReturn(rolesdata);
-    			when(controller.getDataByQuery("FROM PolicyEntity where policyName = 'Config_SampleTest1206.1.xml' and scope ='com'", new SimpleBindings())).thenReturn(basePolicyData);
+    			when(controller.getDataByQuery("FROM PolicyEntity where policyName = :split_1 and scope = :split_0", null)).thenReturn(basePolicyData);
     			servlet.setPolicyController(controller);
     			servlet.setTestUserId("Test");
     			servlet.doPost(request, response);
@@ -242,6 +244,7 @@
 		HttpServletRequest request = mock(HttpServletRequest.class);       
         HttpServletResponse response = mock(HttpServletResponse.class); 
         PolicyController controller = mock(PolicyController.class);
+        PolicyManagerServlet.setjUnit(true);
         List<String> list = new ArrayList<>();
         list.add("{params: { mode: 'EDITFILE', path: '/com/Config_BRMS_Param_BRMSParamvFWDemoPolicy.1.xml', onlyFolders: false}}");
         for(int i =0; i < list.size(); i++){
@@ -249,7 +252,7 @@
             try {
     			when(request.getReader()).thenReturn(reader);
     			when(controller.getRoles("Test")).thenReturn(rolesdata);
-    			when(controller.getDataByQuery("FROM PolicyEntity where policyName = 'Config_BRMS_Param_BRMSParamvFWDemoPolicy.1.xml' and scope ='com'", new SimpleBindings())).thenReturn(policyData);
+    			when(controller.getDataByQuery("FROM PolicyEntity where policyName = :split_1 and scope = :split_0", null)).thenReturn(policyData);
     			servlet.setPolicyController(controller);
     			servlet.setTestUserId("Test");
     			servlet.doPost(request, response);
@@ -288,6 +291,7 @@
 		HttpServletRequest request = mock(HttpServletRequest.class);       
         HttpServletResponse response = mock(HttpServletResponse.class); 
         PolicyController controller = mock(PolicyController.class);
+        PolicyManagerServlet.setjUnit(true);
         List<String> list = new ArrayList<>();
         list.add("{params: { mode: 'EDITFILE', path: '/com/Config_BRMS_Raw_TestBRMSRawPolicy.1.xml', onlyFolders: false}}");
         for(int i =0; i < list.size(); i++){
@@ -295,7 +299,7 @@
             try {
     			when(request.getReader()).thenReturn(reader);
     			when(controller.getRoles("Test")).thenReturn(rolesdata);
-    			when(controller.getDataByQuery("FROM PolicyEntity where policyName = 'Config_BRMS_Raw_TestBRMSRawPolicy.1.xml' and scope ='com'", new SimpleBindings())).thenReturn(policyData);
+    			when(controller.getDataByQuery("FROM PolicyEntity where policyName = :split_1 and scope = :split_0", null)).thenReturn(policyData);
     			servlet.setPolicyController(controller);
     			servlet.setTestUserId("Test");
     			servlet.doPost(request, response);
@@ -334,6 +338,7 @@
 		HttpServletRequest request = mock(HttpServletRequest.class);       
         HttpServletResponse response = mock(HttpServletResponse.class); 
         PolicyController controller = mock(PolicyController.class);
+        PolicyManagerServlet.setjUnit(true);
         List<String> list = new ArrayList<>();
         list.add("{params: { mode: 'EDITFILE', path: '/com/Config_Fault_TestClosedLoopPolicy.1.xml', onlyFolders: false}}");
         for(int i =0; i < list.size(); i++){
@@ -341,7 +346,7 @@
             try {
     			when(request.getReader()).thenReturn(reader);
     			when(controller.getRoles("Test")).thenReturn(rolesdata);
-    			when(controller.getDataByQuery("FROM PolicyEntity where policyName = 'Config_Fault_TestClosedLoopPolicy.1.xml' and scope ='com'", new SimpleBindings())).thenReturn(policyData);
+    			when(controller.getDataByQuery("FROM PolicyEntity where policyName = :split_1 and scope = :split_0", null)).thenReturn(policyData);
     			servlet.setPolicyController(controller);
     			servlet.setTestUserId("Test");
     			servlet.doPost(request, response);
@@ -380,6 +385,7 @@
 		HttpServletRequest request = mock(HttpServletRequest.class);       
         HttpServletResponse response = mock(HttpServletResponse.class); 
         PolicyController controller = mock(PolicyController.class);
+        PolicyManagerServlet.setjUnit(true);
         List<String> list = new ArrayList<>();
         list.add("{params: { mode: 'EDITFILE', path: '/com/Config_PM_TestClosedLoopPMPolicy.1.xml', onlyFolders: false}}");
         for(int i =0; i < list.size(); i++){
@@ -387,7 +393,7 @@
             try {
     			when(request.getReader()).thenReturn(reader);
     			when(controller.getRoles("Test")).thenReturn(rolesdata);
-    			when(controller.getDataByQuery("FROM PolicyEntity where policyName = 'Config_PM_TestClosedLoopPMPolicy.1.xml' and scope ='com'", new SimpleBindings())).thenReturn(policyData);
+    			when(controller.getDataByQuery("FROM PolicyEntity where policyName = :split_1 and scope = :split_0", null)).thenReturn(policyData);
     			servlet.setPolicyController(controller);
     			servlet.setTestUserId("Test");
     			servlet.doPost(request, response);
@@ -433,6 +439,7 @@
 		HttpServletRequest request = mock(HttpServletRequest.class);       
         HttpServletResponse response = mock(HttpServletResponse.class); 
         PolicyController controller = mock(PolicyController.class);
+        PolicyManagerServlet.setjUnit(true);
         List<String> list = new ArrayList<>();
         list.add("{params: { mode: 'EDITFILE', path: '/com/Config_MS_vFirewall.1.xml', onlyFolders: false}}");
         for(int i =0; i < list.size(); i++){
@@ -441,7 +448,7 @@
     			when(request.getReader()).thenReturn(reader);
     			when(commonClassDao.getDataById(GroupPolicyScopeList.class, "groupList", "resource=SampleResource,service=SampleService,type=SampleType,closedLoopControlName=SampleClosedLoop")).thenReturn(groupListData);
     			when(controller.getRoles("Test")).thenReturn(rolesdata);
-    			when(controller.getDataByQuery("FROM PolicyEntity where policyName = 'Config_MS_vFirewall.1.xml' and scope ='com'", new SimpleBindings())).thenReturn(policyData);
+    			when(controller.getDataByQuery("FROM PolicyEntity where policyName = :split_1 and scope = :split_0", null)).thenReturn(policyData);
     			servlet.setPolicyController(controller);
     			servlet.setTestUserId("Test");
     			servlet.doPost(request, response);
@@ -480,6 +487,7 @@
 		HttpServletRequest request = mock(HttpServletRequest.class);       
         HttpServletResponse response = mock(HttpServletResponse.class); 
         PolicyController controller = mock(PolicyController.class);
+        PolicyManagerServlet.setjUnit(true);
         List<String> list = new ArrayList<>();
         list.add("{params: { mode: 'EDITFILE', path: '/com/Config_FW_TestFireWallPolicy.1.xml', onlyFolders: false}}");
         for(int i =0; i < list.size(); i++){
@@ -487,7 +495,7 @@
             try {
     			when(request.getReader()).thenReturn(reader);
     			when(controller.getRoles("Test")).thenReturn(rolesdata);
-    			when(controller.getDataByQuery("FROM PolicyEntity where policyName = 'Config_FW_TestFireWallPolicy.1.xml' and scope ='com'", new SimpleBindings())).thenReturn(policyData);
+    			when(controller.getDataByQuery("FROM PolicyEntity where policyName = :split_1 and scope = :split_0", null)).thenReturn(policyData);
     			servlet.setPolicyController(controller);
     			servlet.setTestUserId("Test");
     			servlet.doPost(request, response);
@@ -524,6 +532,7 @@
 		HttpServletRequest request = mock(HttpServletRequest.class);       
         HttpServletResponse response = mock(HttpServletResponse.class); 
         PolicyController controller = mock(PolicyController.class);
+        PolicyManagerServlet.setjUnit(true);
         List<String> list = new ArrayList<>();
         list.add("{params: { mode: 'EDITFILE', path: '/com/Action_TestActionPolicy.1.xml', onlyFolders: false}}");
         for(int i =0; i < list.size(); i++){
@@ -531,7 +540,7 @@
             try {
     			when(request.getReader()).thenReturn(reader);
     			when(controller.getRoles("Test")).thenReturn(rolesdata);
-    			when(controller.getDataByQuery("FROM PolicyEntity where policyName = 'Action_TestActionPolicy.1.xml' and scope ='com'", new SimpleBindings())).thenReturn(policyData);
+    			when(controller.getDataByQuery("FROM PolicyEntity where policyName = :split_1 and scope = :split_0", null)).thenReturn(policyData);
     			servlet.setPolicyController(controller);
     			servlet.setTestUserId("Test");
     			servlet.doPost(request, response);
@@ -562,6 +571,7 @@
 		HttpServletRequest request = mock(HttpServletRequest.class);       
         HttpServletResponse response = mock(HttpServletResponse.class); 
         PolicyController controller = mock(PolicyController.class);
+        PolicyManagerServlet.setjUnit(true);
         List<String> list = new ArrayList<>();
         list.add("{params: { mode: 'EDITFILE', path: '/com/Decision_TestDecisionPolicyWithRuleAlgorithms.1.xml', onlyFolders: false}}");
         for(int i =0; i < list.size(); i++){
@@ -569,7 +579,7 @@
             try {
     			when(request.getReader()).thenReturn(reader);
     			when(controller.getRoles("Test")).thenReturn(rolesdata);
-    			when(controller.getDataByQuery("FROM PolicyEntity where policyName = 'Decision_TestDecisionPolicyWithRuleAlgorithms.1.xml' and scope ='com'", new SimpleBindings())).thenReturn(policyData);
+    			when(controller.getDataByQuery("FROM PolicyEntity where policyName = :split_1 and scope = :split_0", null)).thenReturn(policyData);
     			servlet.setPolicyController(controller);
     			servlet.setTestUserId("Test");
     			servlet.doPost(request, response);
diff --git a/POLICY-SDK-APP/src/test/java/org/onap/policy/admin/PolicyUserInfoControllerTest.java b/POLICY-SDK-APP/src/test/java/org/onap/policy/admin/PolicyUserInfoControllerTest.java
new file mode 100644
index 0000000..4931d20
--- /dev/null
+++ b/POLICY-SDK-APP/src/test/java/org/onap/policy/admin/PolicyUserInfoControllerTest.java
@@ -0,0 +1,64 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.policy.admin;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.mock;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.openecomp.portalsdk.core.domain.User;
+import org.openecomp.portalsdk.core.util.SystemProperties;
+import org.springframework.mock.web.MockHttpServletResponse;
+
+public class PolicyUserInfoControllerTest {
+
+	private HttpServletRequest request;
+	private MockHttpServletResponse response;
+	
+	@Before
+	public void setUp() throws Exception {
+		HttpSession mockSession = mock(HttpSession.class);
+		 request = mock(HttpServletRequest.class);  
+		 response =  new MockHttpServletResponse();
+		 User user = new User();
+		 user.setOrgUserId("Test");
+		 Mockito.when(mockSession.getAttribute(SystemProperties.getProperty("user_attribute_name"))).thenReturn(user);
+		 Mockito.when(request.getSession(false)).thenReturn(mockSession);
+	}
+
+	@Test
+	public final void testGetPolicyUserInfo() {
+		PolicyUserInfoController controller = new PolicyUserInfoController();
+		controller.getPolicyUserInfo(request, response);
+		try{
+			assertTrue(response.getStatus() == 200);
+		}catch(Exception e){
+			fail();
+		}
+
+	}
+
+}
diff --git a/POLICY-SDK-APP/src/test/java/org/onap/policy/controller/PolicyControllerTest.java b/POLICY-SDK-APP/src/test/java/org/onap/policy/controller/PolicyControllerTest.java
index 382637c..6f20a67 100644
--- a/POLICY-SDK-APP/src/test/java/org/onap/policy/controller/PolicyControllerTest.java
+++ b/POLICY-SDK-APP/src/test/java/org/onap/policy/controller/PolicyControllerTest.java
@@ -19,6 +19,8 @@
  */
 package org.onap.policy.controller;
 
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
@@ -33,6 +35,8 @@
 import org.onap.policy.common.logging.flexlogger.FlexLogger;
 import org.onap.policy.common.logging.flexlogger.Logger;
 import org.onap.policy.rest.dao.CommonClassDao;
+import org.onap.policy.rest.jpa.Datatype;
+import org.onap.policy.rest.jpa.FunctionDefinition;
 import org.onap.policy.rest.jpa.PolicyEntity;
 
 public class PolicyControllerTest {
@@ -44,6 +48,7 @@
 	public void setUp() throws Exception{
 		logger.info("setUp: Entering");
         commonClassDao = mock(CommonClassDao.class);
+        PolicyController.setCommonClassDao(commonClassDao);
         List<Object> data = new ArrayList<>();
         String policyData = "";
         try {
@@ -57,12 +62,30 @@
         entity.setPolicyData(policyData);
         entity.setScope("com");
         data.add(entity);
-        
+   
         when(commonClassDao.getDataByQuery("FROM PolicyEntity where policyName = 'Config_SampleTest1206.1.xml' and scope ='com'", new SimpleBindings())).thenReturn(data);
+        
+        FunctionDefinition fnDefinition = new FunctionDefinition();
+        fnDefinition.setXacmlid("Test");
+        fnDefinition.setShortname("Test");
+        Datatype dataType = new Datatype();
+        dataType.setXacmlId("Test");
+        fnDefinition.setDatatypeBean(dataType);
+        List<Object> fnObjects = new ArrayList<>();
+        fnObjects.add(fnDefinition);
+        when(commonClassDao.getData(FunctionDefinition.class)).thenReturn(fnObjects);
 	}
 	
 	@Test
-	public void dummy(){
-		System.out.println("Dummy");
+	public void testInit(){
+		PolicyController controller = new PolicyController();
+		PolicyController.setjUnit(true);
+		controller.init();
+		try{
+			assertTrue(PolicyController.dropDownMap.size() > 0);
+		}catch(Exception e){
+			logger.error("Exception Occured"+e);
+			fail();
+		}
 	}
 }
diff --git a/POLICY-SDK-APP/src/test/java/org/onap/policy/daoImp/CommonClassDaoImplTest.java b/POLICY-SDK-APP/src/test/java/org/onap/policy/daoImp/CommonClassDaoImplTest.java
index 78dd20a..d4b0c65 100644
--- a/POLICY-SDK-APP/src/test/java/org/onap/policy/daoImp/CommonClassDaoImplTest.java
+++ b/POLICY-SDK-APP/src/test/java/org/onap/policy/daoImp/CommonClassDaoImplTest.java
@@ -37,10 +37,13 @@
 import org.junit.Test;
 import org.onap.policy.common.logging.flexlogger.FlexLogger;
 import org.onap.policy.common.logging.flexlogger.Logger;
+import org.onap.policy.conf.HibernateSession;
+import org.onap.policy.controller.PolicyController;
 import org.onap.policy.daoImp.CommonClassDaoImpl;
 import org.onap.policy.rest.jpa.OnapName;
 import org.onap.policy.rest.jpa.PolicyEntity;
 import org.onap.policy.rest.jpa.PolicyVersion;
+import org.onap.policy.rest.jpa.SystemLogDB;
 import org.onap.policy.rest.jpa.UserInfo;
 import org.onap.policy.rest.jpa.WatchPolicyNotificationTable;
 import org.springframework.orm.hibernate4.LocalSessionFactoryBuilder;
@@ -79,7 +82,22 @@
 			// Set up dao with SessionFactory
 			commonClassDao = new CommonClassDaoImpl();
 			CommonClassDaoImpl.setSessionfactory(sessionFactory);
-
+			PolicyController.setLogTableLimit("1");
+			HibernateSession.setSession(sessionFactory);
+			SystemLogDB data1 = new SystemLogDB();
+			data1.setDate(new Date());
+			data1.setLogtype("INFO");
+			data1.setRemote("Test");
+			data1.setSystem("Test");
+			data1.setType("Test");
+			SystemLogDB data2 = new SystemLogDB();
+			data2.setDate(new Date());
+			data2.setLogtype("error");
+			data2.setRemote("Test");
+			data2.setSystem("Test");
+			data2.setType("Test");
+			HibernateSession.getSession().save(data1);
+			HibernateSession.getSession().save(data2);
 			// Create TCP server for troubleshooting
 			server = Server.createTcpServer("-tcpAllowOthers").start();
 			System.out.println("URL: jdbc:h2:" + server.getURL() + "/mem:test");
@@ -329,10 +347,10 @@
 		}
 	}
 
-	/*
-	 * Test for SQL Injection Protection
-	 *
+	
+	 /* Test for SQL Injection Protection
 	 */
+	 
 	@Test
 	@Transactional
     @Rollback(true)
@@ -375,6 +393,27 @@
 		}
 	}
 
+	@Test
+	public final void testGetLoggingData() {
+		SystemLogDbDaoImpl system = new SystemLogDbDaoImpl();
+		SystemLogDbDaoImpl.setjUnit(true);
+		try{
+			assertTrue(system.getLoggingData() != null);
+		}catch(Exception e){
+			fail();
+		}
+	}
+
+	@Test
+	public final void testGetSystemAlertData() {
+		SystemLogDbDaoImpl system = new SystemLogDbDaoImpl();
+		SystemLogDbDaoImpl.setjUnit(true);
+		try{
+			assertTrue(system.getSystemAlertData() != null);
+		}catch(Exception e){
+			fail();
+		}
+	}
 
 	@After
 	public void deleteDB(){
diff --git a/POLICY-SDK-APP/src/test/resources/xacml.admin.properties b/POLICY-SDK-APP/src/test/resources/xacml.admin.properties
new file mode 100644
index 0000000..0f285b6
--- /dev/null
+++ b/POLICY-SDK-APP/src/test/resources/xacml.admin.properties
@@ -0,0 +1,203 @@
+###
+# ============LICENSE_START=======================================================
+# ONAP Policy Engine
+# ================================================================================
+# Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# 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.
+# ============LICENSE_END=========================================================
+###
+
+#
+# This file is set to the defaults one can use to run the XACML-PAP-ADMIN for testing and development.
+#
+# It is not recommended to modify this file directly, but rather copy it to another location and make any modifications
+# necessary to run the application in a development or a production environment. You can set the Java VM System
+# property to change where the application can find the file. For example:
+#
+#-Dxacml.properties=/opt/app/xacml/etc/xacml.admin.properties 
+#
+#
+# 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=org.onap.policy.xacml.custom.OnapFunctionDefinitionFactory
+xacml.att.policyFinderFactory=com.att.research.xacmlatt.pdp.std.StdPolicyFinderFactory
+
+#
+# This is an extremely simple policy to demonstrate authorization
+# within the Admin Console.
+#
+xacml.rootPolicies=admin
+#
+# PAP Servlet properties
+#
+xacml.PAP.papEngineFactory=org.onap.policy.xacml.std.pap.StdEngineFactory
+
+#
+# Admin Console properties
+#
+xacml.AC.papEngineFactory=org.onap.policy.xacml.admin.util.RESTfulPAPFactory
+
+# Set your domain here:
+xacml.rest.admin.domain=com
+#
+#
+# Property to declare the max time frame for logs.
+#
+xacml.log.timeframe=30
+#
+#
+#
+xacml.rest.admin.closedLoopJSON =JSONConfig.json
+xacml.rest.admin.microServiceModel=model.properties
+xacm.restful.interface.file=RESTful.interface.properties
+#
+#If the Audit is set false, then Audit function will not work at the Server Run time.
+#This will Syncronize the data between Roles and Userinfo Table
+xacml.audit.userInfo = true
+#
+#The Test Environment User Login LoginIU Should provide below on seperating with Comma
+#
+xacml.testEnvironment.loginId = 
+
+#Log DB properties 
+xacml.log.db.driver=org.mariadb.jdbc.Driver
+xacml.log.db.url=jdbc:mariadb://localhost:3306/log?failOverReadOnly=false&autoReconnect=true
+xacml.log.db.user=policy_user
+xacml.log.db.password=policy_user
+
+xacml.att.log.timeframe=150
+
+javax.persistence.jdbc.driver=com.mysql.jdbc.Driver
+javax.persistence.jdbc.url=jdbc:mysql://localhost:3306/onap_sdk
+javax.persistence.jdbc.user=policy_user
+javax.persistence.jdbc.password=policy_user
+
+# Dashboard refresh rate in miliseconds
+xacml.refresh.rate=40000
+xacml.user.column.count=3
+xacml.sqlcontainer.page.length=75
+xacm.xcor.required.pattern=1,1
+xacm.cache.live.time=2
+xacml.max.priority.count=10
+
+#
+# These can be set so the Admin Console knows who is logged on. Ideally, you can run the console in a J2EE
+# container and setup authentication as you please. Setting HttpSession attribute values will override these
+# values set in the properties files.
+#
+# ((HttpServletRequest) request).getSession().setAttribute("xacml.rest.admin.user.name", "Homer");
+#
+# The default policy: Policy-Admin.xml is extremely simple.
+#
+# You can test authorization within the Admin Console by changing the user id.
+# There are 3 supported user ids:
+#	guest - Read only access
+#	editor - Read/Write access
+#	admin - Read/Write/Admin access
+#
+# An empty or null value for xacml.rest.admin.user.id results in no access to the application at all.
+#
+# This is for development/demonstration purposes only. A production environment should provide authentication which is
+# outside the scope of this application. This application can be used to develop a XACML policy for user authorization
+# within this application.
+#
+#xacml.rest.admin.user.name=Guest
+#xacml.rest.admin.user.id=guest
+#xacml.rest.admin.user.name=Editor
+#xacml.rest.admin.user.id=editor
+xacml.rest.admin.user.name=Administrator
+xacml.rest.admin.user.id=super-admin
+xacml.rest.admin.user.email=
+
+#
+# URL location for the PAP servlet.
+#
+xacml.rest.pap.url=http://localhost:8070/pap/
+
+# id PAP
+xacml.rest.pap.userid=testpap
+# pass PAP
+xacml.rest.pap.password=alpha123
+
+# new Property Please mention your PAP-REST webapps Location here. 
+
+xacml.rest.config.webapps=/home/users/PolicyEngine/webapps/ConfigPAP/
+
+# pdps file - Needs to have the location of the PDPs File of the PAP-REST
+xacml.rest.pdp.idfile=test.properties
+
+#Template Versions
+xacml.rest.closedLoopFault=OpenSource.version.1
+xacml.rest.closedLoopPM=OpenSource.version.1
+xacml.rest.microServices=OpenSource.version.1
+xacml.rest.gocPolicy=OpenSource.version.1
+xacml.rest.firewallPolicy=OpenSource.version.1
+
+#***Properties for IntegrityMonitor integration defined in XACMLRestProperties.java***
+
+#The name of the Admin.  Must be unique across the system
+xacml.rest.admin.resource.name=site_1.admin_1
+
+#The site name for the Admin
+site_name=site_1
+
+#Has to be one of pdp_xacml, pdp_drools, pap, pap_admin, logparser, brms_gateway, astra_gateway, elk_server
+node_type=pap_admin
+
+# The (optional) period of time in seconds between executions of the integrity audit.
+# Value < 0 : Audit does not run (default value if property is not present = -1)
+# Value = 0 : Audit runs continuously
+# Value > 0 : The period of time in seconds between execution of the audit on a particular node
+integrity_audit_period_seconds=-1
+
+#Automatic Policy Distribution 
+xacml.att.automatic.push = false
+
+
+#Dashboard Tab Limit
+xacml.onap.dashboard.logTableLimit = 5000
+xacml.onap.dashboard.systemAlertTableLimit = 2000
+
+
+#Diff of policies for Firewall feature
+FW_GETURL=https://todo_enter_the_firewallurl
+FW_AUTHOURL=https://todo_enter_the_firewallAuthurl
+FW_PROXY=todo_enter_the_proxy
+FW_PORT=8080
+
+#SMTP Server Details for Java Mail
+onap.smtp.host = smtp_host
+onap.smtp.port = smtp_port
+onap.smtp.userName = smtp_username
+onap.smtp.password = smtp_password
+onap.smtp.emailExtension=smtp_emailExtension
+onap.application.name = smtp_AppName
+
+#Dialect for Database
+onap.dialect = org.hibernate.dialect.MySQLDialect
+
+policyAdapter.impl.className = org.onap.policy.admin.PolicyAdapter
+
+#Micro Service Model Properties
+xacml.policy.msOnapName=http://org.onap
+xacml.policy.msPolicyName=http://org.onap.policy
\ No newline at end of file
diff --git a/PolicyEngineUtils/pom.xml b/PolicyEngineUtils/pom.xml
index c083705..effaf5b 100644
--- a/PolicyEngineUtils/pom.xml
+++ b/PolicyEngineUtils/pom.xml
@@ -63,9 +63,9 @@
 			<version>2.6.0</version>
 		</dependency>
 		<dependency>
-			<groupId>mysql</groupId>
-			<artifactId>mysql-connector-java</artifactId>
-			<version>5.1.30</version>
+			<groupId>org.mariadb.jdbc</groupId>
+			<artifactId>mariadb-java-client</artifactId>
+			<version>2.1.1</version>
 		</dependency>
 		<dependency>
 			<groupId>com.fasterxml.jackson.core</groupId>
@@ -110,6 +110,11 @@
 			<version>1.3.0</version>
 		</dependency>
 		<dependency>
+		    <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+            <version>2.8.1</version>
+        </dependency>
+		<dependency>
 			<groupId>com.att.aft</groupId>
 			<artifactId>dme2</artifactId>
 			<version>3.1.200</version>
diff --git a/PolicyEngineUtils/src/main/java/org/onap/policy/utils/PolicyUtils.java b/PolicyEngineUtils/src/main/java/org/onap/policy/utils/PolicyUtils.java
index b74bd28..51409b6 100644
--- a/PolicyEngineUtils/src/main/java/org/onap/policy/utils/PolicyUtils.java
+++ b/PolicyEngineUtils/src/main/java/org/onap/policy/utils/PolicyUtils.java
@@ -45,11 +45,11 @@
 import org.xml.sax.InputSource;
 import org.xml.sax.XMLReader;
 
-import com.att.aft.dme2.internal.gson.JsonParser;
-import com.att.aft.dme2.internal.gson.JsonSyntaxException;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.common.base.CharMatcher;
+import com.google.gson.JsonParser;
+import com.google.gson.JsonSyntaxException;
 
 public class PolicyUtils {
     private static final Logger LOGGER = FlexLogger.getLogger(PolicyUtils.class);
diff --git a/docs/index.rst b/docs/index.rst
index 833e1aa..4df15fc 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -1,7 +1,8 @@
 .. This work is licensed under a Creative Commons Attribution 4.0 International License.
 
-TODO Add files to toctree and delete this header
-------------------------------------------------
+Policy Engine
+-------------
+
 .. toctree::
    :maxdepth: 1
 
diff --git a/pom.xml b/pom.xml
index 96cc501..c615114 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
 	<parent>
 		<groupId>org.onap.oparent</groupId>
 		<artifactId>oparent</artifactId>
-		<version>1.0.0-SNAPSHOT</version>
+		<version>0.1.1</version>
 		<relativePath/>
 	</parent>
 
