[POLICY-73] replace openecomp for policy-engine

Change-Id: I54072f6bcd388c0e05562614ee89b4ae7ad67004
Signed-off-by: Guo Ruijing <ruijing.guo@intel.com>
Signed-off-by: Pamela Dragosh <pdragosh@research.att.com>
diff --git a/ONAP-XACML/src/main/java/org/onap/policy/xacml/api/XACMLErrorConstants.java b/ONAP-XACML/src/main/java/org/onap/policy/xacml/api/XACMLErrorConstants.java
new file mode 100644
index 0000000..77c0da4
--- /dev/null
+++ b/ONAP-XACML/src/main/java/org/onap/policy/xacml/api/XACMLErrorConstants.java
@@ -0,0 +1,56 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP-XACML
+ * ================================================================================
+ * 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.api;
+
+/**
+ * List of Error Classifications
+ *  PE100 - Permissions
+ *  PE200 - System Error (such as availability, timeout, configuration, etc...)
+ *  PE300 - Data Issue( such as request for REST/JSON )
+ *  PE400 - Schema validation
+ *  PE500 - Process Flow issues
+ *  PE900 - Default/Unknown Errors
+ *  
+ *
+ */
+public class XACMLErrorConstants {
+	//Captures all the errors related to Authentication, Authorizations and Permissions in the PolicyEngine Process
+	public static final String ERROR_PERMISSIONS = "PE100 - Permissions Error: ";
+	
+	//Captures all the errors related to availability, timeout configuration variables, etc... in the PolicyEngine
+	public static final String ERROR_SYSTEM_ERROR = "PE200 - System Error: ";
+	
+	/*
+	 * Captures all the errors related to configuration values from properties files and data from the interfacing System
+	 * like REST/JSON values 
+	*/
+	public static final String ERROR_DATA_ISSUE = "PE300 - Data Issue: ";
+	
+	//Captures all the errors related to the XML schemas and/or REST/JSON structures 
+	public static final String ERROR_SCHEMA_INVALID = "PE400 - Schema validation Error: ";
+	
+	//Captures all the errors related to the Process, when data from one Process to another Process does not flow
+	public static final String ERROR_PROCESS_FLOW = "PE500 - Process Flow Issue: ";
+	
+	//Captures all the errors that not related to the list of above error codes
+	public static final String ERROR_UNKNOWN = "PE900 - Unknown Error: ";
+	
+
+}
diff --git a/ONAP-XACML/src/main/java/org/onap/policy/xacml/api/pap/ONAPPapEngineFactory.java b/ONAP-XACML/src/main/java/org/onap/policy/xacml/api/pap/ONAPPapEngineFactory.java
new file mode 100644
index 0000000..bd95315
--- /dev/null
+++ b/ONAP-XACML/src/main/java/org/onap/policy/xacml/api/pap/ONAPPapEngineFactory.java
@@ -0,0 +1,38 @@
+package org.onap.policy.xacml.api.pap;
+
+import java.util.Properties;
+
+import com.att.research.xacml.api.pap.PAPException;
+import com.att.research.xacml.util.FactoryException;
+import com.att.research.xacml.util.FactoryFinder;
+
+public abstract class ONAPPapEngineFactory{
+	
+	/**
+	 * Creates a new <code>PAPEngineFactory</code> instance using the given class name and the default thread class loader.
+	 * 
+	 * @param factoryClassName the <code>String</code> name of the factory class to instantiate
+	 * @return an instance of an object that extends <code>ONAPPapEngineFactory</code> to use in creating <code>PAPPolicyEngine</code> objects.
+	 */
+	public static ONAPPapEngineFactory newInstance(String factoryClassName) throws FactoryException {
+		return FactoryFinder.newInstance(factoryClassName, ONAPPapEngineFactory.class, null, true);
+	}
+
+	/**
+	 * Creates a new <code>PAPPolicyEngine</code> based on the configured <code>ONAPPapEngineFactory</code>.
+	 * 
+	 * @return a new <code>PAPPolicyEngine</code>
+	 * @throws PAPException 
+	 */
+	public abstract PAPPolicyEngine newEngine() throws FactoryException, PAPException;
+
+	/**
+	 * Creates a new <code>PAPPolicyEngine</code> based on the configured <code>ONAPPapEngineFactory</code>.
+	 * 
+	 * @return a new <code>PAPPolicyEngine</code>
+	 * @throws PAPException 
+	 */
+	public abstract PAPPolicyEngine newEngine(Properties properties) throws FactoryException, PAPException;
+
+
+}
diff --git a/ONAP-XACML/src/main/java/org/onap/policy/xacml/api/pap/OnapPAPPolicy.java b/ONAP-XACML/src/main/java/org/onap/policy/xacml/api/pap/OnapPAPPolicy.java
new file mode 100644
index 0000000..78ce354
--- /dev/null
+++ b/ONAP-XACML/src/main/java/org/onap/policy/xacml/api/pap/OnapPAPPolicy.java
@@ -0,0 +1,89 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP-XACML
+ * ================================================================================
+ * 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.api.pap;
+
+import java.net.URI;
+import java.util.List;
+import java.util.Map;
+
+import org.onap.policy.xacml.std.pap.StdPAPPolicy;
+
+import com.fasterxml.jackson.annotation.JsonSubTypes;
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
+import com.fasterxml.jackson.annotation.JsonSubTypes.Type;
+
+/*
+ * The following allows us to use Jackson to convert sub-types of this type into JSON and back to objects.
+ */
+@JsonTypeInfo(  
+	    use = JsonTypeInfo.Id.NAME,  
+	    include = JsonTypeInfo.As.PROPERTY,  
+	    property = "PAPPolicyType")  
+@JsonSubTypes({  
+	    @Type(value = StdPAPPolicy.class, name = "StdPAPPolicy") })  
+public interface OnapPAPPolicy {
+	
+	public String getPolicyName();
+	public String getOldPolicyFileName();
+	public String getPolicyDescription();
+	public String getOnapName();
+	public String getConfigName();
+	public Map<String, String> getDynamicFieldConfigAttributes();
+	public Map<String, String> getDynamicSettingsMap();
+	public List<String> getDynamicRuleAlgorithmLabels();
+	public List<String> getDynamicRuleAlgorithmCombo();
+	public List<String> getDynamicRuleAlgorithmField1();
+	public List<String> getDynamicRuleAlgorithmField2();
+	public List<Object> getDynamicVariableList();
+	public List<String> getDataTypeList();
+	public String getConfigBodyData();
+	public String getPolicyID();
+	public String getRuleID();
+	public String getConfigType();
+	public Boolean isEditPolicy();
+	public Boolean isDraft();
+	public String getVersion();
+	public String getDomainDir();
+	public String getConfigPolicyType();
+	public String getJsonBody();
+	public Integer getHighestVersion();
+	public URI getLocation();
+	public String getActionPerformer();
+	public String getActionAttribute();
+	public String getActionBody();
+	public Map<String, String> getDropDownMap();
+	public String getActionDictHeader();
+	public String getActionDictType();
+	public String getActionDictUrl();
+	public String getActionDictMethod();
+	public String getServiceType();
+	public String getUuid();
+	public String getMsLocation();
+    public String getPriority();	
+    public String getDeleteCondition();
+    public String getDictionaryType();
+    public String getDictionary();
+    public String getDictionaryFields();
+    
+	public String getRiskLevel();
+	public String getGuard();
+	public String getRiskType();
+	public String getTTLDate();
+}
diff --git a/ONAP-XACML/src/main/java/org/onap/policy/xacml/api/pap/OnapPDP.java b/ONAP-XACML/src/main/java/org/onap/policy/xacml/api/pap/OnapPDP.java
new file mode 100644
index 0000000..65db0b9
--- /dev/null
+++ b/ONAP-XACML/src/main/java/org/onap/policy/xacml/api/pap/OnapPDP.java
@@ -0,0 +1,44 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP-XACML
+ * ================================================================================
+ * 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.api.pap;
+
+import org.onap.policy.xacml.std.pap.StdPDP;
+
+import com.att.research.xacml.api.pap.PDP;
+import com.fasterxml.jackson.annotation.JsonSubTypes;
+import com.fasterxml.jackson.annotation.JsonSubTypes.Type;
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
+
+/*
+ * The following allows us to use Jackson to convert sub-types of this type into JSON and back to objects.
+ */
+@JsonTypeInfo(  
+	    use = JsonTypeInfo.Id.NAME,  
+	    include = JsonTypeInfo.As.PROPERTY,  
+	    property = "PDPType")  
+@JsonSubTypes({  
+	    @Type(value = StdPDP.class, name = "StdPDP") })  
+public interface OnapPDP extends PDP {
+
+	public Integer 						getJmxPort();
+	
+	public void 						setJmxPort(Integer jmxport);
+	
+}
diff --git a/ONAP-XACML/src/main/java/org/onap/policy/xacml/api/pap/OnapPDPGroup.java b/ONAP-XACML/src/main/java/org/onap/policy/xacml/api/pap/OnapPDPGroup.java
new file mode 100644
index 0000000..3c9bdb3
--- /dev/null
+++ b/ONAP-XACML/src/main/java/org/onap/policy/xacml/api/pap/OnapPDPGroup.java
@@ -0,0 +1,15 @@
+package org.onap.policy.xacml.api.pap;
+
+import java.util.Set;
+
+import com.att.research.xacml.api.pap.PDPGroup;
+import com.att.research.xacml.api.pap.PDPPolicy;
+
+public interface OnapPDPGroup extends PDPGroup {
+
+	public Set<OnapPDP> getOnapPdps();
+	
+	public Set<PDPPolicy> 				getSelectedPolicies();
+	
+	public String						getOperation();
+}
diff --git a/ONAP-XACML/src/main/java/org/onap/policy/xacml/api/pap/PAPPolicyEngine.java b/ONAP-XACML/src/main/java/org/onap/policy/xacml/api/pap/PAPPolicyEngine.java
new file mode 100644
index 0000000..4f1cfaf
--- /dev/null
+++ b/ONAP-XACML/src/main/java/org/onap/policy/xacml/api/pap/PAPPolicyEngine.java
@@ -0,0 +1,66 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP-XACML
+ * ================================================================================
+ * 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.api.pap;
+
+import java.io.InputStream;
+import java.util.Set;
+
+import com.att.research.xacml.api.pap.PAPException;
+import com.att.research.xacml.api.pap.PDPPolicy;
+import com.att.research.xacml.api.pap.PDPStatus;
+
+public interface PAPPolicyEngine{
+	
+	public OnapPDPGroup getDefaultGroup() throws PAPException;
+	
+	public void						SetDefaultGroup(OnapPDPGroup group) throws PAPException;
+	
+	public void		newPDP(String id, OnapPDPGroup group, String name, String description, int jmxport) throws PAPException, NullPointerException;
+	
+	public void						newGroup(String name, String description) throws PAPException, NullPointerException;
+	
+	public OnapPDPGroup getGroup(String id) throws PAPException;
+	
+	public Set<OnapPDPGroup> getOnapPDPGroups() throws PAPException;
+	
+	public OnapPDPGroup getPDPGroup(OnapPDP pdp) throws PAPException;
+	
+	public PDPStatus getStatus(OnapPDP pdp) throws PAPException;
+	
+	public void movePDP(OnapPDP pdp, OnapPDPGroup newGroup) throws PAPException;
+	
+	public void updatePDP(OnapPDP pdp) throws PAPException;
+	
+	public void removePDP(OnapPDP pdp) throws PAPException; 
+	
+	public OnapPDP getPDP(String pdpId) throws PAPException;
+	
+	public void						updateGroup(OnapPDPGroup group) throws PAPException;
+	
+	public void						removeGroup(OnapPDPGroup group, OnapPDPGroup newGroup) throws PAPException, NullPointerException;
+	
+public void						publishPolicy(String id, String name, boolean isRoot, InputStream policy, OnapPDPGroup group) throws PAPException;
+	
+	// copy the given policy file into the group's directory, but do not include the policy in the group's policy set
+	public void						copyPolicy(PDPPolicy policy, OnapPDPGroup group) throws PAPException;
+	
+	public void						removePolicy(PDPPolicy policy, OnapPDPGroup group) throws PAPException;
+	
+}
diff --git a/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pap/StdEngine.java b/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pap/StdEngine.java
new file mode 100644
index 0000000..3132b8c
--- /dev/null
+++ b/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pap/StdEngine.java
@@ -0,0 +1,1034 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP-XACML
+ * ================================================================================
+ * 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.std.pap;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+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.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.onap.policy.common.logging.eelf.MessageCodes;
+import org.onap.policy.common.logging.eelf.PolicyLogger;
+import org.onap.policy.xacml.api.XACMLErrorConstants;
+import org.onap.policy.xacml.api.pap.OnapPDP;
+import org.onap.policy.xacml.api.pap.OnapPDPGroup;
+import org.onap.policy.xacml.api.pap.PAPPolicyEngine;
+
+import com.att.research.xacml.api.pap.PAPException;
+import com.att.research.xacml.api.pap.PDP;
+import com.att.research.xacml.api.pap.PDPGroup;
+import com.att.research.xacml.api.pap.PDPPIPConfig;
+import com.att.research.xacml.api.pap.PDPPolicy;
+import com.att.research.xacml.api.pap.PDPStatus;
+import com.att.research.xacml.util.XACMLProperties;
+import com.google.common.base.Joiner;
+import com.google.common.base.Splitter;
+import com.google.common.collect.Sets;
+
+/**
+ * This is a simple PAP engine that uses some property files and a simple directory
+ * structure in the file system to manage a policy repository and set of PDP nodes.
+ * 
+ *
+ */
+public class StdEngine extends StdPDPItemSetChangeNotifier implements PAPPolicyEngine {
+	public static final String pipPropertyFile = "pip.properties";
+
+	private static Log	logger	= LogFactory.getLog(StdEngine.class);
+
+	public static String	PROP_PAP_REPO = "xacml.pap.pdps";
+	public static String	PROP_PAP_GROUPS = "xacml.pap.groups";
+	public static String	PROP_PAP_GROUPS_DEFAULT = "xacml.pap.groups.default";
+	public static String	PROP_PAP_GROUPS_DEFAULT_NAME = "default";
+	//this value will be accessed from XacmlPapServlet so that we know if a default group did not exist
+	//and was just added. This way, we can add the new group to the database.
+	public boolean wasDefaultGroupJustAdded = false;
+
+    protected final Path repository;
+	protected Set<StdPDPGroup> groups;
+		
+	public StdEngine() throws PAPException, IOException {
+		//
+		// Get the location in the file system of our repository
+		//
+		this.repository = Paths.get(XACMLProperties.getProperty(PROP_PAP_REPO));
+		//
+		// Initialize
+		//
+		this.intialize();
+	}
+	
+	public StdEngine(Properties properties) throws PAPException, IOException {
+		//
+		// Get the location in the file system of our repository
+		//
+		this.repository = Paths.get(properties.getProperty(PROP_PAP_REPO));
+		//
+		// Initialize
+		//
+		this.intialize();
+	}
+	
+	public StdEngine(Path repository) throws PAPException, IOException {
+		//
+		// Save our location
+		//
+		this.repository = repository;
+		//
+		// Initialize
+		//
+		this.intialize();
+	}
+	
+	private void intialize() throws PAPException, IOException {
+		//
+		// Sanity check the repository path
+		//
+		if (this.repository == null) {
+			throw new PAPException ("No repository specified.");
+		}
+		if (Files.notExists(this.repository)) {
+			Files.createDirectory(repository);
+		}
+		if (Files.isDirectory(this.repository) == false) {
+			throw new PAPException ("Repository is NOT a directory: " + this.repository.toAbsolutePath());
+		}
+		if (Files.isWritable(this.repository) == false) {
+			throw new PAPException ("Repository is NOT writable: " + this.repository.toAbsolutePath());
+		}
+		//
+		// Load our groups
+		//
+		this.loadGroups();
+	}
+	
+	private void loadGroups() throws PAPException {
+		//
+		// Create a properties object
+		//
+		Properties properties = new Properties();
+		Path file = Paths.get(this.repository.toString(), XACMLProperties.XACML_PROPERTIES_NAME);
+		try {
+			//
+			// Load the properties
+			//
+			try (InputStream is = new FileInputStream(file.toFile())) {
+				properties.load(is);
+			}
+
+			//
+			// Parse it
+			//
+			this.groups = this.readProperties(this.repository, properties);
+		} catch (IOException e) {
+			PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "StdEngine", "Failed to load properties file");
+			this.groups = new HashSet<>();
+		}
+		//
+		// Initialize the default group
+		//
+		PDPGroup defaultGroup = this.initializeDefaultGroup(file, properties);
+		logger.info("Default group is: " + defaultGroup.getId() + "=" + defaultGroup.getName());
+	}
+	
+	private PDPGroup initializeDefaultGroup(Path file, Properties properties) throws PAPException {
+		wasDefaultGroupJustAdded = false;
+		//
+		// Make sure we have the default group
+		//
+		PDPGroup group = this.getDefaultGroup();
+		if (group != null) {
+			return group;
+		}
+		//
+		// We don't have the default group, create it
+		//
+		String defaultId = properties.getProperty(PROP_PAP_GROUPS_DEFAULT, PROP_PAP_GROUPS_DEFAULT_NAME);
+		if(defaultId == null){
+			defaultId = PROP_PAP_GROUPS_DEFAULT_NAME;
+		}
+		if(defaultId.equals("")){
+			defaultId = PROP_PAP_GROUPS_DEFAULT_NAME;
+		}
+		//we're going to check one more time in case the PROP_PAP_GROUPS_DEFAULT_NAME doesn't exist
+		if(defaultId == null){
+			defaultId = "default";
+		}
+		if(defaultId.equals("")){
+			defaultId = "default";
+		}
+		logger.warn("Default group does NOT exist, creating " + defaultId);
+		Path defaultPath = Paths.get(this.repository.toString(), defaultId);
+		try {
+			//
+			// Does it exist?
+			//
+			if (Files.notExists(defaultPath)) {
+				//
+				// Create its directory
+				//
+				Files.createDirectory(defaultPath);
+				//
+				// Create property files
+				//
+				{
+					Properties props = new Properties();
+					props.setProperty(XACMLProperties.PROP_REFERENCEDPOLICIES, "");
+					props.setProperty(XACMLProperties.PROP_ROOTPOLICIES, "");
+					Path policyPath = Paths.get(defaultPath.toAbsolutePath().toString(), "xacml.policy.properties");
+					Files.createFile(policyPath);
+					try (OutputStream os = Files.newOutputStream(policyPath)) {
+						props.store(os, "");
+					} catch (IOException e) {
+						PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "StdEngine", "Failed to write default policy properties");
+					}
+				}
+				{
+					Properties props = new Properties();
+					props = setPIPProperties(props);
+					Path pipPath = Paths.get(defaultPath.toAbsolutePath().toString(), "xacml.pip.properties");
+					Files.createFile(pipPath);
+					try (OutputStream os = Files.newOutputStream(pipPath)) {
+						props.store(os, "");
+					} catch (IOException e) {
+						PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "StdEngine", "Failed to write default pip properties");
+					}					
+				}
+			}
+			//
+			// Create the default group
+			//
+			StdPDPGroup newDefault = new StdPDPGroup(defaultId, true, "default", "The default group where new PDP's are put.", defaultPath);
+			//
+			// Add it to our list
+			//
+			this.groups.add(newDefault);
+			//
+			// Save our properties out since we have
+			// a new default group.
+			//
+			StdEngine.setGroupProperties(newDefault, properties);
+			//
+			// Save it to disk
+			//
+			try {
+				try (OutputStream os = Files.newOutputStream(file)) {
+					properties.store(os, "");
+				}
+			} catch (IOException e) {
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "StdEngine", "Failed to save properties with new default group information.");
+			}
+			//
+			// Return it
+			//
+			wasDefaultGroupJustAdded = true;
+			return newDefault;
+		} catch (IOException e) {
+			PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "StdEngine", "Failed to create default group");
+			throw new PAPException("Failed to create default group");
+		}
+	}
+	
+	@Override
+	public OnapPDPGroup getDefaultGroup() throws PAPException{
+		for (OnapPDPGroup group : this.groups) {
+			if (group.isDefaultGroup()) {
+				return group;
+			}
+		}
+		//
+		// Default group doesn't exist
+		//
+		return null;
+	}
+
+	@Override
+	public OnapPDPGroup getGroup(String id) throws PAPException {
+		for (OnapPDPGroup g: this.groups) {
+			if (g.getId().equals(id)) {
+				return g;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public void	newGroup(String name, String description) throws PAPException, NullPointerException{	
+		//
+		// Null check
+		//
+		if (name == null) {
+			throw new NullPointerException();
+		}
+		//
+		// Do we already have this group?
+		//
+		for (PDPGroup group : this.groups) {
+			if (group.getName().equals(name)) {
+				throw new PAPException("Group with this name=" + name + " already exists.");
+			}
+		}
+		
+		
+		// create an Id that can be used as a file name and a properties file key.
+		// Ids must not contain \/:*?"<>|=,;
+		// The ID must also be unique within the current set of PDPGroups.
+		String id = createNewPDPGroupId(name);
+		
+		
+		//
+		// Construct the directory path
+		//
+		Path groupPath = Paths.get(this.repository.toString(), id);
+		//
+		// If it exists already
+		//
+		if (Files.exists(groupPath)) {
+			logger.warn("addGroup " + id + " directory exists" + groupPath.toString());
+		} else {
+			try {
+				//
+				// Create the directory
+				//
+				Files.createDirectory(groupPath);
+			} catch (IOException e) {
+				PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "StdEngine", "Failed to create " + groupPath);
+				throw new PAPException("Failed to create " + id);
+			}
+		}
+		//
+		// Create the Policies
+		//
+
+		Path policyProperties = Paths.get(groupPath.toString(), "xacml.policy.properties");
+		if (Files.exists(policyProperties)) {
+			logger.warn("addGroup " + id + " file exists: " + policyProperties.toString());
+		} else {
+			Properties props = new Properties();
+			props.setProperty(XACMLProperties.PROP_REFERENCEDPOLICIES, "");
+			props.setProperty(XACMLProperties.PROP_ROOTPOLICIES, "");
+			try {
+				Files.createFile(policyProperties);
+				try (OutputStream os = Files.newOutputStream(policyProperties)) {
+					props.store(os, "");
+				}
+			} catch (IOException e) {
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "StdEngine", "Failed to create " + policyProperties);
+				throw new PAPException("Failed to create " + id);
+			}
+		}
+		//
+		// Create the PIP config
+		//
+		Path pipProperties = Paths.get(groupPath.toString(), "xacml.pip.properties");
+		Properties props = new Properties();
+		if (Files.exists(pipProperties)) {
+			logger.warn("addGroup " + id + " file exists: " + pipProperties.toString());
+		} else {
+			try {
+				props = setPIPProperties(props);
+				Files.createFile(pipProperties);
+				try (OutputStream os = Files.newOutputStream(pipProperties)) {
+					props.store(os, "");
+				}
+			} catch (IOException e) {
+				PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "StdEngine", "Failed to create " + pipProperties);
+				throw new PAPException("Failed to create " + id);
+			}	
+
+		}
+		//
+		// Ok now add it
+		//
+		StdPDPGroup newGroup = new StdPDPGroup(id, name, description, groupPath);
+		// Add the default PIP configuration. 
+		String list = props.getProperty(XACMLProperties.PROP_PIP_ENGINES);
+        if (list != null && list.length() > 0) {
+            Set<PDPPIPConfig> pipConfigs = new HashSet<>();
+            for (String pipID : list.split("[,]")) {
+                StdPDPPIPConfig config = new StdPDPPIPConfig(pipID, props);
+                if (config.isConfigured()) {
+                    pipConfigs.add(config);
+                }
+            }
+            newGroup.setPipConfigs(pipConfigs);
+        }
+		if (this.groups.add(newGroup)) {
+			// save the new group in our properties and notify any listeners of the change
+			groupChanged(newGroup);
+		}
+
+	}
+	
+
+	
+	
+	/**
+	 * Helper to create a new Group ID.
+	 * Use the Name field to create the Id.
+	 * The Name is expected to not be null; if it is then this method throws an exception.
+	 * The name is supposed to be unique within the current set of groups,
+	 * so creating the ID based on the name will create a unique string.
+	 * 
+	 * @param name
+	 * @return
+	 */
+	private String createNewPDPGroupId(String name) {
+		String id = name;
+		// replace "bad" characters with sequences that will be ok for file names and properties keys.
+		id = id.replace(" ", "_sp_");
+		id = id.replace("\t", "_tab_");
+		id = id.replace("\\", "_bksl_");
+		id = id.replace("/", "_sl_");
+		id = id.replace(":", "_col_");
+		id = id.replace("*", "_ast_");
+		id = id.replace("?", "_q_");
+		id = id.replace("\"", "_quo_");
+		id = id.replace("<", "_lt_");
+		id = id.replace(">", "_gt_");
+		id = id.replace("|", "_bar_");
+		id = id.replace("=", "_eq_");
+		id = id.replace(",", "_com_");
+		id = id.replace(";", "_scom_");
+
+		return id;
+	}
+	
+	
+	@Override
+	public OnapPDP	getPDP(String pdpId) throws PAPException {
+		for (OnapPDPGroup group : this.groups) {
+			for (OnapPDP pdp : group.getOnapPdps()) {
+				if (pdp.getId().equals(pdpId)) {
+					return pdp;
+				}
+			}
+		}
+		return null;
+	}
+
+	
+	@Override
+	public void movePDP(OnapPDP pdp, OnapPDPGroup newGroup) throws PAPException {
+		if (newGroup == null) {
+			throw new NullPointerException("You must specify which group the PDP will belong to.");
+		}
+		PDPGroup currentGroup = this.getPDPGroup(pdp);
+		if (currentGroup == null) {
+			throw new PAPException("PDP must already belong to a group.");
+		}
+		if (currentGroup.equals(newGroup)) {
+			logger.warn("Already in that group.");
+			return;
+		}
+		if (currentGroup instanceof StdPDPGroup && newGroup instanceof StdPDPGroup) {
+			if (((StdPDPGroup) currentGroup).removePDP(pdp)) {
+				boolean result = ((StdPDPGroup) newGroup).addPDP(pdp);
+				if (result) {
+					//
+					// Save the configuration
+					//
+					this.doSave();
+				} else {
+					PolicyLogger.error("Failed to add to new group, putting back into original group.");
+					if (((StdPDPGroup) currentGroup).removePDP(pdp) == false) {
+						PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + "Failed to put PDP back into original group.");
+					}
+				}
+			}
+		} else {
+			String message = "Unknown PDP group class: " + newGroup.getClass().getCanonicalName() + " and " + currentGroup.getClass().getCanonicalName();
+			logger.warn(message);
+			throw new PAPException(message);
+		}
+	}
+
+	
+	@Override
+	public void	updatePDP(OnapPDP pdp) throws PAPException {
+		PDP currentPDP = this.getPDP(pdp.getId());
+		if (currentPDP == null) {
+			String message = "Unknown PDP id '" + pdp.getId() + "'";
+			logger.warn(message);
+			throw new PAPException(message);
+		}
+		
+		// the only things that the user can change are name and description
+		currentPDP.setDescription(pdp.getDescription());
+		currentPDP.setName(pdp.getName());
+		if (currentPDP instanceof OnapPDP && pdp instanceof OnapPDP) {
+			((OnapPDP)currentPDP).setJmxPort(((OnapPDP)pdp).getJmxPort());
+		}
+		this.doSave();
+	}
+	
+	@Override
+	public void removePDP(OnapPDP pdp) throws PAPException {
+		PDPGroup group = this.getPDPGroup(pdp);
+		if (group == null) {
+			throw new NullPointerException();
+		}
+		if (group instanceof StdPDPGroup) {
+			boolean result = ((StdPDPGroup) group).removePDP(pdp);
+			if (result) {
+				this.doSave();
+			}
+			return;
+		}
+		String message = "Unknown PDP group class: " + group.getClass().getCanonicalName();
+		logger.warn(message);
+		throw new PAPException(message);
+	}
+
+	
+	@Override
+	/**
+	 * Should never be called - Detailed status is held on the PDP, not the PAP
+	 */
+	public PDPStatus getStatus(OnapPDP pdp) throws PAPException {
+		return getPDP(pdp.getId()).getStatus();
+	}
+	
+	@Override
+	public void publishPolicy(String id, String name, boolean isRoot, InputStream policy, OnapPDPGroup group) throws PAPException {
+		if (group == null) {
+			throw new NullPointerException();
+		}
+		if (group instanceof StdPDPGroup && this.groups.contains(group)) {
+			((StdPDPGroup) group).publishPolicy(id, name, isRoot, policy);
+			return;
+		}
+		logger.warn("unknown PDP Group: " + group);
+		throw new PAPException("Unknown PDP Group: " + group.getId());
+	}
+
+	// Currently not used on the PAP side.  This is done by ((StdPDPGroup) group).copyPolicyToFile
+	@Override
+	public void copyPolicy(PDPPolicy policy, OnapPDPGroup group)
+			throws PAPException {
+	}
+	
+	
+	@Override
+	public void removePolicy(PDPPolicy policy, OnapPDPGroup group) throws PAPException {
+		if (group == null) {
+			throw new NullPointerException();
+		}
+		if (group instanceof StdPDPGroup && this.groups.contains(group)) {
+			((StdPDPGroup) group).removePolicy(policy);
+			return;
+		}
+		logger.warn("unknown PDP Group: " + group);
+		throw new PAPException("Unknown PDP Group: " + group.getId());
+	}
+
+	
+	//
+	// HELPER methods
+	//
+	
+	private Set<StdPDPGroup>	readProperties(Path repository, Properties properties) throws PAPException {
+		Set<StdPDPGroup> groups = new HashSet<>();
+		//
+		// See if there is a groups property
+		//
+		String groupList = properties.getProperty(PROP_PAP_GROUPS, "");
+		if (groupList == null) {
+			logger.warn("null group list " + PROP_PAP_GROUPS);
+			groupList = "";
+		}
+		if (logger.isDebugEnabled()) {
+			logger.debug("group list: " + groupList);
+		}
+		//
+		// Iterate the groups, converting to a set ensures we have unique groups.
+		//
+		for (String id : Splitter.on(',').trimResults().omitEmptyStrings().split(groupList)) {
+			//
+			// Add our Group Object
+			//
+			StdPDPGroup g = new StdPDPGroup(id.trim(), 
+								id.equals(properties.getProperty(PROP_PAP_GROUPS_DEFAULT, PROP_PAP_GROUPS_DEFAULT_NAME)), 
+								properties,
+								Paths.get(repository.toString(), id));
+
+			//
+			// Add it in
+			//
+			groups.add(g);
+		}
+		//
+		// Dump what we got
+		//
+		if (logger.isDebugEnabled()) {
+			logger.debug("PDP Group List: " + groups.toString());
+		}
+		return groups;
+	}
+	
+	private void saveConfiguration() throws PAPException, IOException {
+		//
+		// Create our properties object
+		//
+		Properties properties = new Properties() {
+			private static final long serialVersionUID = 1L;
+			// For Debugging it is helpful for the file to be in a sorted order,
+			// any by returning the keys in the natural Alpha order for strings we get close enough.
+			// TreeSet is sorted, and this just overrides the normal Properties method to get the keys.
+			@Override
+		    public synchronized Enumeration<Object> keys() {
+		        return Collections.enumeration(new TreeSet<Object>(super.keySet()));
+		    }
+	    };
+		//
+		// Iterate our groups
+		//
+		List<String> ids = new ArrayList<>();
+		for (PDPGroup group : this.groups) {
+			ids.add(group.getId());
+			properties.setProperty(group.getId() + ".name", (group.getName() == null ? "" : group.getName()));
+			properties.setProperty(group.getId() + ".description", (group.getDescription() == null ? "" : group.getDescription()));
+			//
+			// Iterate its PDPs
+			//
+			List<String> pdps = new ArrayList<>();
+			for (PDP pdp : group.getPdps()) {
+				pdps.add(pdp.getId());
+				properties.setProperty(pdp.getId() + ".name", (pdp.getName() == null ? "" : pdp.getName()));
+				properties.setProperty(pdp.getId() + ".description", (pdp.getDescription() == null ? "" : pdp.getDescription()));
+				if (pdp instanceof OnapPDP) {
+					properties.setProperty(pdp.getId() + ".jmxport", (((OnapPDP)pdp).getJmxPort()==0 ? "" : ((OnapPDP)pdp).getJmxPort()).toString());
+				}
+			}
+			String pdpList = "";
+			if (pdps.size() == 1) {
+				pdpList = pdps.get(0);
+			} else if (pdps.size() > 1) {
+				pdpList = Joiner.on(',').skipNulls().join(pdps);
+			}
+			if (logger.isDebugEnabled()) {
+				logger.debug("Group " + group.getId() + " PDPS: " + pdpList);
+			}
+			properties.setProperty(group.getId() + ".pdps", pdpList);
+		}
+		if (ids.isEmpty()) {
+			throw new PAPException("Inconsistency - we have NO groups. We should have at least one.");
+		}
+		String groupList = "";
+		if (ids.size() == 1) {
+			groupList = ids.get(0);
+		} else if (ids.size() > 1){
+			groupList = Joiner.on(',').skipNulls().join(ids);
+		}
+		logger.info("New Group List: " + groupList);
+		
+		properties.setProperty(PROP_PAP_GROUPS, groupList);
+		//
+		// Get the default group
+		//
+		PDPGroup defaultGroup = this.getDefaultGroup();
+		if (defaultGroup == null) {
+			throw new PAPException("Invalid state - no default group.");
+		}
+		properties.setProperty(PROP_PAP_GROUPS_DEFAULT, defaultGroup.getId());
+		//
+		// Now we can save the file
+		//
+		Path file = Paths.get(this.repository.toString(), "xacml.properties");
+		try (OutputStream os = Files.newOutputStream(file)) {
+			properties.store(os, "");
+		}
+	}
+	
+	public static void	removeGroupProperties(String id, Properties properties) {
+		for (Object key : properties.keySet()) {
+			if (key.toString().startsWith(id + ".")) {
+				properties.remove(key);
+			}
+		}
+	}
+	
+	public static void setGroupProperties(PDPGroup group, Properties properties) {
+		//
+		// make sure its in the list of groups
+		//
+		Iterable<String> groups = Splitter.on(',').trimResults().omitEmptyStrings().split( properties.getProperty(PROP_PAP_GROUPS, ""));
+		boolean inList = false;
+		for (String g : groups) {
+			if (g.equals(group.getId())) {
+				inList = true;
+			}
+		}
+		if (inList == false) {
+			Set<String> grps = Sets.newHashSet(groups);
+			grps.add(group.getId());
+			String newGroupList = "";;
+			if (grps.size() == 1) {
+				newGroupList = grps.iterator().next();
+			} else if (grps.size() > 1) {
+				newGroupList = Joiner.on(',').skipNulls().join(grps);
+			}
+			logger.info("New Group List: " + newGroupList);
+			properties.setProperty(PROP_PAP_GROUPS, newGroupList);
+		}
+		//
+		// Set its properties
+		//
+		properties.setProperty(group.getId() + ".name", group.getName());
+		properties.setProperty(group.getId() + ".description", group.getDescription());
+		//
+		// Set its PDP list
+		//
+		if (group.getPdps().size() > 0) {
+			String pdpList = "";
+			if (group.getPdps().size() == 1) {
+				pdpList = group.getPdps().iterator().next().getId();
+			} else if (group.getPdps().size() > 1) {
+				Set<String> ids = new HashSet<>();
+				for (PDP pdp : group.getPdps()) {
+					ids.add(pdp.getId());
+				}
+				pdpList = Joiner.on(',').skipNulls().join(ids);
+			}
+			properties.setProperty(group.getId() + ".pdps", pdpList);
+		} else {
+			properties.setProperty(group.getId() + ".pdps", "");
+		}
+	}
+
+	
+	public void changed() {
+		if (logger.isDebugEnabled()) {
+			logger.debug("changed");
+		}
+		this.doSave();
+		this.fireChanged();
+	}
+
+	public void groupChanged(OnapPDPGroup group) {
+		if (logger.isDebugEnabled()) {
+			logger.debug("groupChanged: " + group);
+		}
+		this.doSave();
+		this.firePDPGroupChanged(group);
+	}
+
+
+	public void pdpChanged(OnapPDP pdp) {
+		if (logger.isDebugEnabled()) {
+			logger.debug("pdpChanged: " + pdp);
+		}
+		this.doSave();
+		this.firePDPChanged(pdp);
+	}
+
+	private void doSave() {
+		try {
+			//
+			// Save the configuration
+			//
+			this.saveConfiguration();
+		} catch (IOException e) {
+			PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "StdEngine", "Failed to save configuration");
+		} catch (PAPException e) {
+			PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "StdEngine", "Failed to save configuration");
+		}		
+	}
+	
+	private Properties setPIPProperties(Properties props){
+		props.setProperty(XACMLProperties.PROP_PIP_ENGINES, "AAF");
+		props.setProperty("AAF.name", "AAFEngine");
+		props.setProperty("AAF.description", "AAFEngine to communicate with AAF to take decisions");
+		props.setProperty("AAF.classname","org.onap.policy.xacml.std.pip.engines.aaf.AAFEngine");
+		// read from PIP properties file. 
+		Path file = Paths.get(pipPropertyFile);
+		if (!Files.notExists(file)) {
+			InputStream in;
+			Properties prop = new Properties();
+			try {
+				in = new FileInputStream(file.toFile());
+				prop.load(in);
+			} catch (IOException e) {
+				PolicyLogger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "can not load the pip properties from file" +e);
+			}
+			props = prop;
+		}
+		return props;
+	}
+
+	
+	@Override
+	public Set<OnapPDPGroup> getOnapPDPGroups() throws PAPException {
+		final Set<OnapPDPGroup> grps = new HashSet<>();
+		for (OnapPDPGroup g : this.groups) {
+			grps.add(g);
+		}
+		return Collections.unmodifiableSet(grps);
+	}
+
+	@Override
+	public OnapPDPGroup getPDPGroup(OnapPDP pdp) throws PAPException {
+		for (OnapPDPGroup group : this.groups) {
+			if (group.getPdps().contains(pdp)) {
+				return group;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public void SetDefaultGroup(OnapPDPGroup group) throws PAPException {
+		boolean changesMade = false;
+		for (OnapPDPGroup aGroup : groups) {
+			if (aGroup.getId().equals(group.getId())) {
+				if ( ! aGroup.isDefaultGroup()) {
+					if (aGroup instanceof StdPDPGroup) {
+						((StdPDPGroup) aGroup).setDefault(true);
+						changesMade = true;
+					} else {
+						throw new IllegalArgumentException("Group in groups of unknown type '" + aGroup.getClass().getName() + "'");
+					}
+				}
+			} else {
+				// not the new default group
+				if (aGroup.isDefaultGroup()) {
+					if (aGroup instanceof StdPDPGroup) {
+						((StdPDPGroup) aGroup).setDefault(false);
+						changesMade = true;
+					} else {
+						throw new IllegalArgumentException("Group in groups of unknown type '" + aGroup.getClass().getName() + "'");
+					}
+				}
+			}
+		}
+		if (changesMade) {
+			this.doSave();
+		}
+		
+		return;	
+		
+	}
+
+	@Override
+	public void newPDP(String id, OnapPDPGroup group, String name, String description, int jmxport)
+			throws PAPException, NullPointerException {
+		if (group == null) {
+			throw new PAPException("You must specify which group the PDP will belong to.");
+		}
+		if (this.groups.contains(group) == false) {
+			throw new PAPException("Unknown group, not in our list.");
+		}
+		for (OnapPDP p : group.getOnapPdps()) {
+			if (p.getId().equals(id)) {
+				throw new PAPException("A PDP with this ID exists.");
+			}
+		}
+		if (group instanceof StdPDPGroup) {
+			StdPDP pdp = new StdPDP(id, name, description, jmxport);
+			if (((StdPDPGroup) group).addPDP(pdp)) {
+				//
+				// Save the properties and notify any listeners
+				//
+				pdpChanged(pdp);
+				return;
+			}
+		}
+		return;
+		
+	}
+
+	@Override
+	public void updateGroup(OnapPDPGroup group) throws PAPException {
+		if (group == null || group.getId() == null) {
+			throw new PAPException("Group or id is null");
+		}
+		if (group.getName() == null || group.getName().trim().length() == 0) {
+			throw new PAPException("New name for group cannot be null or blank");
+		}
+		StdPDPGroup existingGroup = (StdPDPGroup)getGroup(group.getId());
+		if (existingGroup == null) {
+			throw new PAPException("Update found no existing group with id '" + group.getId() + "'");
+		}
+		
+		
+		// We do dramatically different things when the Name changes
+		// because the Name is essentially the identity of the group (as the User knows it) so when the Identity changes we have to change the group ID.
+		if (group.getName().equals(existingGroup.getName())) {
+
+			// update the disk
+			try {
+				((StdPDPGroup)group).saveGroupConfiguration();
+			} catch (IOException e) {
+				throw new PAPException("Unable to save new configuration for '" + group.getName() + "': " + e.getMessage());
+			}
+			// update the group in the set by simply replacing the old instance with the new one
+			this.groups.remove(existingGroup);
+			this.groups.add((StdPDPGroup)group);
+			
+		} else {
+			// the name/identity of the group has changed
+			// generate the new id
+			String newId = createNewPDPGroupId(group.getName());
+			
+			// make sure no other group uses the new id
+			for (OnapPDPGroup g : groups) {
+				if (g.getId().equals(newId)) {
+					throw new PAPException("Replacement name maps to ID '" + newId + "' which is already in use");
+				}
+			}
+			((StdPDPGroup)group).setId(newId);
+
+			// rename the existing directory to the new id
+			Path oldPath = existingGroup.getDirectory();
+			Path newPath = Paths.get(oldPath.getParent().toString(), newId);
+			((StdPDPGroup)group).setDirectory(newPath);
+			
+			try {
+				boolean success = oldPath.toFile().renameTo(newPath.toFile());
+				if ( ! success) {
+					throw new PAPException("Unable to rename directory; reason unknown");
+				}
+			} catch (Exception e) {
+				PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "StdEngine", "Unable to rename directory");
+				throw new PAPException("Unable to move directory from '" + oldPath + "' to '" + newPath + "': " + e.getMessage());
+			}
+			// update the disk
+			try {
+				((StdPDPGroup)group).saveGroupConfiguration();
+			} catch (IOException e) {
+				throw new PAPException("Unable to save new configuration for '" + group.getName() + "': " + e.getMessage());
+			}
+			
+			// save the new group into the Set
+			groups.remove(existingGroup);
+			groups.add((StdPDPGroup)group);
+			
+		}
+		
+		// perhaps only the group changed, but if the name/id changed it may look to a listener like more than one group
+		changed();
+
+		
+	}
+
+	@Override
+	public void removeGroup(OnapPDPGroup group, OnapPDPGroup newGroup) throws PAPException, NullPointerException {
+		if (group == null) {
+			throw new NullPointerException();
+		}
+		//
+		// Does this group exist?
+		//
+		if (this.groups.contains(group) == false) {
+			PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + "This group doesn't exist.");
+			throw new PAPException("The group '" + group.getId() + "' does not exist");
+		}
+		//
+		// Is it the default group?
+		//
+		if (group.isDefaultGroup()) {
+			throw new PAPException("You cannot delete the default group.");
+		}
+		Set<OnapPDP> pdps = group.getOnapPdps();
+		//
+		// Are there PDPs? If so, then we need a target group
+		//
+		if (pdps.isEmpty() == false && newGroup == null) {
+			throw new NullPointerException("Group targeted for deletion has PDPs, you must provide a new group for them.");
+		}
+		//
+		// Move the PDPs
+		//
+		if (pdps.isEmpty() == false) {
+			if (! (newGroup instanceof StdPDPGroup)) {
+				throw new PAPException("Unexpected class for newGroup: " + newGroup.getClass().getCanonicalName());
+			}
+			// The movePDP function will modify the set of PDPs in the group.
+			// To avoid concurrent modification exceptions we need to duplicate the list before calling that function.
+			List<OnapPDP> pdpList = new ArrayList<>();
+			for (OnapPDP pdp : pdps) {
+				pdpList.add(pdp);
+			}
+			// now we can use the PDPs from the list without having ConcurrentAccessExceptions
+			for (OnapPDP pdp : pdpList) {
+				this.movePDP(pdp, newGroup);
+			}
+		}
+		//
+		// remove the directory for the group
+		//
+		String id = group.getId();
+		Path groupPath = Paths.get(this.repository.toString(), id);
+		//
+		// If it exists already
+		//
+		if ( ! Files.exists(groupPath)) {
+			logger.warn("removeGroup " + id + " directory does not exist" + groupPath.toString());
+		} else {
+			try {
+				Files.walkFileTree(groupPath, new SimpleFileVisitor<Path>() {
+
+					@Override
+					public FileVisitResult visitFile(Path file,
+							BasicFileAttributes attrs) throws IOException {
+						Files.delete(file);
+						return super.visitFile(file, attrs);
+					}
+					
+				});
+				//
+				// delete the directory
+				//
+				Files.delete(groupPath);
+			} catch (IOException e) {
+				PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "StdEngine", "Failed to delete " + groupPath);
+				throw new PAPException("Failed to delete " + id);
+			}
+		}
+		
+		// remove the group from the set of all groups
+		groups.remove(group);
+		
+		//
+		// Save changes
+		//
+		changed();
+		this.doSave();
+		return;
+		
+	}
+
+}
diff --git a/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pap/StdEngineFactory.java b/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pap/StdEngineFactory.java
new file mode 100644
index 0000000..ee67856
--- /dev/null
+++ b/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pap/StdEngineFactory.java
@@ -0,0 +1,57 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP-XACML
+ * ================================================================================
+ * 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.std.pap;
+
+import org.onap.policy.common.logging.eelf.MessageCodes;
+import org.onap.policy.common.logging.eelf.PolicyLogger;
+
+import java.io.IOException;
+import java.util.Properties;
+
+import org.onap.policy.xacml.api.pap.ONAPPapEngineFactory;
+import org.onap.policy.xacml.api.pap.PAPPolicyEngine;
+
+import com.att.research.xacml.api.pap.PAPException;
+import com.att.research.xacml.util.FactoryException;
+
+public class StdEngineFactory extends ONAPPapEngineFactory {
+	
+	@Override
+	public PAPPolicyEngine newEngine() throws FactoryException, PAPException {
+		try {
+			return (PAPPolicyEngine) new StdEngine();
+		} catch (IOException e) {
+			PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "StdEngineFactory", "Failed to create engine");
+			return null;
+		}
+	}
+
+	@Override
+	public PAPPolicyEngine newEngine(Properties properties) throws FactoryException,
+			PAPException {
+		try {
+			return (PAPPolicyEngine) new StdEngine(properties);
+		} catch (IOException e) {
+			PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "StdEngineFactory", "Failed to create engine");
+			return null;
+		}
+	}
+	
+}
diff --git a/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pap/StdPAPPolicy.java b/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pap/StdPAPPolicy.java
new file mode 100644
index 0000000..d69f38d
--- /dev/null
+++ b/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pap/StdPAPPolicy.java
@@ -0,0 +1,910 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP-XACML
+ * ================================================================================
+ * 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.std.pap;
+
+import java.io.Serializable;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.onap.policy.xacml.api.pap.OnapPAPPolicy;
+
+public class StdPAPPolicy implements OnapPAPPolicy, Serializable{
+	private static final long serialVersionUID = 5260230629397322000L;
+
+	private String policyName = null;
+	private String oldPolicyFileName = null;
+	private String policyDescription = null;
+	private String onapName = null;
+	private String configName = null;
+	private Map<String, String> dyanamicFieldConfigAttributes = new HashMap<>();
+	private Map<String, String> dropDownMap = new HashMap<>();
+	private Map<String, String> dynamicSettingsMap = new HashMap<>();
+	private List<String> dynamicRuleAlgorithmLabels;
+	private List<String> dynamicRuleAlgorithmCombo;
+	private List<String> dynamicRuleAlgorithmField1;
+	private List<String> dynamicRuleAlgorithmField2;
+	private List<Object> dynamicVariableList;
+	private List<String> dataTypeList;
+	private String configBodyData = null;
+	private String policyID = null;
+	private String ruleID = null;
+	private String brmsController;
+	private ArrayList<String> brmsDependency;
+	private String configType = null;
+	private Boolean editPolicy = false;
+	private Boolean draft = false;
+	private String version = null;
+	private String domain = null;
+	private String configPolicyType = null; 
+	private String jsonBody = null;
+	private String serviceType = null;
+	private Integer highestVersion = null;
+	private URI location = null;
+	private String actionPerformer = null;
+	private String actionAttribute = null;
+	private String actionBody = null;
+	private String actionDictHeader = null;
+	private String actionDictType = null;
+	private String actionDictUrl = null;
+	private String actionDictMethod = null;
+	private String uuid = null;
+	private String msLocation = null;
+	private String priority = null;
+	private Map<String,String> drlRuleAndUIParams=null;
+	private String deleteCondition = null;
+	private String dictionaryType = null;
+	private String dictionary = null;
+	private String dictionaryFields = null;
+	private String providerComboBox = null;
+	private String riskType = null;
+	private String guard = null;
+	private String riskLevel;
+	private String ttlDate = null;
+
+
+	public StdPAPPolicy() {
+
+	}
+
+	//Constructor for sending location when pushing policies
+	public StdPAPPolicy(URI location) {
+		this.location = location;
+	}
+
+	//Constructor for Validating Config Policies
+	public StdPAPPolicy(String policyName, String body, String configType, String configPolicyType) {
+		this.policyName = policyName;
+		this.configBodyData = body;
+		this.configType = configType;
+		this.configPolicyType = configPolicyType;
+	}
+
+	//convenience constructor
+	public StdPAPPolicy(String configPolicyType, String policyName, String description, String onapName, String configName, Map<String, String> attributes, String configType, 
+			String body, Boolean editPolicy, String domain, String riskLevel, String riskType, String guard, String ttlDate){
+		this(configPolicyType, policyName, description, onapName, configName, attributes, configType, 
+				body, editPolicy, domain, 1, riskLevel, riskType, guard, ttlDate);
+	}
+
+	//Constructor for Create/Update Action Policies from API
+	public StdPAPPolicy(String policyName, String description, Map<String, String> attributes, List<String> dynamicRuleAlgorithmLabels, List<String> dynamicRuleAlgorithmCombo, 
+			List<String> dynamicRuleAlgorithmField1, List<String> dynamicRuleAlgorithmField2, String actionPerformer,String actionAttribute, Boolean editPolicy, 
+			String domain, int highestVersion) {
+
+		this.policyName = policyName;
+		this.policyDescription = description;
+		this.dyanamicFieldConfigAttributes = attributes;
+		this.dynamicRuleAlgorithmLabels = dynamicRuleAlgorithmLabels;
+		this.dynamicRuleAlgorithmCombo = dynamicRuleAlgorithmCombo;
+		this.dynamicRuleAlgorithmField1 = dynamicRuleAlgorithmField1;
+		this.dynamicRuleAlgorithmField2 = dynamicRuleAlgorithmField2;
+		this.actionPerformer = actionPerformer;
+		this.actionAttribute = actionAttribute;
+		this.editPolicy = editPolicy;
+		this.domain = domain;
+		this.highestVersion = highestVersion;	
+
+	}
+
+	//Constructor for Create/Update Decision Policies from Admin Console
+	public StdPAPPolicy(String policyName, String description, String onapName, String providerComboBox, Map<String, String> attributes, Map<String, String> settings, 
+			List<String> dynamicRuleAlgorithmLabels, List<String> dynamicRuleAlgorithmCombo, List<String> dynamicRuleAlgorithmField1, 
+			List<String> dynamicRuleAlgorithmField2, Map<String, String> dropDownMap, List<Object> dynamicVariableList, 
+			List<String> dataTypeList, Boolean editPolicy, String domain, int highestVersion) {
+
+		this.policyName = policyName;
+		this.policyDescription = description;
+		this.onapName = onapName;
+		this.setProviderComboBox(providerComboBox);
+		this.dyanamicFieldConfigAttributes = attributes;
+		this.dynamicSettingsMap = settings;
+		this.dynamicRuleAlgorithmLabels = dynamicRuleAlgorithmLabels;
+		this.dynamicRuleAlgorithmCombo = dynamicRuleAlgorithmCombo;
+		this.dynamicRuleAlgorithmField1 = dynamicRuleAlgorithmField1;
+		this.dynamicRuleAlgorithmField2 = dynamicRuleAlgorithmField2;
+		this.dynamicVariableList = dynamicVariableList;
+		this.dataTypeList = dataTypeList;
+		this.dropDownMap = dropDownMap;
+		this.editPolicy = editPolicy;
+		this.domain = domain;
+		this.highestVersion = highestVersion;	
+
+	}
+
+
+	//Constructor for Create Config Policies from API and Admin Console
+	//Constructor for Updating Config Policies from the API
+	public StdPAPPolicy(String configPolicyType, String policyName, String description, String onapName, String configName, Map<String, String> attributes, String configType, 
+			String body, Boolean editPolicy, String domain, int highestVersion, String riskLevel, String riskType, String guard, String ttlDate) {
+
+		this.configPolicyType = configPolicyType;
+		this.policyName = policyName;
+		this.policyDescription = description;
+		this.onapName = onapName;
+		this.configName = configName;
+		this.dyanamicFieldConfigAttributes = attributes;
+		this.configType = configType;
+		this.configBodyData = body;
+		this.editPolicy = editPolicy;
+		this.domain = domain;
+		this.highestVersion = highestVersion;
+		this.riskLevel = riskLevel;
+		this.riskType = riskType;
+		this.guard = guard;	
+		this.ttlDate = ttlDate;
+	}
+
+	//convenience constructor
+	public StdPAPPolicy (String configPolicyType, String policyName, String description, String onapName, String configName, Map<String, String> attributes, String body, String policyID, 
+			String ruleID, String configType, Boolean editPolicy, String version, String domain, String riskLevel, String riskType, String guard, String ttlDate) {
+		this (configPolicyType, policyName, description, onapName, configName, attributes, body, policyID, 
+				ruleID, configType, editPolicy, version, domain,  1, riskLevel, riskType, guard, ttlDate); 
+	}
+
+	//Constructor for Updating Config Policies from Admin Console
+	public StdPAPPolicy (String configPolicyType, String policyName, String description, String onapName, String configName, Map<String, String> attributes, String body, String policyID, 
+			String ruleID, String configType, Boolean editPolicy, String version, String domain,  int highestVersion, String riskLevel, String riskType, String guard, String ttlDate) {
+
+		this.configPolicyType = configPolicyType;
+		this.policyName = policyName;
+		this.policyDescription = description;
+		this.onapName = onapName;
+		this.configName = configName;
+		this.dyanamicFieldConfigAttributes = attributes;
+		this.configBodyData = body;
+		this.policyID = policyID;
+		this.ruleID = ruleID;
+		this.configType = configType;
+		this.editPolicy = editPolicy;
+		this.version = version;
+		this.domain = domain;
+		this.highestVersion = highestVersion;
+		this.riskLevel = riskLevel;
+		this.riskType = riskType;
+		this.guard = guard;	
+		this.ttlDate = ttlDate;
+	}
+
+
+	//Constructor for Creating Config Firewall Policies
+	public StdPAPPolicy (String configPolicyType, String policyName, String description, String configName, 
+			Boolean editPolicy, String domain, String jsonBody,  Integer highestVersion, String riskLevel, String riskType, String guard, String ttlDate) {
+
+		this.configPolicyType = configPolicyType;
+		this.policyName = policyName;
+		this.policyDescription = description;
+		this.configName = configName;
+		this.editPolicy = editPolicy;
+		this.domain = domain;
+		this.jsonBody = jsonBody;
+		this.highestVersion = highestVersion;
+		this.riskLevel = riskLevel;
+		this.riskType = riskType;
+		this.guard = guard;	
+		this.ttlDate = ttlDate;
+
+	}
+
+	//Constructor for Creating Goc Policies
+	public StdPAPPolicy (String configPolicyType, String policyName, String description, String configName, 
+			Boolean editPolicy, String domain, String jsonBody,  Integer highestVersion, String eCompName, String riskLevel, String riskType, String guard, String ttlDate) {
+
+		this.configPolicyType = configPolicyType;
+		this.policyName = policyName;
+		this.policyDescription = description;
+		this.configName = configName;
+		this.editPolicy = editPolicy;
+		this.domain = domain;
+		this.jsonBody = jsonBody;
+		this.highestVersion = highestVersion;
+		this.onapName=eCompName;
+		this.riskLevel = riskLevel;
+		this.riskType = riskType;
+		this.guard = guard;	
+		this.ttlDate = ttlDate;
+	}
+
+	//Constructor for Creating BRMS Policies from the Admin Console
+	public StdPAPPolicy (String configPolicyType, String policyName, String description, 
+			String configName, Boolean editPolicy, String domain, 
+			Map<String,String> dyanamicFieldConfigAttributes, Integer highestVersion, String eCompName, 
+			String configBodyData, String riskLevel, String riskType, String guard, String ttlDate, String brmsController, ArrayList<String> brmsDependency) {
+
+		this.configPolicyType = configPolicyType;
+		this.policyName = policyName;
+		this.policyDescription = description;
+		this.configName = configName;
+		this.editPolicy = editPolicy;
+		this.domain = domain;
+		this.dyanamicFieldConfigAttributes = dyanamicFieldConfigAttributes;
+		this.highestVersion = highestVersion;
+		this.onapName=eCompName;
+		this.configBodyData=configBodyData;
+		this.riskLevel = riskLevel;
+		this.riskType = riskType;
+		this.guard = guard;	
+		this.ttlDate = ttlDate;
+		this.brmsController = brmsController;
+		this.brmsDependency = brmsDependency;
+	}
+
+	//Constructor for Creating BRMS Param Policies from the Admin Console
+	public StdPAPPolicy (String configPolicyType, String policyName, String description, 
+			String configName, Boolean editPolicy, String domain, 
+			Map<String,String> dyanamicFieldConfigAttributes, Integer highestVersion, String eCompName, 
+			String configBodyData,Map<String,String> drlRuleAndUIParams, String riskLevel, String riskType, String guard, String ttlDate, String brmsController, ArrayList<String> brmsDependency) {
+
+		this.configPolicyType = configPolicyType;
+		this.policyName = policyName;
+		this.policyDescription = description;
+		this.configName = configName;
+		this.editPolicy = editPolicy;
+		this.domain = domain;
+		this.dyanamicFieldConfigAttributes = dyanamicFieldConfigAttributes;
+		this.highestVersion = highestVersion;
+		this.onapName=eCompName;
+		this.configBodyData=configBodyData;
+		this.drlRuleAndUIParams=drlRuleAndUIParams;
+		this.riskLevel = riskLevel;
+		this.riskType = riskType;
+		this.guard = guard;	
+		this.ttlDate = ttlDate;
+		this.brmsController = brmsController;
+		this.brmsDependency = brmsDependency;
+	}
+
+	//Constructor for Creating CloseLoop_Fault and Performance Metric Policies
+	public StdPAPPolicy (String configPolicyType, String policyName, String description, String onapName, 
+			String jsonBody, Boolean draft, String oldPolicyFileName, String serviceType, Boolean editPolicy, 
+			String domain, Integer highestVersion, String riskLevel, String riskType, String guard, String ttlDate) {
+
+		this.configPolicyType = configPolicyType;
+		this.policyName = policyName;
+		this.policyDescription = description;
+		this.onapName = onapName;
+		this.jsonBody = jsonBody;
+		this.draft = draft;
+		this.oldPolicyFileName = oldPolicyFileName;
+		this.serviceType = serviceType;
+		this.editPolicy = editPolicy;
+		this.domain = domain;
+		this.highestVersion = highestVersion;
+		this.riskLevel = riskLevel;
+		this.riskType = riskType;
+		this.guard = guard;	
+		this.ttlDate = ttlDate;
+	}
+
+	//Constructor for Updating Config Firewall Policies from the Admin Console
+	public StdPAPPolicy (String configPolicyType, String policyName, String description, String configName, Boolean editPolicy, String domain, String policyID, 
+			String ruleID, String version, String jsonBody,  Integer highestVersion, String riskLevel, String riskType, String guard, String ttlDate) {
+
+		this.configPolicyType = configPolicyType;
+		this.policyName = policyName;
+		this.policyDescription = description;
+		this.configName = configName;
+		this.editPolicy = editPolicy;
+		this.domain = domain;
+		this.policyID = policyID;
+		this.ruleID = ruleID;
+		this.version = version;
+		this.jsonBody = jsonBody;
+		this.highestVersion = highestVersion;
+		this.riskLevel = riskLevel;
+		this.riskType = riskType;
+		this.guard = guard;	
+		this.ttlDate = ttlDate;
+	}
+
+	//Constructor for Micro Service Creating/Updating Policies from the Admin Console
+	public StdPAPPolicy(String configPolicyType, String policyName, String description, String onapName, String configName, String serviceType, String uuid, 
+			String msLocation, String jsonBody, String priority, String version, Boolean editPolicy, String domain, int highestVersion, String riskLevel, 
+			String riskType, String guard, String ttlDate) {
+
+		this.configPolicyType = configPolicyType;
+		this.policyName = policyName;
+		this.policyDescription = description;
+		this.onapName = onapName;
+		this.configName = configName;
+		this.serviceType = serviceType;
+		this.uuid = uuid;
+		this.msLocation = msLocation;
+		this.priority = priority;
+		this.version = version;
+		this.jsonBody = jsonBody;
+		this.editPolicy = editPolicy;
+		this.domain = domain;
+		this.highestVersion = highestVersion;
+		this.riskLevel = riskLevel;
+		this.riskType = riskType;
+		this.guard = guard;	
+		this.ttlDate = ttlDate;
+	}
+
+	//Constructor for Updating Goc Policies from the Admin Console
+	public StdPAPPolicy (String configPolicyType, String policyName, String description, 
+			String configName, Boolean editPolicy, String domain, 
+			String policyID, String ruleID, String version, 
+			String jsonBody,  Integer highestVersion, String eCompName,String riskLevel, String riskType, String guard, String ttlDate) {
+
+		this.configPolicyType = configPolicyType;
+		this.policyName = policyName;
+		this.policyDescription = description;
+		this.configName = configName;
+		this.editPolicy = editPolicy;
+		this.domain = domain;
+		this.policyID = policyID;
+		this.ruleID = ruleID;
+		this.version = version;
+		this.jsonBody = jsonBody;
+		this.highestVersion = highestVersion;
+		this.onapName=eCompName;
+		this.riskLevel = riskLevel;
+		this.riskType = riskType;
+		this.guard = guard;	
+		this.ttlDate = ttlDate;
+	}
+
+	//Constructor for Updating Brms Policies from the Admin Console
+	public StdPAPPolicy (String configPolicyType, String policyName, String description, 
+			String configName, Boolean editPolicy, String domain, 
+			String policyID, String ruleID, String version, 
+			Map<String,String> dyanamicFieldConfigAttributes, Integer highestVersion, String eCompName, 
+			String configBodyData , String riskLevel, String riskType, String guard, String ttlDate
+			) {
+		this.configPolicyType = configPolicyType;
+		this.policyName = policyName;
+		this.policyDescription = description;
+		this.configName = configName;
+		this.editPolicy = editPolicy;
+		this.domain = domain;
+		this.policyID = policyID;
+		this.ruleID = ruleID;
+		this.version = version;
+		this.dyanamicFieldConfigAttributes = dyanamicFieldConfigAttributes;
+		this.highestVersion = highestVersion;
+		this.onapName=eCompName;
+		this.configBodyData=configBodyData;
+		this.riskLevel = riskLevel;
+		this.riskType = riskType;
+		this.guard = guard;	
+		this.ttlDate = ttlDate;
+	}
+
+	//Constructor for Updating Brms Param Policies from the Admin Console
+	public StdPAPPolicy (String configPolicyType, String policyName, String description, 
+			String configName, Boolean editPolicy, String domain, 
+			String policyID, String ruleID, String version, 
+			Map<String,String> dyanamicFieldConfigAttributes, Integer highestVersion, String eCompName, 
+			Map<String,String> drlRuleAndUIParams, String riskLevel, String riskType, String guard, String ttlDate
+			) {
+		this.configPolicyType = configPolicyType;
+		this.policyName = policyName;
+		this.policyDescription = description;
+		this.configName = configName;
+		this.editPolicy = editPolicy;
+		this.domain = domain;
+		this.policyID = policyID;
+		this.ruleID = ruleID;
+		this.version = version;
+		this.dyanamicFieldConfigAttributes = dyanamicFieldConfigAttributes;
+		this.highestVersion = highestVersion;
+		this.onapName=eCompName;
+		this.drlRuleAndUIParams=drlRuleAndUIParams;
+		this.riskLevel = riskLevel;
+		this.riskType = riskType;
+		this.guard = guard;	
+		this.ttlDate = ttlDate;
+	}
+
+	// Constructor for deleting policies from the API
+	public StdPAPPolicy(String policyName, String deleteCondition) {
+		this.policyName = policyName;
+		this.deleteCondition = deleteCondition;
+	}
+
+	// Constructor for creating dictionary items from the API>
+	public StdPAPPolicy(String dictionaryType, String dictionary, String dictionaryFields) {
+		this.dictionaryType = dictionaryType;
+		this.dictionary = dictionary;
+		this.dictionaryFields = dictionaryFields;
+	}
+
+	@Override
+	public String getPolicyName() {
+		return policyName;
+	}
+
+	@Override
+	public String getPolicyDescription() {
+		return policyDescription;
+	}
+
+	@Override
+	public String getOnapName() {
+		return onapName;
+	}
+
+	@Override
+	public String getConfigName() {
+		return configName;
+	}
+
+	@Override
+	public Map<String, String> getDynamicFieldConfigAttributes() {
+		return dyanamicFieldConfigAttributes;
+	}
+
+	@Override
+	public String getConfigBodyData() {
+		return configBodyData;
+	}
+
+	@Override
+	public String getPolicyID() {
+		return policyID;
+	}
+
+	@Override
+	public String getRuleID() {
+		return ruleID;
+	}
+
+	@Override
+	public String getConfigType() {
+		return configType;
+	}
+
+	@Override
+	public Boolean isEditPolicy() {
+		return editPolicy;
+	}
+
+	@Override
+	public Boolean isDraft() {
+		return draft;
+	}
+
+	@Override
+	public String getVersion() {
+		return version;
+	}
+
+	@Override
+	public String getDomainDir() {
+		return domain;
+	}
+
+	@Override
+	public String getConfigPolicyType() {
+		return configPolicyType;
+	}
+
+	@Override
+	public String getJsonBody() {
+		return jsonBody;
+	}
+
+	@Override
+	public Integer getHighestVersion() {
+		return highestVersion;
+	}
+
+	@Override
+	public URI getLocation() {
+		return location;
+	}
+
+	@Override
+	public List<String> getDynamicRuleAlgorithmLabels() {
+		return dynamicRuleAlgorithmLabels;
+	}
+
+	@Override
+	public List<String> getDynamicRuleAlgorithmCombo() {
+		return dynamicRuleAlgorithmCombo;
+	}
+
+	@Override
+	public List<String> getDynamicRuleAlgorithmField1() {
+		return dynamicRuleAlgorithmField1;
+	}
+
+	@Override
+	public List<String> getDynamicRuleAlgorithmField2() {
+		return dynamicRuleAlgorithmField2;
+	}
+
+	@Override
+	public String getActionPerformer() {
+		return actionPerformer;
+	}
+
+	@Override
+	public String getActionAttribute() {
+		return actionAttribute;
+	}
+
+	@Override
+	public String getActionBody() {
+		return actionBody;
+	}
+
+	@Override
+	public Map<String, String> getDropDownMap() {
+		return dropDownMap;
+	}
+
+	@Override
+	public String getActionDictHeader() {
+		return actionDictHeader;
+	}
+
+	@Override
+	public String getActionDictType() {
+		return actionDictType;
+	}
+
+	@Override
+	public String getActionDictUrl() {
+		return actionDictUrl;
+	}
+
+	@Override
+	public String getActionDictMethod() {
+		return actionDictMethod;
+	}
+
+	@Override
+	public Map<String, String> getDynamicSettingsMap() {
+		return dynamicSettingsMap;
+	}
+
+	@Override
+	public List<Object> getDynamicVariableList() {
+		return dynamicVariableList;
+	}
+
+	@Override
+	public List<String> getDataTypeList() {
+		return dataTypeList;
+	}
+
+	@Override
+	public String getOldPolicyFileName() {
+		return oldPolicyFileName;
+	}
+
+	@Override
+	public String getServiceType() {
+		return serviceType;
+	}
+
+	@Override
+	public String getUuid() {
+		return uuid;
+	}
+
+	@Override
+	public String getMsLocation() {
+		return msLocation;
+	}
+
+	@Override
+	public String getPriority() {
+		return priority;
+	}
+
+	@Override
+	public String getDeleteCondition() {
+		return deleteCondition;
+	}
+
+	@Override
+	public String getDictionaryType() {
+		return dictionaryType;
+	}
+
+	@Override
+	public String getDictionary() {
+		return dictionary;
+	}
+
+	@Override
+	public String getTTLDate(){
+		return ttlDate;
+	}
+
+	@Override
+	public String getDictionaryFields() {
+		return dictionaryFields;
+	}
+
+	@Override
+	public String getRiskType() {
+		return riskType;
+	}
+
+	@Override
+	public String getRiskLevel() {
+		return riskLevel;
+	}
+
+	@Override
+	public String getGuard() {
+		return guard;
+	}
+
+	@Override
+	public String toString() {
+		return "StdPAPPolicy [policyName=" + policyName + ", policyDescription=" + policyDescription + ", onapName="
+				+ onapName + ", configName=" + configName + ", dyanamicFieldConfigAttributes=" + dyanamicFieldConfigAttributes + ", configBodyData=" + configBodyData
+				+ ", policyID=" + policyID + ", ruleID=" + ruleID + ", configType=" + configType + ", editPolicy=" + ", version=" + ", domain=" + domain  
+				+ ", configPolicyType=" + configPolicyType + ", jsonBody=" + jsonBody + ", highestVersion=" + highestVersion + ", location=" + location 
+				+ ",dynamicRuleAlgorithmLabels=" + dynamicRuleAlgorithmLabels + ",dynamicRuleAlgorithmCombo=" + dynamicRuleAlgorithmCombo 
+				+ ",dynamicRuleAlgorithmField1=" + dynamicRuleAlgorithmField1 + ",dynamicRuleAlgorithmField2=" + dynamicRuleAlgorithmField2 
+				+ ",actionPerformer=" + actionPerformer + ",actionAttribute=" + actionAttribute + ",actionBody=" + actionBody + ",dropDownMap=" + dropDownMap
+				+ ",actionDictHeader=" + actionDictHeader + ",actionDictType=" + actionDictType + ",actionDictUrl=" + actionDictUrl 
+				+ ",actionDictMethod=" + actionDictMethod + ",dynamicSettingsMap=" + dynamicSettingsMap + ",dynamicVariableList=" + dynamicVariableList + ",providerComboBox=" + providerComboBox
+				+ ",dataTypeList=" + dataTypeList + ",draft=" + ",oldPolicyFileName=" + oldPolicyFileName + ",serviceType=" + serviceType
+				+ ",uuid=" + uuid + ",msLocation=" + msLocation + ",priority=" + priority + ",deleteCondition=" + deleteCondition + ",dictionaryType=" + dictionaryType 
+				+ ",dictionary=" + dictionary + ",dictionaryFields=" + dictionaryFields + ",uuid=" + uuid + ",msLocation=" + msLocation + ",priority=" 
+				+ priority + ",deleteCondition=" + deleteCondition + ",riskType="+riskType + ",riskLevel="+riskLevel + ",guard="+ guard + ",ttlDate="+ ttlDate + "]";
+	}
+
+	// Methods needed for JSON Deserialization
+	public void setPolicyName(String policyName) {
+		this.policyName = policyName;
+	}
+
+	public void setPolicyDescription(String policyDescription) {
+		this.policyDescription = policyDescription;
+	}
+
+	public void setOnapName(String onapName) {
+		this.onapName = onapName;
+	}
+
+	public void setConfigName(String configName) {
+		this.configName = configName;
+	}
+
+	public void setDyanamicFieldConfigAttributes(
+			Map<String, String> dyanamicFieldConfigAttributes) {
+		this.dyanamicFieldConfigAttributes = dyanamicFieldConfigAttributes;
+	}
+
+	public void setConfigBodyData(String configBodyData) {
+		this.configBodyData = configBodyData;
+	}
+
+	public void setPolicyID(String policyID) {
+		this.policyID = policyID;
+	}
+
+	public void setRuleID(String ruleID) {
+		this.ruleID = ruleID;
+	}
+
+	public void setConfigType(String configType) {
+		this.configType = configType;
+	}
+
+	public void setEditPolicy(Boolean editPolicy) {
+		this.editPolicy = editPolicy;
+	}
+
+	public void setVersion(String version) {
+		this.version = version;
+	}
+
+	public void setDomainDir(String domain) {
+		this.domain = domain;
+	}
+
+	public void setConfigPolicyType(String configPolicyType) {
+		this.configPolicyType = configPolicyType;
+	}
+
+	public void setJsonBody(String jsonBody) {
+		this.jsonBody = jsonBody;
+	}
+
+	public void setHighestVersion(Integer highestVersion) {
+		this.highestVersion = highestVersion;
+	}
+
+	public void setLocation (URI location) {
+		this.location = location;
+	}
+
+	public void setDynamicRuleAlgorithmLabels(
+			List<String> dynamicRuleAlgorithmLabels) {
+		this.dynamicRuleAlgorithmLabels = dynamicRuleAlgorithmLabels;
+	}
+
+	public void setDynamicRuleAlgorithmCombo(List<String> dynamicRuleAlgorithmCombo) {
+		this.dynamicRuleAlgorithmCombo = dynamicRuleAlgorithmCombo;
+	}
+
+	public void setDynamicRuleAlgorithmField1(
+			List<String> dynamicRuleAlgorithmField1) {
+		this.dynamicRuleAlgorithmField1 = dynamicRuleAlgorithmField1;
+	}
+
+	public void setDynamicRuleAlgorithmField2(
+			List<String> dynamicRuleAlgorithmField2) {
+		this.dynamicRuleAlgorithmField2 = dynamicRuleAlgorithmField2;
+	}
+
+	public void setActionPerformer(String actionPerformer) {
+		this.actionPerformer = actionPerformer;
+	}
+
+	public void setActionAttribute(String actionAttribute) {
+		this.actionAttribute = actionAttribute;
+	}
+
+	public void setActionBody(String actionBody) {
+		this.actionBody = actionBody;
+	}
+
+	public void setDropDownMap(Map<String, String> dropDownMap) {
+		this.dropDownMap = dropDownMap;
+	}
+
+	public void setActionDictHeader(String actionDictHeader) {
+		this.actionDictHeader = actionDictHeader;
+	}
+
+	public void setActionDictType(String actionDictType) {
+		this.actionDictType = actionDictType;
+	}
+
+	public void setActionDictUrl(String actionDictUrl) {
+		this.actionDictUrl = actionDictUrl;
+	}
+
+	public void setActionDictMethod(String actionDictMethod) {
+		this.actionDictMethod = actionDictMethod;
+	}
+
+	public void setDynamicSettingsMap(Map<String, String> dynamicSettingsMap) {
+		this.dynamicSettingsMap = dynamicSettingsMap;
+	}
+
+	public void setDynamicVariableList(List<Object> dynamicVariableList) {
+		this.dynamicVariableList = dynamicVariableList;
+	}
+
+	public void setDataTypeList(List<String> dataTypeList) {
+		this.dataTypeList = dataTypeList;
+	}
+
+	public void setDraft(Boolean draft) {
+		this.draft = draft;
+	}
+
+	public void setOldPolicyFileName(String oldPolicyFileName) {
+		this.oldPolicyFileName = oldPolicyFileName;
+	}
+
+	public void setServiceType(String serviceType) {
+		this.serviceType = serviceType;
+	}
+
+	public Map<String, String> getDrlRuleAndUIParams() {
+		return drlRuleAndUIParams;
+	}
+
+	public void setDrlRuleAndUIParams(Map<String, String> drlRuleAndUIParams) {
+		this.drlRuleAndUIParams = drlRuleAndUIParams;
+	}
+
+	public void setUuid(String uuid) {
+		this.uuid = uuid;
+	}
+
+	public void setMsLocation(String msLocation) {
+		this.msLocation = msLocation;
+	}
+
+	public void setPriority(String priority) {
+		this.priority = priority;
+	}
+
+	public void setDeleteCondition(String deleteCondition) {
+		this.deleteCondition = deleteCondition;
+	}
+
+	public void setDictionaryType(String dictionaryType) {
+		this.dictionaryType = dictionaryType;
+	}
+
+	public void setDictionary(String dictionary) {
+		this.dictionary = dictionary;
+	}
+
+	public void setDictionaryFields(String dictionaryFields) {
+		this.dictionaryFields = dictionaryFields;
+	}
+
+	public String getProviderComboBox() {
+		return providerComboBox;
+	}
+
+	public void setProviderComboBox(String providerComboBox) {
+		this.providerComboBox = providerComboBox;
+	}
+
+	public void setRiskType(String riskType){
+		this.riskType = riskType;
+	}
+
+	public void setRiskLevel(String riskLevel){
+		this.riskLevel = riskLevel;
+	}
+
+	public void setGuard(String guard){
+		this.guard = guard;
+	}
+
+	public void setTTLDate(String ttlDate){
+		this.ttlDate = ttlDate;
+	}
+
+	public String getBrmsController() {
+		return brmsController;
+	}
+
+	public void setBrmsController(String brmsController) {
+		this.brmsController = brmsController;
+	}
+
+	public ArrayList<String> getBrmsDependency() {
+		return brmsDependency;
+	}
+
+	public void setBrmsDependency(ArrayList<String> brmsDependency) {
+		this.brmsDependency = brmsDependency;
+	}
+}
\ No newline at end of file
diff --git a/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pap/StdPDP.java b/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pap/StdPDP.java
new file mode 100644
index 0000000..20dbfae
--- /dev/null
+++ b/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pap/StdPDP.java
@@ -0,0 +1,222 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP-XACML
+ * ================================================================================
+ * 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.std.pap;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Properties;
+import java.util.Set;
+
+import org.onap.policy.xacml.api.pap.OnapPDP;
+
+import org.onap.policy.common.logging.flexlogger.FlexLogger; 
+import org.onap.policy.common.logging.flexlogger.Logger;
+import com.att.research.xacml.api.pap.PDPPIPConfig;
+import com.att.research.xacml.api.pap.PDPPolicy;
+import com.att.research.xacml.api.pap.PDPStatus;
+
+public class StdPDP extends StdPDPItemSetChangeNotifier implements OnapPDP, Comparable<StdPDP>, Serializable {
+	private static final long serialVersionUID = 1L;
+	private static Logger	logger	= FlexLogger.getLogger(StdPDP.class);
+	
+	private String id;
+	
+	private String name;
+	
+	private String description;
+	
+	private Integer jmxport = 0;
+	
+	private PDPStatus status = new StdPDPStatus();
+	
+	private Set<PDPPolicy> policies = new HashSet<>();
+	
+	private Set<PDPPIPConfig> pipConfigs = new HashSet<>();
+	
+	public StdPDP() {
+		
+	}
+	
+	public StdPDP(String id, Integer  jmxport) {
+		this(id, null, null, jmxport);
+	}
+	
+	public StdPDP(String id, String name, Integer  jmxport) {
+		this(id, name, null, jmxport);
+	}
+	
+	public StdPDP(String id, String name, String description, Integer jmxport) {
+		this.id = id;
+		this.name = name;
+		this.description = description;
+		if(jmxport != null){
+			this.jmxport = jmxport;
+		} 
+	}
+	
+	public StdPDP(String id, Properties properties) {
+		this(id, 0);
+		
+		this.initialize(properties);
+	}
+	
+	public void initialize(Properties properties) {
+		for (Object key : properties.keySet()) {
+			if (key.toString().startsWith(this.id + ".")) {
+				if (logger.isDebugEnabled()) {
+					logger.debug("Found: " + key);
+				}
+				if (key.toString().endsWith(".name")) {
+					this.name = properties.getProperty(key.toString());
+				} else if (key.toString().endsWith(".description")) {
+					this.description = properties.getProperty(key.toString());
+				}else if (key.toString().endsWith(".jmxport")) {
+					//todo fix this hackjob
+					if (properties.getProperty(key.toString()) != null && properties.getProperty(key.toString()).trim().length() > 0){
+						logger.debug("initialize before: " + this.jmxport);
+						this.jmxport = Integer.valueOf( properties.getProperty(key.toString()));
+						logger.debug("initialize after: " + this.jmxport);
+					}else{
+						this.jmxport = 0;
+					}
+				}
+			}
+		}
+	}
+
+	@Override
+	public String getId() {
+		return this.id;
+	}
+
+	public void setId(String id) {
+		this.id=id;
+	}
+
+	@Override
+	public String getName() {
+		return this.name;
+	}
+	
+	@Override
+	public void setName(String name) {
+		this.name = name;
+		this.firePDPChanged(this);
+	}
+
+	@Override
+	public String getDescription() {
+		return this.description;
+	}
+	
+	@Override
+	public void setDescription(String description) {
+		this.description = description;
+		this.firePDPChanged(this);
+	}
+
+	@Override
+	public PDPStatus getStatus() {
+		return this.status;
+	}
+
+	public void setStatus(PDPStatus status) {
+		this.status = status;
+	}
+	
+	@Override
+	public Set<PDPPolicy> getPolicies() {
+		return Collections.unmodifiableSet(this.policies);
+	}
+	
+	public void setPolicies(Set<PDPPolicy> policies) {
+		this.policies = policies;
+	}
+
+	@Override
+	public Set<PDPPIPConfig> getPipConfigs() {
+		return Collections.unmodifiableSet(this.pipConfigs);
+	}
+	
+	public void setPipConfigs(Set<PDPPIPConfig> pipConfigs) {
+		this.pipConfigs = pipConfigs;
+	}
+	public void setJmxPort(Integer jmxport) {
+		this.jmxport = jmxport;
+	}
+	@Override
+	public Integer getJmxPort() {
+		return this.jmxport;
+	}
+	
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((id == null) ? 0 : id.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		StdPDP other = (StdPDP) obj;
+		if (id == null) {
+			if (other.id != null)
+				return false;
+		} else if (!id.equals(other.id))
+			return false;
+		return true;
+	}
+
+	@Override
+	public String toString() {
+		return "StdPDP [id=" + id + ", name=" + name + ", description="
+				+ description + ", jmxport=" + jmxport + ", status=" + status + ", policies=" + policies
+				+ ", pipConfigs=" + pipConfigs + "]";
+	}
+	
+	//
+	// Comparable interface
+	//
+	@Override
+	public int compareTo(StdPDP o) {
+		if (o == null) {
+			return -1;
+		}
+		if ( ! (o instanceof StdPDP)) {
+			return -1;
+		}
+		if (((StdPDP)o).name == null) {
+			return -1;
+		}
+		if (name == null) {
+			return 1;
+		}
+		return name.compareTo(((StdPDP)o).name);
+	}
+	
+}
diff --git a/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pap/StdPDPGroup.java b/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pap/StdPDPGroup.java
new file mode 100644
index 0000000..63cc4b4
--- /dev/null
+++ b/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pap/StdPDPGroup.java
@@ -0,0 +1,1058 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP-XACML
+ * ================================================================================
+ * 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.std.pap;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.onap.policy.common.logging.eelf.MessageCodes;
+import org.onap.policy.common.logging.eelf.PolicyLogger;
+import org.onap.policy.xacml.api.XACMLErrorConstants;
+import org.onap.policy.xacml.api.pap.OnapPDP;
+import org.onap.policy.xacml.api.pap.OnapPDPGroup;
+import org.onap.policy.xacml.std.pap.StdPDPItemSetChangeNotifier.StdItemSetChangeListener;
+
+import com.att.research.xacml.api.pap.PAPException;
+import com.att.research.xacml.api.pap.PDP;
+//import com.att.research.xacml.api.pap.PDPGroup;
+import com.att.research.xacml.api.pap.PDPGroupStatus;
+import com.att.research.xacml.api.pap.PDPGroupStatus.Status;
+import com.att.research.xacml.api.pap.PDPPIPConfig;
+import com.att.research.xacml.api.pap.PDPPolicy;
+import com.att.research.xacml.util.XACMLProperties;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.google.common.base.Joiner;
+import com.google.common.base.Splitter;
+import com.google.common.io.ByteStreams;
+
+public class StdPDPGroup extends StdPDPItemSetChangeNotifier implements OnapPDPGroup, StdItemSetChangeListener, Comparable<Object>, Serializable {
+	private static final long serialVersionUID = 1L;
+	private static Log	logger	= LogFactory.getLog(StdPDPGroup.class);
+	
+	private String id;
+	
+	private boolean isDefault = false;
+	
+	private String name;
+	
+	private String description;
+	
+	private StdPDPGroupStatus status = new StdPDPGroupStatus(Status.UNKNOWN);
+	
+	private Set<OnapPDP>	pdps = new HashSet<>();
+	
+	private Set<PDPPolicy> policies = new HashSet<>();
+	
+	private Set<PDPPolicy> selectedPolicies = new HashSet<>();
+	
+	private Set<PDPPIPConfig> pipConfigs = new HashSet<>();
+	
+	private String operation;
+	
+	@JsonIgnore
+	private  Path directory;
+	
+	@JsonIgnore
+	private Integer jmxport;
+	
+	
+	public StdPDPGroup(String id, Path directory) {
+		this.id = id;
+		this.directory = directory;
+	}
+	
+	public StdPDPGroup(String id, boolean isDefault, Path directory) {
+		this(id, directory);
+		this.isDefault = isDefault;
+	}
+	
+	public StdPDPGroup(String id, boolean isDefault, String name, String description, Path directory) {
+		this(id, isDefault, directory);
+		this.name = name;
+		// force all policies to have a name
+		if (name == null) {
+			this.name = id;
+		}
+		this.description = description;
+	}
+	
+	public StdPDPGroup(String id, String name, String description, Path directory) {
+		this(id, false, name, description, directory);
+		this.resetStatus();
+	}
+	
+	public StdPDPGroup(String id, boolean isDefault, Properties properties, Path directory) throws PAPException {
+		this(id, isDefault, directory);
+		this.initialize(properties, directory);
+		this.resetStatus();
+	}
+	
+	private void initialize(Properties properties, Path directory) throws PAPException {
+		if (this.id == null || this.id.length() == 0) {
+			logger.warn("Cannot initialize with a null or zero length id");
+			return;
+		}
+		//
+		// Pull the group's properties
+		//
+		for (Object key : properties.keySet()) {
+			if (key.toString().startsWith(this.id + ".")) {
+				if (key.toString().endsWith(".name")) {
+					this.name = properties.getProperty(key.toString());
+				} else if (key.toString().endsWith(".description")) {
+					this.description = properties.getProperty(key.toString());
+				} else if (key.toString().endsWith(".pdps")) {
+					String pdpList = properties.getProperty(key.toString());
+					if (pdpList != null && pdpList.length() > 0) {
+						for (String id : Splitter.on(',').omitEmptyStrings().trimResults().split(pdpList)) {
+							StdPDP pdp = new StdPDP(id, properties);
+							pdp.addItemSetChangeListener(this);
+							this.pdps.add(pdp);
+						}
+					}
+				}
+			}
+			// force all policies to have a name
+			if (this.name == null) {
+				this.name = this.id;
+			}
+		}
+		//
+		// Validate our directory
+		//
+		if (Files.notExists(directory)) {
+			logger.warn("Group directory does NOT exist: " + directory.toString());
+			try {
+				Files.createDirectory(directory);
+				this.status.addLoadWarning("Group directory does NOT exist");
+			} catch (IOException e) {
+				PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "StdPDPGroup", "Group directory does NOT exist");
+				this.status.addLoadError("Group directory does NOT exist");
+				this.status.setStatus(PDPGroupStatus.Status.LOAD_ERRORS);
+			}
+		}
+		//
+		// Parse policies
+		//
+		this.loadPolicies(Paths.get(directory.toString(), "xacml.policy.properties"));
+		//
+		// Parse pip config
+		//
+		this.loadPIPConfig(Paths.get(directory.toString(), "xacml.pip.properties"));
+	}
+	
+	public void loadPolicies(Path file) throws PAPException {
+		//
+		// Read the Groups Policies
+		//
+		Properties policyProperties = new Properties();
+		if ( ! file.toFile().exists()) {
+			// need to create the properties file with default values
+			policyProperties.setProperty(XACMLProperties.PROP_ROOTPOLICIES, "");
+			policyProperties.setProperty(XACMLProperties.PROP_REFERENCEDPOLICIES, "");
+			// save properties to file
+			try (OutputStream os = Files.newOutputStream(file)) {
+				policyProperties.store(os, "");
+			} catch (Exception e) {
+				throw new PAPException("Failed to create new default policy properties file '" + file +"'");
+			}
+		} else {
+			// load previously existing file
+			try {
+				//
+				// Load the properties
+				//
+				try (InputStream is = Files.newInputStream(file)) {
+					policyProperties.load(is);
+				}
+				//
+				// Parse the policies
+				//
+				this.readPolicyProperties(directory, policyProperties);
+			} catch (IOException e) {
+				logger.warn("Failed to load group policy properties file: " + file, e);
+				this.status.addLoadError("Not policy properties defined");
+				this.status.setStatus(Status.LOAD_ERRORS);
+				throw new PAPException("Failed to load group policy properties file: " + file);
+			}
+		}
+	}
+	
+	public void loadPIPConfig(Path file) throws PAPException {
+		//
+		// Read the Groups' PIP configuration
+		//
+		Properties pipProperties = new Properties();
+		if ( ! file.toFile().exists()) {
+			// need to create the properties file with no values
+			pipProperties = setPIPProperties(pipProperties);
+			// save properties to file
+			try {
+				try (OutputStream os = Files.newOutputStream(file)) {
+					pipProperties.store(os, "");
+				}
+			} catch (Exception e) {
+				throw new PAPException("Failed to create new default pip properties file '" + file +"'");
+			}
+			//Even if we create a new pip file, we still need to parse and load the properties
+			try{
+				this.readPIPProperties(directory, pipProperties);
+			}catch(Exception e){
+				throw new PAPException("Failed to load the new pip properties file");
+			}
+		} else {
+			try {
+				//
+				// Load the properties
+				//
+				try (InputStream is = Files.newInputStream(file)) {
+					pipProperties.load(is);
+				}
+				// For all old PIP config's modify to the new PIP Configuration. 
+				// If PIP is empty add the new values and save it. 
+				if(pipProperties.get(XACMLProperties.PROP_PIP_ENGINES).toString().trim().equals("")){
+					pipProperties = setPIPProperties(pipProperties);
+					try (OutputStream os = Files.newOutputStream(file)) {
+						pipProperties.store(os, "");
+					}
+				}
+				//
+				// Parse the pips
+				//
+				this.readPIPProperties(directory, pipProperties);
+			} catch (IOException e) {
+				logger.warn("Failed to open group PIP Config properties file: " + file, e);
+				this.status.addLoadError("Not PIP config properties defined");
+				this.status.setStatus(Status.LOAD_ERRORS);
+				throw new PAPException("Failed to load group policy properties file: " + file);
+
+			}
+		}
+	}
+	
+	public void resetStatus() {
+//		//
+//		// If we are updating, don't allow reset
+//		//
+//		if (this.status.getStatus() == Status.UPDATING_CONFIGURATION) {
+//			logger.warn("We are updating, chill.");
+//			return;
+//		}
+//		//
+//		// Load errors take precedence
+//		//
+//		if (this.status.getStatus() == Status.LOAD_ERRORS) {
+//			logger.warn("We had load errors.");
+//			return;
+//		}
+		//
+		// Reset our status object
+		//
+		this.status.reset();
+		//
+		// Determine our status
+		//
+		for (PDP pdp : this.pdps) {
+			switch (pdp.getStatus().getStatus()) {
+			case OUT_OF_SYNCH:
+				this.status.addOutOfSynchPDP(pdp);
+				break;
+			case LAST_UPDATE_FAILED:
+				this.status.addLastUpdateFailedPDP(pdp);
+				break;
+			case LOAD_ERRORS:
+				this.status.addFailedPDP(pdp);
+				break;
+			case UPDATING_CONFIGURATION:
+				this.status.addUpdatingPDP(pdp);
+				break;
+			case UP_TO_DATE:
+				this.status.addInSynchPDP(pdp);
+				break;
+			case UNKNOWN:
+			case CANNOT_CONNECT:
+			case NO_SUCH_HOST:
+			default:
+				this.status.addUnknownPDP(pdp);
+				break;
+			}
+		}
+		
+		// priority is worst-cast to best case
+		if (this.status.getUnknownPDPs().size() > 0) {
+			this.status.setStatus(Status.UNKNOWN);
+		} else if (this.status.getFailedPDPs().size() > 0 || this.status.getLastUpdateFailedPDPs().size() > 0) {
+			this.status.setStatus(Status.LOAD_ERRORS);
+		} else if (this.status.getOutOfSynchPDPs().size() > 0) {
+			this.status.setStatus(Status.OUT_OF_SYNCH);
+		} else if (this.status.getUpdatingPDPs().size() > 0) {
+			this.status.setStatus(Status.UPDATING_CONFIGURATION);
+		} else {
+			this.status.setStatus(Status.OK); 
+		}
+	}
+
+	@Override
+	public String getId() {
+		return this.id;
+	}
+	
+	public void setId(String id) {
+		this.id = id;
+	}
+
+	@Override
+	public boolean isDefaultGroup() {
+		return this.isDefault;
+	}
+	
+	public void setDefaultGroup(boolean isDefault) {
+		this.isDefault = isDefault;
+		//
+		// Cannot fire this because 2 operations have
+		// to occur: 1) old default=false (don't want to fire) and
+		// then 2) new default=true (yes fire - but we'll have to do that
+		// elsewhere.
+		//this.firePDPGroupChanged(this);
+	}
+
+	@Override
+	public String getName() {
+		return name;
+	}
+
+	@Override
+	public void setName(String groupName) {
+		this.name = groupName;
+		this.firePDPGroupChanged(this);
+	}
+
+	@Override
+	public String getDescription() {
+		return this.description;
+	}
+
+	@Override
+	public void setDescription(String groupDescription) {
+		this.description = groupDescription;
+		this.firePDPGroupChanged(this);
+	}
+	
+	public Path getDirectory() {
+		return this.directory;
+	}
+
+	public void setDirectory(Path groupDirectory) {
+		this.directory = groupDirectory;
+		// this is used only for transmission on the RESTful interface, so no need to fire group changed?
+	}
+
+	@Override
+	public PDPGroupStatus getStatus(){
+		return this.status;
+	}
+	
+	@Override
+	public Set<PDPPolicy> getSelectedPolicies() {
+		return this.selectedPolicies;
+	}
+	
+	@Override
+	public String getOperation() {
+		return this.operation;
+	}
+	
+	@Override
+	public Set<PDP> getPdps() {
+		return Collections.unmodifiableSet(pdps);
+	}
+
+	public void setOnapPdps(Set<OnapPDP> pdps) {
+		this.pdps = pdps;
+	}
+	
+	public Set<OnapPDP> getOnapPdps(){
+		return Collections.unmodifiableSet(pdps);
+	}
+	
+	public boolean addPDP(OnapPDP pdp) {
+		return this.pdps.add(pdp);
+	}
+	
+	public boolean removePDP(PDP pdp) {
+		return this.pdps.remove(pdp);
+	}
+
+	@Override
+	public Set<PDPPolicy> getPolicies() {
+		return Collections.unmodifiableSet(this.policies);
+	}
+
+	@Override
+	public PDPPolicy getPolicy(String id) {
+		for (PDPPolicy policy : this.policies) {
+			if (policy.getId().equals(id)) {
+				return policy;
+			}
+		}
+		return null;
+	}
+
+	public Properties getPolicyProperties()
+	{
+		Properties properties = new Properties(){
+			private static final long serialVersionUID = 1L;
+			// For Debugging it is helpful for the file to be in a sorted order,
+			// any by returning the keys in the natural Alpha order for strings we get close enough.
+			// TreeSet is sorted, and this just overrides the normal Properties method to get the keys.
+			@Override
+		    public synchronized Enumeration<Object> keys() {
+		        return Collections.enumeration(new TreeSet<Object>(super.keySet()));
+		    }
+	    };;
+		List<String> roots = new ArrayList<String>();
+		List<String> refs = new ArrayList<String>();
+		
+		for (PDPPolicy policy : this.policies) {
+			// for all policies need to tell PDP the "name", which is the base name for the file id
+			if (policy.getName() != null) {
+				properties.setProperty(policy.getId() + ".name", policy.getName());
+			}
+			// put the policy on the correct list
+			if (policy.isRoot()) {
+				roots.add(policy.getId());
+			} else {
+				refs.add(policy.getId());
+			}
+		}
+		
+		properties.setProperty(XACMLProperties.PROP_ROOTPOLICIES, Joiner.on(',').join(roots));
+		properties.setProperty(XACMLProperties.PROP_REFERENCEDPOLICIES, Joiner.on(',').join(refs));
+	
+		return properties;
+	}
+	
+	public PDPPolicy publishPolicy(String id, String name, boolean isRoot, InputStream policy) throws PAPException {
+		//
+		// Does it exist already?
+		//
+		if (this.getPolicy(id) != null) {
+			throw new PAPException("Policy with id " + id + " already exists - unpublish it first.");
+		}
+		Path tempFile = null;
+		try {
+			//
+			// Copy the policy over
+			//
+			tempFile = Files.createFile(Paths.get(this.directory.toAbsolutePath().toString(), id));
+			long num;
+			try (OutputStream os = Files.newOutputStream(tempFile)) {
+				num = ByteStreams.copy(policy, os);
+			}
+			logger.info("Copied " + num + " bytes for policy " + name);
+			
+			StdPDPPolicy tempRootPolicy = new StdPDPPolicy(id, isRoot, name, tempFile.toUri());
+			if (tempRootPolicy.isValid() == false) {
+				try {
+					Files.delete(tempFile);
+				} catch(Exception ee) {
+					PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, ee, "StdPDPGroup", "Policy was invalid, could NOT delete it.");
+				}
+				throw new PAPException("Policy is invalid");
+			}
+			//
+			// Add it in
+			//
+			this.policies.add(tempRootPolicy);
+			//
+			// We are changed
+			//
+			this.firePDPGroupChanged(this);
+			//
+			// Return our new object.
+			//
+			return tempRootPolicy;
+		} catch (IOException e) {
+			PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "StdPDPGroup", "Failed to publishPolicy");
+		}
+		return null;
+	}
+	
+	/**
+	 * Copy one policy file into the Group's directory but do not change the configuration.
+	 * This is one part of a multi-step process of publishing policies.
+	 * There may be multiple changes in the group (adding multiple policies, deleting policies, changine root<->referenced)
+	 * that must be done all at once, so we just copy the file in preparation for a later "update whole group" operation.
+	 * 
+	 * @param id
+	 * @param name
+	 * @param isRoot
+	 * @param policy
+	 * @return
+	 * @throws PAPException
+	 */
+	public void copyPolicyToFile(String id,  InputStream policy) throws PAPException {
+		try {
+			//
+			// Copy the policy over
+			//
+			long num;
+			Path policyFilePath = Paths.get(this.directory.toAbsolutePath().toString(), id);
+			
+			Path policyFile;
+			if (Files.exists(policyFilePath)) {
+				policyFile = policyFilePath;
+			} else {
+				policyFile = Files.createFile(policyFilePath);
+			}
+
+			try (OutputStream os = Files.newOutputStream(policyFile)) {
+				num = ByteStreams.copy(policy, os);
+			}
+			
+			logger.info("Copied " + num + " bytes for policy " + name);
+
+			for (PDPPolicy p : policies) {
+				if (p.getId().equals(id)) {
+					// we just re-copied/refreshed/updated the policy file for a policy that already exists in this group
+					logger.info("Policy '" + id + "' already exists in group '" + getId() + "'");
+					return;
+				}
+			}
+			
+			// policy is new to this group
+			StdPDPPolicy tempRootPolicy = new StdPDPPolicy(id, true, name, policyFile.toUri());
+			if (tempRootPolicy.isValid() == false) {
+				try {
+					Files.delete(policyFile);
+				} catch(Exception ee) {
+					PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, ee, "StdPDPGroup", "Policy was invalid, could NOT delete it.");
+				}
+				throw new PAPException("Policy is invalid");
+			}
+			//
+			// Add it in
+			//
+			this.policies.add(tempRootPolicy);
+			//
+			// We are changed
+			//
+			this.firePDPGroupChanged(this);
+		} catch (IOException e) {
+			PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "StdPDPGroup", "Failed to copyPolicyToFile");
+			throw new PAPException("Failed to copy policy to file: " + e);
+		}
+		return;
+	}
+	
+	/**
+	 * Policy Engine API Copy one policy file into the Group's directory but do not change the configuration.
+	 * 
+	 * @param id
+	 * @param name
+	 * @param policy
+	 * @return
+	 * @throws PAPException
+	 */
+	public void copyPolicyToFile(String id,  String name, InputStream policy) throws PAPException {
+		try {
+			//
+			// Copy the policy over
+			//
+			long num;
+			Path policyFilePath = Paths.get(this.directory.toAbsolutePath().toString(), id);
+
+			Path policyFile;
+			if (Files.exists(policyFilePath)) {
+				policyFile = policyFilePath;
+			} else {
+				policyFile = Files.createFile(policyFilePath);
+			}
+
+			try (OutputStream os = Files.newOutputStream(policyFile)) {
+				num = ByteStreams.copy(policy, os);
+			}
+
+			logger.info("Copied " + num + " bytes for policy " + name);
+			for (PDPPolicy p : policies) {
+				if (p.getId().equals(id)) {
+					// we just re-copied/refreshed/updated the policy file for a policy that already exists in this group
+					logger.info("Policy '" + id + "' already exists in group '" + getId() + "'");
+					return;
+				}
+			}
+			
+			// policy is new to this group
+			StdPDPPolicy tempRootPolicy = new StdPDPPolicy(id, true, name, policyFile.toUri());
+			if (tempRootPolicy.isValid() == false) {
+				try {
+					Files.delete(policyFile);
+				} catch(Exception ee) {
+					PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, ee, "StdPDPGroup", "Policy was invalid, could NOT delete it.");
+				}
+				throw new PAPException("Policy is invalid");
+			}
+			//
+			// Add it in
+			//
+			this.policies.add(tempRootPolicy);
+			//
+			// We are changed
+			//
+			this.firePDPGroupChanged(this);
+
+		} catch (IOException e) {
+			PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "StdPDPGroup", "Failed to copyPolicyToFile");
+			throw new PAPException("Failed to copy policy to file: " + e);
+		}
+		return;
+	}
+		
+	public boolean removePolicyFromGroup(PDPPolicy policy) {
+		PolicyLogger.info("policy: " + policy.getId());
+		PolicyLogger.info("Policy ID:" + policy.getPolicyId());
+		PolicyLogger.info("Policy Version: " + policy.getVersion());
+		PolicyLogger.info("StdPDPPolicy Class cast: " + this.getPolicy(policy.getId()).toString());
+		StdPDPPolicy currentPolicy = (StdPDPPolicy) this.getPolicy(policy.getId());
+		if (currentPolicy == null) {
+			PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + "Policy " + policy.getId() + " does not exist.");
+			return false;
+		}
+		try {
+			//
+			// Remove it from our list
+			//
+			this.policies.remove(currentPolicy);
+			//
+			// We are changed
+			//
+			this.firePDPGroupChanged(this);
+			return true;
+		} catch (Exception e) {
+			PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "StdPDPGroup", "Failed to delete policy");
+		}
+		return false;
+	}
+	
+	public boolean removePolicy(PDPPolicy policy) {
+		StdPDPPolicy currentPolicy = (StdPDPPolicy) this.getPolicy(policy.getId());
+		if (currentPolicy == null) {
+			PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + "Policy " + policy.getId() + " does not exist.");
+			return false;
+		}
+		try {
+			//
+			// Delete it on disk
+			//
+			Files.delete(Paths.get(currentPolicy.getLocation()));
+			//
+			// Remove it from our list
+			//
+			this.policies.remove(currentPolicy);
+			//
+			// We are changed
+			//
+			this.firePDPGroupChanged(this);
+			return true;
+		} catch (Exception e) {
+			PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "StdPDPGroup", "Failed to delete policy " + policy);
+		}
+		return false;
+	}
+
+	@Override
+	public Set<PDPPIPConfig> getPipConfigs() {
+		return Collections.unmodifiableSet(this.pipConfigs);
+	}
+
+	@Override
+	public PDPPIPConfig getPipConfig(String id) {
+		for (PDPPIPConfig config : this.pipConfigs) {
+			if (config.getId().equals(id)) {
+				return config;
+			}
+		}
+		return null;
+	}
+	
+	public void setPipConfigs(Set<PDPPIPConfig> pipConfigs) {
+		this.pipConfigs = pipConfigs;
+		this.firePDPGroupChanged(this);
+	}
+	
+	public void removeAllPIPConfigs() {
+		this.pipConfigs.clear();
+		this.firePDPGroupChanged(this);
+	}
+	
+	public Properties getPipConfigProperties() {
+		Properties properties = new Properties();
+		List<String> configs = new ArrayList<String>();
+		
+		for (PDPPIPConfig config : this.pipConfigs) {
+			configs.add(config.getId());
+			properties.putAll(config.getConfiguration());
+		}
+		
+		properties.setProperty(XACMLProperties.PROP_PIP_ENGINES, Joiner.on(',').join(configs));
+
+		return properties;
+	}
+
+	@Override
+	public void repair() {
+		//
+		// Reset the status object
+		//
+		this.status.reset();
+		//
+		// Validate our directory
+		//
+		boolean fire = false;
+		if (Files.notExists(directory)) {
+			logger.warn("Group directory does NOT exist: " + directory.toString());
+			try {
+				Files.createDirectory(directory);
+				fire = true;
+				this.status.addLoadWarning("Created missing group directory");
+			} catch (IOException e) {
+				PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "StdPDPGroup", "Failed to create missing Group directory.");
+				this.status.addLoadError("Failed to create missing Group directory.");
+				this.status.setStatus(PDPGroupStatus.Status.LOAD_ERRORS);
+			}
+		}
+		//
+		// Validate our PIP config file
+		//
+		Path pipPropertiesFile = Paths.get(directory.toString(), "xacml.pip.properties");
+		if (Files.notExists(pipPropertiesFile)) {
+			try {
+				Files.createFile(pipPropertiesFile);
+				fire = true;
+				this.status.addLoadWarning("Created missing PIP properties file");
+			} catch (IOException e) {
+				PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "StdPDPGroup", "Failed to create missing PIP properties file");
+				this.status.addLoadError("Failed to create missing PIP properties file");
+				this.status.setStatus(PDPGroupStatus.Status.LOAD_ERRORS);
+			}
+		}
+		//
+		// Valid our policy properties file
+		//
+		Path policyPropertiesFile = Paths.get(directory.toString(), "xacml.policy.properties");
+		if (Files.notExists(policyPropertiesFile)) {
+			try {
+				Files.createFile(policyPropertiesFile);
+				fire = true;
+				this.status.addLoadWarning("Created missing Policy properties file");
+			} catch (IOException e) {
+				PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "StdPDPGroup", "Failed to create missing Policy properties file");
+				this.status.addLoadError("Failed to create missing Policy properties file");
+				this.status.setStatus(PDPGroupStatus.Status.LOAD_ERRORS);
+			}
+		}
+		this.resetStatus();
+		if (fire) {
+			this.fireChanged();
+		}
+	}
+
+	private void	readPolicyProperties(Path directory, Properties properties) {
+		//
+		// There are 2 property values that hold policies, root and referenced
+		//
+		String[] lists = new String[2];
+		lists[0] = properties.getProperty(XACMLProperties.PROP_ROOTPOLICIES);
+		lists[1] = properties.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES);
+		//
+		// Iterate each policy list
+		//
+		boolean isRoot = true;
+		for (String list : lists) {
+			//
+			// Was there actually a property?
+			//
+			if (list == null || list.length() == 0) {
+				isRoot = false;
+				continue;
+			}
+			//
+			// Parse it out
+			//
+			Iterable<String> policyList = Splitter.on(',').trimResults().omitEmptyStrings().split(list);
+			//
+			// Was there actually a list
+			//
+			if (policyList == null) {
+				isRoot = false;
+				continue;
+			}
+			for (String id : policyList) {
+				//
+				// Construct the policy filename
+				//
+				Path policyPath = Paths.get(directory.toString(), id );
+				//
+				// Create the Policy Object
+				//
+				StdPDPPolicy policy;
+				try {
+					policy = new StdPDPPolicy(id, isRoot, policyPath.toUri(), properties);
+				} catch (IOException e) {
+					PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "StdPDPGroup", "Failed to create policy object");
+					policy = null;
+				}
+				//
+				// Is it valid?
+				//
+				if (policy != null && policy.isValid()) {
+					this.policies.add(policy);
+					this.status.addLoadedPolicy(policy);
+				} else {
+					this.status.addFailedPolicy(policy);
+					this.status.setStatus(Status.LOAD_ERRORS);
+				}
+				// force all policies to have a name
+				if (policy!=null && policy.getName() == null) {
+					policy.setName(policy.getId());
+				}
+			}
+			isRoot = false;
+		}
+	}
+
+	private void	readPIPProperties(Path directory, Properties properties) {
+		String list = properties.getProperty(XACMLProperties.PROP_PIP_ENGINES);
+		if (list == null || list.length() == 0) {
+			return;
+		}
+		for (String id : list.split("[,]")) {
+			StdPDPPIPConfig config = new StdPDPPIPConfig(id, properties);
+			if (config.isConfigured()) {
+				this.pipConfigs.add(config);
+				this.status.addLoadedPipConfig(config);
+			} else {
+				this.status.addFailedPipConfig(config);
+				this.status.setStatus(Status.LOAD_ERRORS);
+			}
+		}
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((id == null) ? 0 : id.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		StdPDPGroup other = (StdPDPGroup) obj;
+		if (id == null) {
+			if (other.id != null)
+				return false;
+		} else if (!id.equals(other.id))
+			return false;
+		return true;
+	}
+
+	@Override
+	public String toString() {
+		return "StdPDPGroup [id=" + id + ", isDefault=" + isDefault + ", name="
+				+ name + ", description=" + description + ", status=" + status
+				+ ", pdps=" + pdps + ", policies=" + policies + ", pipConfigs="
+				+ pipConfigs + ", directory=" + directory + ",selectedPolicies=" 
+						+ selectedPolicies + ",operation=" + operation + "]";
+	}
+
+	@Override
+	public void changed() {
+
+		// save the (changed) properties
+		try {
+			saveGroupConfiguration();
+		} catch (PAPException | IOException e) {
+			PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "StdPDPGroup", "Unable to save group configuration change");
+			// don't notify other things of change if we cannot save it???
+			return;
+		}
+		
+		this.firePDPGroupChanged(this);
+
+	}
+
+	@Override
+	public void groupChanged(OnapPDPGroup group) {
+		this.changed();
+	}
+
+	@Override
+	public void pdpChanged(OnapPDP pdp) {
+		//
+		// If one of the group's PDP's changed, then the group changed
+		//
+		this.changed();
+	}
+
+	
+	//
+	// Methods needed for JSON deserialization
+	//
+	public StdPDPGroup() {
+		
+	}
+	
+	public StdPDPGroup(OnapPDPGroup group) {
+		this.id = group.getId();
+		this.name = group.getName();
+		this.description = group.getDescription();
+		this.isDefault = group.isDefaultGroup();
+		this.pdps = group.getOnapPdps();
+		this.policies = group.getPolicies();
+		this.pipConfigs = group.getPipConfigs();
+	}
+
+	public boolean isDefault() {
+		return isDefault;
+	}
+	public void setDefault(boolean isDefault) {
+		this.isDefault = isDefault;
+	}
+	public void setStatus(PDPGroupStatus status) {
+		this.status = new StdPDPGroupStatus(status);
+	}
+	public void setPolicies(Set<PDPPolicy> policies) {
+		this.policies = policies;
+	}
+	public void setSelectedPolicies(Set<PDPPolicy> selectedPolicies) {
+		this.selectedPolicies = selectedPolicies;
+	}
+	public void setOperation(String operation) {
+		this.operation = operation;
+	}
+	
+	public void saveGroupConfiguration() throws PAPException, IOException {
+		
+		// First save the Policy properties
+		
+		// save the lists of policies
+		Properties policyProperties = this.getPolicyProperties();
+		
+		// save info about each policy
+		for (PDPPolicy policy : this.policies){
+			policyProperties.put(policy.getId() + ".name", policy.getName());
+		}
+
+		//
+		// Now we can save the file
+		//
+		Path file = Paths.get(this.directory.toString(), "xacml.policy.properties");
+		try (OutputStream os = Files.newOutputStream(file)) {
+			policyProperties.store(os, "");
+		} catch (Exception e) {
+			PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "STdPDPGroup", "Group Policies Config save failed");
+			throw new PAPException("Failed to save policy properties file '" + file +"'");
+		}
+		
+				
+		// Now save the PIP Config properties
+		Properties pipProperties = this.getPipConfigProperties();
+
+		//
+		// Now we can save the file
+		//
+		file = Paths.get(this.directory.toString(), "xacml.pip.properties");
+		try (OutputStream os = Files.newOutputStream(file)) {
+			pipProperties.store(os, "");
+		} catch (Exception e) {
+			PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "StdPDPGroup", "Group PIP Config save failed");
+			throw new PAPException("Failed to save pip properties file '" + file +"'");
+		}
+	}
+
+	//
+	// Comparable Interface
+	//
+	@Override
+	public int compareTo(Object arg0) {
+		if (arg0 == null) {
+			return -1;
+		}
+		if ( ! (arg0 instanceof StdPDPGroup)) {
+			return -1;
+		}
+		if (((StdPDPGroup)arg0).name == null) {
+			return -1;
+		}
+		if (name == null) {
+			return 1;
+		}
+
+		return name.compareTo(((StdPDPGroup)arg0).name);
+	}
+	
+	//Adding Default PIP engine(s) while Loading initially. We don't want 
+	//			Programmer intervention with the PIP engines. 
+	private Properties setPIPProperties(Properties props){
+		props.setProperty("AAF.name", "AAFEngine");
+		props.setProperty("AAF.description", "AAFEngine to communicate with AAF to take decisions");
+		props.setProperty("AAF.classname","org.onap.policy.xacml.std.pip.engines.aaf.AAFEngine");
+		props.setProperty(XACMLProperties.PROP_PIP_ENGINES, "AAF");
+		// read from PIP properties file. 
+		Path file = Paths.get(StdEngine.pipPropertyFile);
+		if (!Files.notExists(file)) {
+			InputStream in;
+			Properties prop = new Properties();
+			try {
+				in = new FileInputStream(file.toFile());
+				prop.load(in);
+			} catch (IOException e) {
+				PolicyLogger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "can not load the pip properties from file" +e);
+			}
+			props = prop;
+		}
+		return props;
+	}
+
+
+}
diff --git a/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pap/StdPDPGroupStatus.java b/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pap/StdPDPGroupStatus.java
new file mode 100644
index 0000000..296f738
--- /dev/null
+++ b/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pap/StdPDPGroupStatus.java
@@ -0,0 +1,405 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP-XACML
+ * ================================================================================
+ * 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.std.pap;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import com.att.research.xacml.api.pap.PDP;
+import com.att.research.xacml.api.pap.PDPGroupStatus;
+import com.att.research.xacml.api.pap.PDPPIPConfig;
+import com.att.research.xacml.api.pap.PDPPolicy;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
+public class StdPDPGroupStatus implements PDPGroupStatus {
+	
+	private Status status = Status.UNKNOWN;
+	
+	private Set<String>	loadErrors = new HashSet<>();
+	
+	private Set<String> loadWarnings = new HashSet<>();
+	
+	private Set<PDPPolicy> loadedPolicies = new HashSet<>();
+	
+	private Set<PDPPolicy> failedPolicies = new HashSet<>();
+	
+	private Set<PDPPIPConfig>	loadedPIPConfigs = new HashSet<>();
+	
+	private Set<PDPPIPConfig>	failedPIPConfigs = new HashSet<>();
+	
+	private Set<PDP>			inSynchPDPs = new HashSet<>();
+	
+	private Set<PDP>			outOfSynchPDPs = new HashSet<>();
+	
+	private Set<PDP>			failedPDPs = new HashSet<>();
+	
+	private Set<PDP>			updatingPDPs = new HashSet<>();
+	
+	private Set<PDP>			lastUpdateFailedPDPs = new HashSet<>();
+	
+	private Set<PDP>			unknownPDPs = new HashSet<>();
+	
+	
+	// Constructor needed for JSON deserialization
+	public StdPDPGroupStatus() {
+		
+	}
+	
+	public StdPDPGroupStatus(Status status) {
+		this.status = status;
+	}
+
+	public StdPDPGroupStatus(PDPGroupStatus stat) {
+		this.status = stat.getStatus();
+		this.failedPDPs.clear(); this.failedPDPs.addAll(stat.getFailedPDPs());
+		this.failedPIPConfigs.clear(); this.failedPIPConfigs.addAll(stat.getFailedPipConfigs());
+		this.failedPolicies.clear(); this.failedPolicies.addAll(stat.getFailedPolicies());
+		this.inSynchPDPs.clear(); this.inSynchPDPs.addAll(stat.getInSynchPDPs());
+		this.lastUpdateFailedPDPs.clear(); this.lastUpdateFailedPDPs.addAll(stat.getLastUpdateFailedPDPs());
+		this.loadedPIPConfigs.clear(); this.loadedPIPConfigs.addAll(stat.getLoadedPipConfigs());
+		this.loadedPolicies.clear(); this.loadedPolicies.addAll(stat.getLoadedPolicies());
+		this.loadErrors.clear(); this.loadErrors.addAll(stat.getLoadErrors());
+		this.loadWarnings.clear(); this.loadWarnings.addAll(stat.getLoadWarnings());
+		this.outOfSynchPDPs.clear(); this.outOfSynchPDPs.addAll(stat.getOutOfSynchPDPs());
+		this.unknownPDPs.clear(); this.unknownPDPs.addAll(stat.getUpdatingPDPs());
+		this.updatingPDPs.clear(); this.updatingPDPs.addAll(stat.getUpdatingPDPs());
+	}
+
+	public Set<PDPPIPConfig> getLoadedPIPConfigs() {
+		return loadedPIPConfigs;
+	}
+	public void setLoadedPIPConfigs(Set<PDPPIPConfig> loadedPIPConfigs) {
+		this.loadedPIPConfigs = loadedPIPConfigs;
+	}
+	public Set<PDPPIPConfig> getFailedPIPConfigs() {
+		return failedPIPConfigs;
+	}
+	public void setFailedPIPConfigs(Set<PDPPIPConfig> failedPIPConfigs) {
+		this.failedPIPConfigs = failedPIPConfigs;
+	}
+	public Set<PDP> getUnknownPDPs() {
+		return unknownPDPs;
+	}
+	public void setUnknownPDPs(Set<PDP> unknownPDPs) {
+		this.unknownPDPs = unknownPDPs;
+	}
+	public void setLoadErrors(Set<String> loadErrors) {
+		this.loadErrors = loadErrors;
+	}
+	public void setLoadWarnings(Set<String> loadWarnings) {
+		this.loadWarnings = loadWarnings;
+	}
+	public void setLoadedPolicies(Set<PDPPolicy> loadedPolicies) {
+		this.loadedPolicies = loadedPolicies;
+	}
+	public void setFailedPolicies(Set<PDPPolicy> failedPolicies) {
+		this.failedPolicies = failedPolicies;
+	}
+	public void setInSynchPDPs(Set<PDP> inSynchPDPs) {
+		this.inSynchPDPs = inSynchPDPs;
+	}
+	public void setOutOfSynchPDPs(Set<PDP> outOfSynchPDPs) {
+		this.outOfSynchPDPs = outOfSynchPDPs;
+	}
+	public void setFailedPDPs(Set<PDP> failedPDPs) {
+		this.failedPDPs = failedPDPs;
+	}
+	public void setUpdatingPDPs(Set<PDP> updatingPDPs) {
+		this.updatingPDPs = updatingPDPs;
+	}
+	public void setLastUpdateFailedPDPs(Set<PDP> lastUpdateFailedPDPs) {
+		this.lastUpdateFailedPDPs = lastUpdateFailedPDPs;
+	}
+	
+
+	@Override
+	public Status getStatus() {
+		return status;
+	}
+
+	public void setStatus(Status status) {
+		this.status = status;
+	}
+
+	@Override
+	public Set<String> getLoadErrors() {
+		return Collections.unmodifiableSet(this.loadErrors);
+	}
+
+	public void addLoadError(String error) {
+		this.loadErrors.add(error);
+	}
+
+	@Override
+	public Set<String> getLoadWarnings() {
+		return Collections.unmodifiableSet(this.loadWarnings);
+	}
+
+	public void addLoadWarning(String warning) {
+		this.loadWarnings.add(warning);
+	}
+
+	@Override
+	public Set<PDPPolicy> getLoadedPolicies() {
+		return Collections.unmodifiableSet(this.loadedPolicies);
+	}
+	
+	public void addLoadedPolicy(PDPPolicy policy) {
+		this.loadedPolicies.add(policy);
+	}
+
+	@Override
+	public Set<PDPPolicy> getFailedPolicies() {
+		return Collections.unmodifiableSet(this.failedPolicies);
+	}
+	
+	public void addFailedPolicy(PDPPolicy policy) {
+		this.failedPolicies.add(policy);
+	}
+
+	@Override
+	public boolean policiesOK() {
+		if (this.failedPolicies.size() > 0) {
+			return false;
+		}
+		return true;
+	}
+
+	@Override
+	public Set<PDPPIPConfig> getLoadedPipConfigs() {
+		return Collections.unmodifiableSet(this.loadedPIPConfigs);
+	}
+	
+	public void addLoadedPipConfig(PDPPIPConfig config) {
+		this.loadedPIPConfigs.add(config);
+	}
+
+	@Override
+	public Set<PDPPIPConfig> getFailedPipConfigs() {
+		return Collections.unmodifiableSet(this.failedPIPConfigs);
+	}
+	
+	public void addFailedPipConfig(PDPPIPConfig config) {
+		this.failedPIPConfigs.add(config);
+	}
+
+	@Override
+	public boolean pipConfigOK() {
+		if (this.failedPIPConfigs.size() > 0) {
+			return false;
+		}
+		return true;
+	}
+
+	@Override
+	public Set<PDP> getInSynchPDPs() {
+		return Collections.unmodifiableSet(this.inSynchPDPs);
+	}
+
+	public void addInSynchPDP(PDP pdp) {
+		this.inSynchPDPs.add(pdp);
+	}
+
+	@Override
+	public Set<PDP> getOutOfSynchPDPs() {
+		return Collections.unmodifiableSet(this.outOfSynchPDPs);
+	}
+
+	public void addOutOfSynchPDP(PDP pdp) {
+		this.outOfSynchPDPs.add(pdp);
+	}
+
+	@Override
+	public Set<PDP> getFailedPDPs() {
+		return Collections.unmodifiableSet(this.failedPDPs);
+	}
+
+	public void addFailedPDP(PDP pdp) {
+		this.failedPDPs.add(pdp);
+	}
+
+	@Override
+	public Set<PDP> getUpdatingPDPs() {
+		return Collections.unmodifiableSet(this.updatingPDPs);
+	}
+
+	public void addUpdatingPDP(PDP pdp) {
+		this.updatingPDPs.add(pdp);
+	}
+
+	@Override
+	public Set<PDP> getLastUpdateFailedPDPs() {
+		return Collections.unmodifiableSet(this.lastUpdateFailedPDPs);
+	}
+
+	public void addLastUpdateFailedPDP(PDP pdp) {
+		this.lastUpdateFailedPDPs.add(pdp);
+	}
+
+	@Override
+	@JsonIgnore
+	public Set<PDP> getUnknownStatusPDPs() {
+		return Collections.unmodifiableSet(this.unknownPDPs);
+	}
+
+	public void addUnknownPDP(PDP pdp) {
+		this.unknownPDPs.add(pdp);
+	}
+
+	@Override
+	public boolean pdpsOK() {
+		if (this.outOfSynchPDPs.size() > 0) {
+			return false;
+		}
+		if (this.failedPDPs.size() > 0) {
+			return false;
+		}
+		if (this.lastUpdateFailedPDPs.size() > 0) {
+			return false;
+		}
+		if (this.unknownPDPs.size() > 0) {
+			return false;
+		}
+		return true;
+	}
+
+	@Override
+	@JsonIgnore
+	public boolean isGroupOk() {
+		if (this.policiesOK() == false) {
+			return false;
+		}
+		if (this.pipConfigOK() == false) {
+			return false;
+		}
+		if (this.pdpsOK() == false) {
+			return false;
+		}
+		if (this.loadErrors.isEmpty() == false) {
+			return false;
+		}
+		return (this.status == Status.OK);
+	}
+	
+	public void reset() {
+		this.status = Status.OK;
+		
+		this.loadErrors.clear();
+		this.loadWarnings.clear();
+		this.loadedPolicies.clear();
+		this.failedPolicies.clear();
+		this.loadedPIPConfigs.clear();
+		this.failedPIPConfigs.clear();
+		this.inSynchPDPs.clear();
+		this.outOfSynchPDPs.clear();
+		this.failedPDPs.clear();
+		this.updatingPDPs.clear();
+		this.lastUpdateFailedPDPs.clear();
+		this.unknownPDPs.clear();
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result
+				+ (failedPDPs.hashCode());
+		result = prime
+				* result
+				+ (failedPIPConfigs.hashCode());
+		result = prime * result
+				+ (failedPolicies.hashCode());
+		result = prime * result
+				+ (inSynchPDPs.hashCode());
+		result = prime
+				* result
+				+ (lastUpdateFailedPDPs.hashCode());
+		result = prime * result
+				+ (loadErrors.hashCode());
+		result = prime * result
+				+ (loadWarnings.hashCode());
+		result = prime
+				* result
+				+ (loadedPIPConfigs.hashCode());
+		result = prime * result
+				+ (loadedPolicies.hashCode());
+		result = prime * result
+				+ (outOfSynchPDPs.hashCode());
+		result = prime * result + (status.hashCode());
+		result = prime * result
+				+ (unknownPDPs.hashCode());
+		result = prime * result
+				+ (updatingPDPs.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		StdPDPGroupStatus other = (StdPDPGroupStatus) obj;
+		if (!failedPDPs.equals(other.failedPDPs))
+			return false;
+		if (!failedPIPConfigs.equals(other.failedPIPConfigs))
+			return false;
+		if (!failedPolicies.equals(other.failedPolicies))
+			return false;
+		if (!inSynchPDPs.equals(other.inSynchPDPs))
+			return false;
+		if (!lastUpdateFailedPDPs.equals(other.lastUpdateFailedPDPs))
+			return false;
+		if (!loadErrors.equals(other.loadErrors))
+			return false;
+		if (!loadWarnings.equals(other.loadWarnings))
+			return false;
+		if (!loadedPIPConfigs.equals(other.loadedPIPConfigs))
+			return false;
+		if (!loadedPolicies.equals(other.loadedPolicies))
+			return false;
+		if (!outOfSynchPDPs.equals(other.outOfSynchPDPs))
+			return false;
+		if (status != other.status)
+			return false;
+		if (!unknownPDPs.equals(other.unknownPDPs))
+			return false;
+		if (!updatingPDPs.equals(other.updatingPDPs))
+			return false;
+		return true;
+	}
+
+	@Override
+	public String toString() {
+		return "StdPDPGroupStatus [status=" + status + ", loadErrors="
+				+ loadErrors + ", loadWarnings=" + loadWarnings
+				+ ", loadedPolicies=" + loadedPolicies + ", failedPolicies="
+				+ failedPolicies + ", loadedPIPConfigs=" + loadedPIPConfigs
+				+ ", failedPIPConfigs=" + failedPIPConfigs + ", inSynchPDPs="
+				+ inSynchPDPs + ", outOfSynchPDPs=" + outOfSynchPDPs
+				+ ", failedPDPs=" + failedPDPs + ", updatingPDPs="
+				+ updatingPDPs + ", lastUpdateFailedPDPs="
+				+ lastUpdateFailedPDPs + ", unknownPDPs=" + unknownPDPs + "]";
+	}
+
+}
diff --git a/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pap/StdPDPItemSetChangeNotifier.java b/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pap/StdPDPItemSetChangeNotifier.java
new file mode 100644
index 0000000..d23501f
--- /dev/null
+++ b/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pap/StdPDPItemSetChangeNotifier.java
@@ -0,0 +1,81 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP-XACML
+ * ================================================================================
+ * 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.std.pap;
+
+import java.util.Collection;
+import java.util.LinkedList;
+
+import org.onap.policy.xacml.api.pap.OnapPDP;
+import org.onap.policy.xacml.api.pap.OnapPDPGroup;
+
+public class StdPDPItemSetChangeNotifier {
+	
+	private Collection<StdItemSetChangeListener> listeners = null;
+	
+	public interface StdItemSetChangeListener {
+		
+		public void changed();
+		
+		public void groupChanged(OnapPDPGroup group);
+		
+		public void pdpChanged(OnapPDP pdp);
+
+	}
+	
+	public void addItemSetChangeListener(StdItemSetChangeListener listener) {
+		if (this.listeners == null) {
+			this.listeners = new LinkedList<StdItemSetChangeListener>();
+		}
+		this.listeners.add(listener);
+	}
+	
+	public void removeItemSetChangeListener(StdItemSetChangeListener listener) {
+		if (this.listeners != null) {
+			this.listeners.remove(listener);
+		}
+	}
+
+	public void fireChanged() {
+		if (this.listeners == null) {
+			return;
+		}
+		for (StdItemSetChangeListener l : this.listeners) {
+			l.changed();
+		}		
+	}
+
+	public void firePDPGroupChanged(OnapPDPGroup group) {
+		if (this.listeners == null) {
+			return;
+		}
+		for (StdItemSetChangeListener l : this.listeners) {
+			l.groupChanged(group);
+		}
+	}
+
+	public void firePDPChanged(OnapPDP pdp) {
+		if (this.listeners == null) {
+			return;
+		}
+		for (StdItemSetChangeListener l : this.listeners) {
+			l.pdpChanged(pdp);
+		}
+	}
+}
diff --git a/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pap/StdPDPPIPConfig.java b/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pap/StdPDPPIPConfig.java
new file mode 100644
index 0000000..f043846
--- /dev/null
+++ b/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pap/StdPDPPIPConfig.java
@@ -0,0 +1,216 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP-XACML
+ * ================================================================================
+ * 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.std.pap;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import com.att.research.xacml.api.pap.PDPPIPConfig;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.onap.policy.common.logging.flexlogger.FlexLogger; 
+import org.onap.policy.common.logging.flexlogger.Logger;
+
+public class StdPDPPIPConfig implements PDPPIPConfig, Serializable {
+	private static final long serialVersionUID = 1L;
+	private static Logger	logger	= FlexLogger.getLogger(StdPDPPIPConfig.class);
+	
+	private String id;
+	
+	private String name;
+	
+	private String description;
+	
+	private String classname;
+	
+	private Map<String,String> config = new HashMap<>();
+	
+	public StdPDPPIPConfig() {
+		
+	}
+
+	public StdPDPPIPConfig(String id) {
+		this.id = id;
+	}
+	
+	public StdPDPPIPConfig(String id, String name, String description) {
+		this(id);
+		this.name = name;
+		this.description = description;
+	}
+
+	public StdPDPPIPConfig(String id, Properties properties) {
+		this(id);
+		if ( ! this.initialize(properties) ) {
+			throw new IllegalArgumentException("PIP Engine '" + id + "' has no classname property in config");
+		}
+	}
+	
+	public boolean initialize(Properties properties) {
+		boolean classnameSeen = false;
+		for (Object key : properties.keySet()) {
+			if (key.toString().startsWith(this.id + ".")) {
+				if (logger.isDebugEnabled()) {
+					logger.debug("Found: " + key);
+				}
+				if (key.toString().equals(this.id + ".name")) {
+					this.name = properties.getProperty(key.toString());
+				} else if (key.toString().equals(this.id + ".description")) {
+					this.description = properties.getProperty(key.toString());
+				} else if (key.toString().equals(this.id + ".classname")) {
+					this.classname = properties.getProperty(key.toString());
+					classnameSeen = true;
+				}
+				// all properties, including the special ones located above, are included in the properties list
+				this.config.put(key.toString(), properties.getProperty(key.toString()));
+			}
+		}
+		return classnameSeen;
+	}
+
+	@Override
+	public String getId() {
+		return this.id;
+	}
+	
+	public void setId(String id) {
+		this.id = id;
+	}
+
+	@Override
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	@Override
+	public String getDescription() {
+		return this.description;
+	}
+	
+	public void setDescription(String description) {
+		this.description = description;
+	}
+
+	@Override
+	public String getClassname() {
+		return classname;
+	}
+
+	public void setClassname(String classname) {
+		this.classname = classname;
+	}
+
+	@Override
+	@JsonIgnore
+	public Map<String,String> getConfiguration() {
+		return Collections.unmodifiableMap(this.config);
+	}
+
+	public void setValues(Map<String,String> config) {
+		this.config = config;
+	}
+
+	@Override
+	@JsonIgnore
+	public boolean isConfigured() {
+		//
+		// Also include this in the JSON I/O if it is a data field rather than calculated
+		//
+		return true;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result
+				+ ((classname == null) ? 0 : classname.hashCode());
+		result = prime * result + ((config == null) ? 0 : config.hashCode());
+		result = prime * result
+				+ ((description == null) ? 0 : description.hashCode());
+		result = prime * result + ((id == null) ? 0 : id.hashCode());
+		result = prime * result + ((name == null) ? 0 : name.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		StdPDPPIPConfig other = (StdPDPPIPConfig) obj;
+		if (classname == null) {
+			if (other.classname != null)
+				return false;
+		} else if (!classname.equals(other.classname))
+			return false;
+		if (config == null) {
+			if (other.config != null)
+				return false;
+		} else if (!config.equals(other.config))
+			return false;
+		if (description == null) {
+			if (other.description != null)
+				return false;
+		} else if (!description.equals(other.description))
+			return false;
+		if (id == null) {
+			if (other.id != null)
+				return false;
+		} else if (!id.equals(other.id))
+			return false;
+		if (name == null) {
+			if (other.name != null)
+				return false;
+		} else if (!name.equals(other.name))
+			return false;
+		return true;
+	}
+
+	@Override
+	public String toString() {
+		return "StdPDPPIPConfig [id=" + id + ", name=" + name
+				+ ", description=" + description + ", classname=" + classname
+				+ ", config=" + config + "]";
+	}
+
+	
+	
+	//
+	// Methods needed for JSON serialization/deserialization
+	//
+
+	public Map<String, String> getConfig() {
+		return config;
+	}
+	public void setConfig(Map<String, String> config) {
+		this.config = config;
+	}
+	
+}
diff --git a/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pap/StdPDPPolicy.java b/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pap/StdPDPPolicy.java
new file mode 100644
index 0000000..892211a
--- /dev/null
+++ b/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pap/StdPDPPolicy.java
@@ -0,0 +1,366 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP-XACML
+ * ================================================================================
+ * 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.std.pap;
+
+import org.onap.policy.common.logging.eelf.PolicyLogger;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.net.URI;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Properties;
+
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicySetType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.onap.policy.xacml.util.XACMLPolicyScanner;
+
+import com.att.research.xacml.api.pap.PAPException;
+import com.att.research.xacml.api.pap.PDPPolicy;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.google.common.base.Splitter;
+import com.google.common.collect.Lists;
+
+
+public class StdPDPPolicy implements PDPPolicy, Serializable {
+	private static final long serialVersionUID = 1L;
+	private static Log	logger	= LogFactory.getLog(StdPDPPolicy.class);
+	
+	private String id = null;
+	
+	private String name = null;
+
+	private String policyId = null;
+	
+	private String description = null;
+	
+	private int[]	version = null;
+
+	private boolean isRoot = false;
+	
+	private boolean isValid = false;
+	
+	private URI location = null;
+	
+
+	public StdPDPPolicy(String id, boolean isRoot) {
+		this.id = id;
+		this.isRoot = isRoot;
+	}
+
+	public StdPDPPolicy(String id, boolean isRoot, String name) {
+		this(id, isRoot);
+		this.name = name;
+	}
+
+	
+	public StdPDPPolicy(String id, boolean isRoot, String name, URI location) throws IOException {
+		this(id, isRoot);
+		this.name = name;
+		this.location = location;
+		
+		//
+		// Read the policy data
+		//		
+		String theID = this.readPolicyData();
+
+		if (this.id == null) {
+			logger.debug("id is null so we are calling readPolicyData() to get the policyID");
+			this.id = theID;
+		}
+		
+		logger.debug("The final outcome of the constructor returned the following:  id = " + id + 
+						", location = " + location + ", name = " + name);
+		
+	}
+	
+	public StdPDPPolicy(String id, boolean isRoot, String name, URI location, boolean isValid, String policyId, 
+							String description, String version) throws IOException {
+		this(id, isRoot);
+		this.name = name;
+		this.location = location;
+		this.policyId = policyId;
+		this.description = description;
+		this.version = versionStringToArray(version);
+		this.isValid = isValid;
+		
+		logger.debug("The final outcome of the constructor returned the following:  id = " + id + 
+						", location = " + location + ", name = " + name + ", policyId = " + policyId +
+							", description = " + description + ", Version = " + version);
+		
+	}
+	
+	public StdPDPPolicy(String id, boolean isRoot, String name, URI location, boolean isFromAPI) throws IOException {
+		this(id, isRoot);
+		this.name = name;
+		this.location = location;
+		this.isValid = isFromAPI;
+		
+		logger.debug("The final outcome of the constructor returned the following:  id = " + id + 
+						", location = " + location + ", name = " + name);
+		
+	}
+
+	public StdPDPPolicy(String id, boolean isRoot, URI location, Properties properties) throws IOException {
+		this(id, isRoot);
+		this.location = location;
+		//
+		// Read the policy data
+		//
+		this.readPolicyData();
+		//
+		// See if there's a name
+		//
+		for (Object key : properties.keySet()) {
+			if (key.toString().equals(id + ".name")) {
+				this.name = properties.getProperty(key.toString());
+				break;
+			}
+		}
+	}
+	
+	
+	private String readPolicyData() throws IOException {
+		//
+		// Extract XACML policy information
+		//
+		URL url = this.location.toURL();
+		Object rootElement = XACMLPolicyScanner.readPolicy(url.openStream());
+		if (rootElement == null ||
+			(
+				! (rootElement instanceof PolicySetType) &&
+				! (rootElement instanceof PolicyType)
+			)	) {
+			logger.warn("No root policy element in URI: " + this.location.toString() + " : " + rootElement);
+			this.isValid = false;
+		} else {
+			this.version = versionStringToArray(XACMLPolicyScanner.getVersion(rootElement));
+			if (rootElement instanceof PolicySetType) {
+				this.policyId = ((PolicySetType)rootElement).getPolicySetId();
+				this.description = ((PolicySetType)rootElement).getDescription();
+				this.isValid = true;
+				this.version = versionStringToArray(((PolicySetType)rootElement).getVersion());
+			} else if (rootElement instanceof PolicyType) {
+				this.policyId = ((PolicyType)rootElement).getPolicyId();
+				this.description = ((PolicyType)rootElement).getDescription();
+				this.version = versionStringToArray(((PolicyType)rootElement).getVersion());
+				this.isValid = true;
+			} else {
+				PolicyLogger.error("Unknown root element: " + rootElement.getClass().getCanonicalName());
+			}
+		}
+		if (this.policyId != null) {
+			ArrayList<String> foo = Lists.newArrayList(Splitter.on(':').split(this.policyId));
+			if (foo.isEmpty() == false) {
+				return foo.get(foo.size() - 1);
+			}
+		}
+		return null;
+	}
+	
+	@Override
+	public String getId() {
+		return id;
+	}
+
+	public void setId(String id) {
+		this.id = id;
+	}
+
+	@Override
+	public String getName() {
+		return this.name;
+	}
+	
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	@Override
+	public String getPolicyId() {
+		return this.policyId;
+	}
+	
+	@Override
+	public String getDescription() {
+		return this.description;
+	}
+	
+	@Override
+	public String getVersion() {
+		return versionArrayToString(this.version);
+	}
+	
+	@Override
+	@JsonIgnore
+	public int[] getVersionInts() {
+		return version;
+	}
+
+	@Override
+	public boolean isRoot() {
+		return this.isRoot;
+	}
+
+	@Override
+	public boolean isValid()
+	{
+		return this.isValid;
+	}
+
+	@Override
+	@JsonIgnore
+	public InputStream getStream() throws PAPException, IOException {
+		try {
+			if (this.location != null) {
+				URL url = this.location.toURL();
+				return url.openStream();
+			}
+			return null;
+		} catch (FileNotFoundException e) {
+			throw new PAPException(e);
+		}
+	}
+
+	@Override
+	public URI getLocation() throws PAPException {
+		return this.location;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((id == null) ? 0 : id.hashCode());
+		result = prime * result
+				+ ((policyId == null) ? 0 : policyId.hashCode());
+		result = prime * result;
+		if (version != null) {
+			for (int i = 0; i < version.length; i++) {
+				result += version[i];
+			}
+		}
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		StdPDPPolicy other = (StdPDPPolicy) obj;
+		if (id == null) {
+			if (other.id != null)
+				return false;
+		} else if (!id.equals(other.id))
+			return false;
+		if (policyId == null) {
+			if (other.policyId != null)
+				return false;
+		} else if (!policyId.equals(other.policyId))
+			return false;
+		if (version != other.version)
+			return false;
+		return true;
+	}
+
+	@Override
+	public String toString() {
+		return "StdPDPPolicy [id=" + id + ", name=" + name + ", policyId="
+				+ policyId + ", description=" + description + ", version="
+				+ this.getVersion() + ", isRoot=" + isRoot + ", isValid=" + isValid
+				+ ", location=" + location + "]";
+	}
+	
+	
+	/**
+	 * Given a version string consisting of integers with dots between them, convert it into an array of ints.
+	 * 
+	 * @param version
+	 * @return
+	 * @throws NumberFormatException
+	 */
+	public static int[] versionStringToArray(String version) throws NumberFormatException {
+		if (version == null || version.length() == 0) {
+			return new int[0];
+		}
+		String[] stringArray = version.split("\\.");
+		int[] resultArray = new int[stringArray.length];
+		for (int i = 0; i < stringArray.length; i++) {
+			resultArray[i] = Integer.parseInt(stringArray[i]);
+		}
+		return resultArray;
+	}
+	
+	/**
+	 * Given an array representing a version, create the corresponding dot-separated string.
+	 * 
+	 * @param array
+	 * @return
+	 */
+	public static String versionArrayToString(int[] array) {
+		if (array == null || array.length == 0) {
+			return "";
+		}
+		String versionString = "";
+		if (array.length > 0) {
+			versionString = "" + array[0];
+			for (int i = 1; i < array.length; i++) {
+				versionString += "." + array[i];
+			}
+		}
+		return versionString;
+	}
+	
+
+	
+	//
+	// Methods needed for JSON Deserialization
+	//
+	public StdPDPPolicy() {}
+	
+	public void setPolicyId(String policyId) {
+		this.policyId = policyId;
+	}
+	public void setDescription(String description) {
+		this.description = description;
+	}
+	public void setVersion(String version) {
+		this.version = versionStringToArray(version);
+	}
+	public void setRoot(boolean isRoot) {
+		this.isRoot = isRoot;
+	}
+	public void setValid(boolean isValid) {
+		this.isValid = isValid;
+	}
+	public void setLocation(URI location) {
+		this.location = location;
+	}
+	
+}
diff --git a/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pap/StdPDPStatus.java b/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pap/StdPDPStatus.java
new file mode 100644
index 0000000..f875995
--- /dev/null
+++ b/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pap/StdPDPStatus.java
@@ -0,0 +1,265 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP-XACML
+ * ================================================================================
+ * 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.std.pap;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import com.att.research.xacml.api.pap.PDPPIPConfig;
+import com.att.research.xacml.api.pap.PDPPolicy;
+import com.att.research.xacml.api.pap.PDPStatus;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
+public class StdPDPStatus implements Serializable, PDPStatus {
+	private static final long serialVersionUID = 1L;
+	
+	private Status status = Status.UNKNOWN;
+
+	private Set<String>	loadErrors = new HashSet<>();
+	
+	private Set<String> loadWarnings = new HashSet<>();
+	
+	private Set<PDPPolicy> loadedPolicies = new HashSet<>();
+	
+	private Set<PDPPolicy> loadedRootPolicies = new HashSet<>();
+	
+	private Set<PDPPolicy> failedPolicies = new HashSet<>();
+	
+	private Set<PDPPIPConfig>	loadedPIPConfigs = new HashSet<>();
+	
+	private Set<PDPPIPConfig>	failedPIPConfigs = new HashSet<>();
+	
+	public StdPDPStatus() {
+	}
+
+	public void set(StdPDPStatus newStatus) {
+		this.status				=	newStatus.status;
+		this.loadErrors.clear();
+		this.loadErrors.addAll(newStatus.getLoadErrors());
+		this.loadWarnings.clear();
+		this.loadWarnings.addAll(newStatus.getLoadWarnings());
+		this.loadedPolicies.clear();
+		this.loadedPolicies.addAll(newStatus.getLoadedPolicies());
+		this.loadedRootPolicies.clear();
+		this.loadedRootPolicies.addAll(newStatus.getLoadedRootPolicies());
+		this.failedPolicies.clear();
+		this.failedPolicies.addAll(newStatus.getFailedPolicies());
+		this.loadedPIPConfigs.clear();
+		this.loadedPIPConfigs.addAll(newStatus.getLoadedPipConfigs());
+		this.failedPIPConfigs.clear();
+		this.failedPIPConfigs.addAll(newStatus.getFailedPipConfigs());
+	}
+	
+	
+
+	@Override
+	public Status getStatus() {
+		return this.status;
+	}
+	
+	public void setStatus(Status status) {
+		this.status = status;
+	}
+	
+	@Override
+	public Set<String> getLoadErrors() {
+		return Collections.unmodifiableSet(this.loadErrors);
+	}
+
+	public void setLoadErrors(Set<String> errors) {
+		this.loadErrors = errors;
+	}
+	
+	public void addLoadError(String error) {
+		this.loadErrors.add(error);
+	}
+
+	@Override
+	public Set<String> getLoadWarnings() {
+		return Collections.unmodifiableSet(this.loadWarnings);
+	}
+
+	public void setLoadWarnings(Set<String> warnings) {
+		this.loadWarnings = warnings;
+	}
+	
+	public void addLoadWarning(String warning) {
+		this.loadWarnings.add(warning);
+	}
+
+	@Override
+	public Set<PDPPolicy> getLoadedPolicies() {
+		return Collections.unmodifiableSet(this.loadedPolicies);
+	}
+	
+	public void setLoadedPolicies(Set<PDPPolicy> policies) {
+		this.loadedPolicies = policies;
+	}
+	
+	public void addLoadedPolicy(PDPPolicy policy) {
+		this.loadedPolicies.add(policy);
+	}
+	
+	@Override
+	public Set<PDPPolicy> getLoadedRootPolicies() {
+		return Collections.unmodifiableSet(this.loadedRootPolicies);
+	}
+	
+	public void setLoadedRootPolicies(Set<PDPPolicy> policies) {
+		this.loadedRootPolicies = policies;
+	}
+	
+	public void addRootPolicy(PDPPolicy policy) {
+		this.loadedRootPolicies.add(policy);
+	}
+	
+	public void addAllLoadedRootPolicies(Set<PDPPolicy> policies) {
+		this.loadedRootPolicies.addAll(policies);
+	}
+	
+	@Override
+	public Set<PDPPolicy> getFailedPolicies() {
+		return Collections.unmodifiableSet(this.failedPolicies);
+	}
+	
+	public void	setFailedPolicies(Set<PDPPolicy> policies) {
+		this.failedPolicies = policies;
+	}
+	
+	public void addFailedPolicy(PDPPolicy policy) {
+		this.failedPolicies.add(policy);
+	}
+
+	@Override
+	public boolean policiesOK() {
+		if (this.failedPolicies.size() > 0) {
+			return false;
+		}
+		return true;
+	}
+
+	@Override
+	public Set<PDPPIPConfig> getLoadedPipConfigs() {
+		return Collections.unmodifiableSet(this.loadedPIPConfigs);
+	}
+	
+	public void setLoadedPipConfigs(Set<PDPPIPConfig> configs) {
+		this.loadedPIPConfigs = configs;
+	}
+	
+	public void addLoadedPipConfig(PDPPIPConfig config) {
+		this.loadedPIPConfigs.add(config);
+	}
+
+	@Override
+	public Set<PDPPIPConfig> getFailedPipConfigs() {
+		return Collections.unmodifiableSet(this.failedPIPConfigs);
+	}
+
+	public void setFailedPipConfigs(Set<PDPPIPConfig> configs) {
+		this.failedPIPConfigs = configs;
+	}
+	
+	public void addFailedPipConfig(PDPPIPConfig config) {
+		this.failedPIPConfigs.add(config);
+	}
+
+	@Override
+	public boolean pipConfigOK() {
+		if (this.failedPIPConfigs.size() > 0) {
+			return false;
+		}
+		return true;
+	}
+
+	@Override
+	@JsonIgnore
+	public boolean isOk() {
+		if (this.policiesOK() == false) {
+			return false;
+		}
+		if (this.pipConfigOK() == false) {
+			return false;
+		}
+		return (this.status == Status.UP_TO_DATE);
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime
+				* result
+				+ (failedPIPConfigs.hashCode());
+		result = prime * result
+				+ (failedPolicies.hashCode());
+		result = prime * result
+				+ (loadErrors.hashCode());
+		result = prime * result
+				+ (loadWarnings.hashCode());
+		result = prime
+				* result
+				+ (loadedPIPConfigs.hashCode());
+		result = prime * result
+				+ (loadedPolicies.hashCode());
+		result = prime * result + (status.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		StdPDPStatus other = (StdPDPStatus) obj;
+		if (!failedPIPConfigs.equals(other.failedPIPConfigs))
+			return false;
+		if (!failedPolicies.equals(other.failedPolicies))
+			return false;
+		if (!loadErrors.equals(other.loadErrors))
+			return false;
+		if (!loadWarnings.equals(other.loadWarnings))
+			return false;
+		if (!loadedPIPConfigs.equals(other.loadedPIPConfigs))
+			return false;
+		if (!loadedPolicies.equals(other.loadedPolicies))
+			return false;
+		if (status != other.status)
+			return false;
+		return true;
+	}
+
+	@Override
+	public String toString() {
+		return "StdPDPStatus [status=" + status + ", loadErrors=" + loadErrors
+				+ ", loadWarnings=" + loadWarnings + ", loadedPolicies="
+				+ loadedPolicies + ", loadedRootPolicies=" + loadedRootPolicies 
+				+ ", failedPolicies=" + failedPolicies
+				+ ", loadedPIPConfigs=" + loadedPIPConfigs
+				+ ", failedPIPConfigs=" + failedPIPConfigs + "]";
+	}
+
+
+}
diff --git a/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pip/engines/OperationHistoryEngine.java b/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pip/engines/OperationHistoryEngine.java
new file mode 100644
index 0000000..f99855c
--- /dev/null
+++ b/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pip/engines/OperationHistoryEngine.java
@@ -0,0 +1,297 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP-XACML
+ * ================================================================================
+ * 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.std.pip.engines;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Properties;
+import java.util.Set;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Persistence;
+import javax.persistence.Query;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.eclipse.persistence.config.PersistenceUnitProperties;
+
+import com.att.research.xacml.api.Attribute;
+import com.att.research.xacml.api.AttributeValue;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.XACML;
+import com.att.research.xacml.api.XACML3;
+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.datatypes.DataTypes;
+import com.att.research.xacml.std.pip.StdMutablePIPResponse;
+import com.att.research.xacml.std.pip.StdPIPRequest;
+import com.att.research.xacml.std.pip.StdPIPResponse;
+import com.att.research.xacml.std.pip.engines.StdConfigurableEngine;
+import com.att.research.xacml.util.XACMLProperties;
+
+/**
+ * PIP Engine for Implementing {@link com.att.research.xacml.std.pip.engines.ConfigurableEngine} interface to provide
+ * attribute retrieval from Operation History Table.  
+ * 
+ * @version $Revision$
+ */
+public class OperationHistoryEngine extends StdConfigurableEngine{
+	public static final String DEFAULT_DESCRIPTION		= "PIP for retrieving Operations History from DB";
+	public static final String DEFAULT_ISSUER			= "org:onap:xacml:guard:historydb";
+	
+	private static final Log LOGGER= LogFactory.getLog(OperationHistoryEngine.class);
+	
+	private static final PIPRequest PIP_REQUEST_ACTOR	= new StdPIPRequest(
+			XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, 
+			new IdentifierImpl("actor"),
+			XACML.ID_DATATYPE_STRING);
+
+	private static final PIPRequest PIP_REQUEST_RECIPE	= new StdPIPRequest(
+			XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, 
+			new IdentifierImpl("recipe"), 
+			XACML.ID_DATATYPE_STRING);
+
+	private static final PIPRequest PIP_REQUEST_TARGET	= new StdPIPRequest(
+			XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, 
+			new IdentifierImpl("target"), 
+			XACML.ID_DATATYPE_STRING);
+
+	private void addIntegerAttribute(StdMutablePIPResponse stdPIPResponse, Identifier category, Identifier attributeId, int value, PIPRequest pipRequest) {
+		AttributeValue<BigInteger> attributeValue	= null;
+		try {
+			attributeValue	= DataTypes.DT_INTEGER.createAttributeValue(value);
+		} catch (Exception ex) {
+			LOGGER.error("Failed to convert " + value + " to an AttributeValue<Boolean>", ex);
+		}
+		if (attributeValue != null) {
+			stdPIPResponse.addAttribute(new StdMutableAttribute(category, attributeId, attributeValue, pipRequest.getIssuer()/*this.getIssuer()*/, false));
+		}
+	}
+
+	public OperationHistoryEngine() {
+		super();
+	}
+
+	@Override
+	public Collection<PIPRequest> attributesRequired() {
+		return new ArrayList<>();
+	}
+
+	@Override
+	public Collection<PIPRequest> attributesProvided() {
+		return new ArrayList<>();
+	}
+
+	@Override
+	public PIPResponse getAttributes(PIPRequest pipRequest, PIPFinder pipFinder) throws PIPException {
+		LOGGER.info("Entering FeqLimiter PIP");
+		/*
+		 * First check to see if the issuer is set and then match it
+		 */
+		String string;
+		if ((string = pipRequest.getIssuer()) == null) {
+			LOGGER.info("FeqLimiter PIP - No issuer in the request!");
+			return StdPIPResponse.PIP_RESPONSE_EMPTY;
+		}
+		else{
+			//Notice, we are checking here for the base issuer prefix.
+			if (!string.contains(this.getIssuer())) {
+				LOGGER.debug("Requested issuer '" + string + "' does not match " + (this.getIssuer() == null ? "null" : "'" + this.getIssuer() + "'"));
+				LOGGER.info("FeqLimiter PIP - Issuer "+ string +" does not match with: "+this.getIssuer());
+				return StdPIPResponse.PIP_RESPONSE_EMPTY;
+			}
+		}
+		String[] s1 = string.split("tw:");
+		String[] s2 = s1[1].split(":");
+		int timeWindowVal = Integer.parseInt(s2[0]);// number [of minutes, hours, days...]
+		String timeWindowScale = s2[1];//e.g., minute, hour, day, week, month, year
+		String actor = getActor(pipFinder).iterator().next();
+		String operation = getRecipe(pipFinder).iterator().next();
+		String target = getTarget(pipFinder).iterator().next();
+		String timeWindow = timeWindowVal + " " + timeWindowScale;
+		LOGGER.info("Going to query DB about: "+actor + " " + operation + " " + target + " " + timeWindow);
+		int countFromDB = getCountFromDB(actor, operation, target, timeWindowVal, timeWindowScale);
+		StdMutablePIPResponse stdPIPResponse	= new StdMutablePIPResponse();
+		this.addIntegerAttribute(stdPIPResponse,
+				XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, 
+				new IdentifierImpl("count"), 
+				countFromDB,
+				pipRequest);
+		return new StdPIPResponse(stdPIPResponse);
+	}
+
+	@Override
+	public void configure(String id, Properties properties) throws PIPException {
+		super.configure(id, properties);
+		if (this.getDescription() == null) {
+			this.setDescription(DEFAULT_DESCRIPTION);
+		}
+		if (this.getIssuer() == null) {
+			this.setIssuer(DEFAULT_ISSUER);
+		}
+	}
+
+	private PIPResponse getAttribute(PIPRequest pipRequest, PIPFinder pipFinder) {
+		PIPResponse pipResponse	= null;
+		try {
+			pipResponse	= pipFinder.getMatchingAttributes(pipRequest, this);
+			if (pipResponse.getStatus() != null && !pipResponse.getStatus().isOk()) {
+				LOGGER.info("Error retrieving " + pipRequest.getAttributeId().stringValue() + ": " + pipResponse.getStatus().toString());
+				pipResponse	= null;
+			}
+			if (pipResponse!=null && pipResponse.getAttributes().isEmpty()) {
+				LOGGER.info("No value for " + pipRequest.getAttributeId().stringValue());
+				pipResponse	= null;
+			}
+		} catch (PIPException ex) {
+			LOGGER.error("PIPException getting subject-id attribute: " + ex.getMessage(), ex);			
+		}
+		return pipResponse;
+	}
+
+
+	private Set<String> getActor(PIPFinder pipFinder) {
+		/*
+		 * Get the AT&T UID from either the subject id or the attuid property
+		 */
+		PIPResponse pipResponseATTUID	= this.getAttribute(PIP_REQUEST_ACTOR, pipFinder);
+		if (pipResponseATTUID == null) {
+			return new HashSet<>();
+		}
+		/*
+		 * Iterate over all of the returned results and do the LDAP requests
+		 */
+		Collection<Attribute> listATTUIDs	= pipResponseATTUID.getAttributes();
+		Set<String> setATTUIDs			= new HashSet<>();
+		for (Attribute attributeATTUID: listATTUIDs) {
+			Iterator<AttributeValue<String>> iterAttributeValues	= attributeATTUID.findValues(DataTypes.DT_STRING);
+			if (iterAttributeValues != null) {
+				while (iterAttributeValues.hasNext()) {
+					String attuid	= iterAttributeValues.next().getValue();
+					if (attuid != null) {
+						setATTUIDs.add(attuid);
+					}
+				}
+			}
+		}
+		return setATTUIDs;
+	}
+
+	private Set<String> getRecipe(PIPFinder pipFinder) {
+		/*
+		 * Get the AT&T UID from either the subject id or the attuid property
+		 */
+		PIPResponse pipResponseATTUID	= this.getAttribute(PIP_REQUEST_RECIPE, pipFinder);
+		if (pipResponseATTUID == null) {
+			return new HashSet<>();
+		}
+		/*
+		 * Iterate over all of the returned results and do the LDAP requests
+		 */
+		Collection<Attribute> listATTUIDs	= pipResponseATTUID.getAttributes();
+		Set<String> setATTUIDs			= new HashSet<>();
+		for (Attribute attributeATTUID: listATTUIDs) {
+			Iterator<AttributeValue<String>> iterAttributeValues	= attributeATTUID.findValues(DataTypes.DT_STRING);
+			if (iterAttributeValues != null) {
+				while (iterAttributeValues.hasNext()) {
+					String attuid	= iterAttributeValues.next().getValue();
+					if (attuid != null) {
+						setATTUIDs.add(attuid);
+					}
+				}
+			}
+		}
+		return setATTUIDs;
+	}
+
+
+	private Set<String> getTarget(PIPFinder pipFinder) {
+		/*
+		 * Get the AT&T UID from either the subject id or the attuid property
+		 */
+		PIPResponse pipResponseATTUID	= this.getAttribute(PIP_REQUEST_TARGET, pipFinder);
+		if (pipResponseATTUID == null) {
+			return new HashSet<>();
+		}
+		/*
+		 * Iterate over all of the returned results and do the LDAP requests
+		 */
+		Collection<Attribute> listATTUIDs	= pipResponseATTUID.getAttributes();
+		Set<String> setATTUIDs			= new HashSet<>();
+		for (Attribute attributeATTUID: listATTUIDs) {
+			Iterator<AttributeValue<String>> iterAttributeValues	= attributeATTUID.findValues(DataTypes.DT_STRING);
+			if (iterAttributeValues != null) {
+				while (iterAttributeValues.hasNext()) {
+					String attuid	= iterAttributeValues.next().getValue();
+					if (attuid != null) {
+						setATTUIDs.add(attuid);
+					}
+				}
+			}
+		}
+		return setATTUIDs;
+	}
+
+	private static int getCountFromDB(String actor, String operation, String target, int timeWindow, String timeUnits){
+		EntityManager em;
+		try{
+			Properties properties = XACMLProperties.getProperties();
+			properties.setProperty(PersistenceUnitProperties.ECLIPSELINK_PERSISTENCE_XML, "META-INF/operationHistoryPU.xml");
+			em = Persistence.createEntityManagerFactory("OperationsHistoryPU",properties).createEntityManager();
+		}catch(Exception e){
+			LOGGER.error("Test thread got Exception " + e.getLocalizedMessage() + " Can't connect to Operations History DB.", e);
+			return -1;
+		}
+		// Preventing SQL injection
+		if(!validTimeUnits(timeUnits)){
+			LOGGER.error("given PIP timeUnits is not valid. " + timeUnits);
+			em.close();
+			return -1;
+		}
+		String sql = "select count(*) as count from operationshistory10 where outcome<>'Failure_Guard' and actor=?"
+				+ " and operation=?"
+				+ " and target=?"
+				+ " and endtime between date_sub(now(),interval ? "+timeUnits+") and now()";
+		Query nq = em.createNativeQuery(sql);
+		nq.setParameter(1, actor);
+		nq.setParameter(2, operation);
+		nq.setParameter(3, target);
+		nq.setParameter(4, timeWindow);
+		int ret = ((Number)nq.getSingleResult()).intValue();
+		LOGGER.info("###########************** History count: " + ret);
+		em.close();
+		return ret;	
+	}
+	
+	// Validating Time Units to prevent SQL Injection. 
+	private static boolean validTimeUnits(String timeUnits) {
+		return (timeUnits.equalsIgnoreCase("minute") || timeUnits.equalsIgnoreCase("hour") || timeUnits.equalsIgnoreCase("day") 
+			|| timeUnits.equalsIgnoreCase("week") || timeUnits.equalsIgnoreCase("month")||timeUnits.equalsIgnoreCase("year"))?
+				true: false;
+	}
+}
diff --git a/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pip/engines/aaf/AAFEngine.java b/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pip/engines/aaf/AAFEngine.java
new file mode 100644
index 0000000..ee75c5f
--- /dev/null
+++ b/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pip/engines/aaf/AAFEngine.java
@@ -0,0 +1,272 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP-XACML
+ * ================================================================================
+ * 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.std.pip.engines.aaf;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.onap.policy.utils.AAFPolicyClient;
+import org.onap.policy.utils.AAFPolicyException;
+
+import com.att.research.xacml.api.Attribute;
+import com.att.research.xacml.api.AttributeValue;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.XACML3;
+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.datatypes.DataTypes;
+import com.att.research.xacml.std.pip.StdMutablePIPResponse;
+import com.att.research.xacml.std.pip.StdPIPRequest;
+import com.att.research.xacml.std.pip.StdPIPResponse;
+import com.att.research.xacml.std.pip.engines.StdConfigurableEngine;
+import com.att.research.xacml.util.XACMLProperties;
+
+/**
+ * PIP Engine for Implementing {@link com.att.research.xacml.std.pip.engines.ConfigurableEngine} interface to provide
+ * attribute retrieval from AAF interface.  
+ * 
+ * @version $Revision$
+ */
+public class AAFEngine extends StdConfigurableEngine {
+	
+	public static final String DEFAULT_DESCRIPTION		= "PIP for authenticating aaf attributes using the AAF REST interface";
+	public static final String DEFAULT_ISSUER			= "aaf";
+	
+	private static final String SUCCESS = "Success";
+	
+	public static final String AAF_RESULT= "AAF_RESULT";
+	public static final String AAF_RESPONSE= "AAF_RESPONSE";
+	// 
+	public static final Identifier AAF_RESPONSE_ID = new IdentifierImpl(AAF_RESPONSE);
+	public static final Identifier AAF_RESULT_ID = new IdentifierImpl(AAF_RESULT);
+	
+	//
+	private static final PIPRequest PIP_REQUEST_UID = new StdPIPRequest(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, new IdentifierImpl("AAF_ID"), XACML3.ID_DATATYPE_STRING);
+	private static final PIPRequest PIP_REQUEST_PASS =  new StdPIPRequest(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, new IdentifierImpl("AAF_PASS"), XACML3.ID_DATATYPE_STRING);
+	private static final PIPRequest PIP_REQUEST_TYPE = new StdPIPRequest(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, new IdentifierImpl("AAF_TYPE"), XACML3.ID_DATATYPE_STRING);
+	private static final PIPRequest PIP_REQUEST_INSTANCE = new StdPIPRequest(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, new IdentifierImpl("AAF_INSTANCE"), XACML3.ID_DATATYPE_STRING);
+	private static final PIPRequest PIP_REQUEST_ACTION = new StdPIPRequest(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, new IdentifierImpl("AAF_ACTION"), XACML3.ID_DATATYPE_STRING);
+	
+	private static final List<PIPRequest> mapRequiredAttributes	= new ArrayList<>();
+	static{ 
+		mapRequiredAttributes.add(new StdPIPRequest(PIP_REQUEST_UID));
+		mapRequiredAttributes.add(new StdPIPRequest(PIP_REQUEST_PASS));
+		mapRequiredAttributes.add(new StdPIPRequest(PIP_REQUEST_TYPE));
+		mapRequiredAttributes.add(new StdPIPRequest(PIP_REQUEST_INSTANCE));
+		mapRequiredAttributes.add(new StdPIPRequest(PIP_REQUEST_ACTION));
+	}
+	
+	private static final Map<PIPRequest, String> mapSupportedAttributes	= new HashMap<>();
+	static{
+		mapSupportedAttributes.put(new StdPIPRequest(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, AAF_RESPONSE_ID, XACML3.ID_DATATYPE_STRING), "response");
+		mapSupportedAttributes.put(new StdPIPRequest(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, AAF_RESULT_ID, XACML3.ID_DATATYPE_BOOLEAN), "result");
+	}
+	
+	protected Log logger	= LogFactory.getLog(this.getClass());
+	
+	public AAFEngine(){
+		//default constructor
+	}
+	
+	private PIPResponse getAttribute(PIPRequest pipRequest, PIPFinder pipFinder) {
+		PIPResponse pipResponse	= null;
+		try {
+			pipResponse	= pipFinder.getMatchingAttributes(pipRequest, this);
+			if (pipResponse.getStatus() != null && !pipResponse.getStatus().isOk()) {
+				this.logger.warn("Error retrieving " + pipRequest.getAttributeId().stringValue() + ": " + pipResponse.getStatus().toString());
+				pipResponse	= null;
+			}
+			if (pipResponse != null && pipResponse.getAttributes().isEmpty()) {
+				this.logger.warn("No value for " + pipRequest.getAttributeId().stringValue());
+				pipResponse	= null;
+			}
+		} catch (PIPException ex) {
+			this.logger.error("PIPException getting subject-id attribute: " + ex.getMessage(), ex);			
+		}
+		return pipResponse;
+	}
+	
+	private String getValue(PIPResponse pipResponse){
+		String result = null;
+		Collection<Attribute> listAttributes = pipResponse.getAttributes();
+		for(Attribute attribute: listAttributes){
+			Iterator<AttributeValue<String>> iterAttributeValues = attribute.findValues(DataTypes.DT_STRING);
+			if(iterAttributeValues!=null) {
+				while(iterAttributeValues.hasNext()){
+					result = iterAttributeValues.next().getValue();
+					break;
+				}
+			}
+		}
+		return result;
+	}
+	
+	private synchronized String getResult(PIPFinder pipFinder) {
+		PIPResponse pipResponseUID = this.getAttribute(PIP_REQUEST_UID, pipFinder);
+		PIPResponse pipResponsePass = this.getAttribute(PIP_REQUEST_PASS, pipFinder);
+		PIPResponse pipResponseType = this.getAttribute(PIP_REQUEST_TYPE, pipFinder);
+		PIPResponse pipResponseAction = this.getAttribute(PIP_REQUEST_ACTION, pipFinder);
+		PIPResponse pipResponseInstance = this.getAttribute(PIP_REQUEST_INSTANCE, pipFinder);
+		String response = null;
+		// Evaluate AAF if we have all the required values. 
+		if(pipResponseUID!=null && pipResponsePass!=null && pipResponseType != null && pipResponseAction!= null && pipResponseInstance!=null){
+			String userName = getValue(pipResponseUID);
+			String pass = getValue(pipResponsePass);
+			
+			AAFPolicyClient aafClient = null;
+			Properties properties;
+			try {
+                properties = XACMLProperties.getProperties();
+                logger.debug("environment : " + properties.getProperty("ENVIRONMENT"));
+            } catch (IOException e1) {
+                logger.error("Exception while getting the properties " + e1);
+                properties = new Properties();
+                properties.setProperty("AAF_LOG_LEVEL", "DEBUG");
+            }
+			if(userName!=null && pass!=null){
+				try {
+					aafClient = AAFPolicyClient.getInstance(properties);
+				} catch (AAFPolicyException e) {
+					logger.error("AAF configuration failed. " + e.getMessage() +e);
+				}
+				if(aafClient!=null){
+					if(aafClient.checkAuth(userName, pass)){
+						String type = getValue(pipResponseType);
+						String instance = getValue(pipResponseInstance);
+						String action = getValue(pipResponseAction);
+						if(aafClient.checkPerm(userName, pass, type, instance, action)){
+							response = SUCCESS + "Permissions Validated";
+						}else{
+							response = "No Permissions for "+userName+" to: "+type+", "+instance+", "+action; 
+						}
+					}else{
+						response = "Authentication Failed for the given Values";
+					}
+				}
+			}else{
+				response = "ID and Password are not given";
+			}
+			
+		}else{
+			response = "Insufficient Values to Evaluate AAF";
+		}
+		return response;
+	}
+	
+	private void addStringAttribute(StdMutablePIPResponse stdPIPResponse, Identifier category, Identifier attributeId, String value) {
+		if (value != null) {
+			AttributeValue<String> attributeValue	= null;
+			try {
+				attributeValue	= DataTypes.DT_STRING.createAttributeValue(value);
+			} catch (Exception ex) {
+				this.logger.error("Failed to convert " + value + " to an AttributeValue<String>", ex);
+			}
+			if (attributeValue != null) {
+				stdPIPResponse.addAttribute(new StdMutableAttribute(category, attributeId, attributeValue, this.getIssuer(), false));
+			}
+		}
+	}
+
+	private void addBooleanAttribute(StdMutablePIPResponse stdPIPResponse, Identifier category, Identifier attributeId, boolean value) {
+		AttributeValue<Boolean> attributeValue	= null;
+		try {
+			attributeValue	= DataTypes.DT_BOOLEAN.createAttributeValue(value);
+		} catch (Exception ex) {
+			this.logger.error("Failed to convert " + value + " to an AttributeValue<Boolean>", ex);
+		}
+		if (attributeValue != null) {
+			stdPIPResponse.addAttribute(new StdMutableAttribute(category, attributeId, attributeValue, this.getIssuer(), false));
+		}
+	}
+	
+	@Override
+	public PIPResponse getAttributes(PIPRequest pipRequest, PIPFinder pipFinder) throws PIPException {
+		/*
+		 * First check to see if the issuer is set and then match it
+		 */
+		String string;
+
+		if((string = pipRequest.getIssuer()) != null && !string.equals(this.getIssuer())) {
+			this.logger.debug("Requested issuer '" + string + "' does not match " + (this.getIssuer() == null ? "null" : "'" + this.getIssuer() + "'"));
+			return StdPIPResponse.PIP_RESPONSE_EMPTY;
+		}
+
+
+		/*
+		 * Drop the issuer and see if the request matches any of our supported queries
+		 */
+		PIPRequest pipRequestSupported	= (pipRequest.getIssuer() == null ? pipRequest : new StdPIPRequest(pipRequest.getCategory(), pipRequest.getAttributeId(), pipRequest.getDataTypeId()));
+		if (!mapSupportedAttributes.containsKey(pipRequestSupported)) {
+			this.logger.debug("Requested attribute '" + pipRequest.toString() + "' is not supported");
+			return StdPIPResponse.PIP_RESPONSE_EMPTY;
+		}
+		StdMutablePIPResponse stdPIPResponse = new StdMutablePIPResponse();
+		String response = this.getResult(pipFinder);
+		boolean result = false;
+		if(response != null && response.contains(SUCCESS)){
+			result = true;
+		}
+		this.addBooleanAttribute(stdPIPResponse, XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, AAF_RESULT_ID, result);
+		this.addStringAttribute(stdPIPResponse, XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, AAF_RESPONSE_ID, response);
+		return new StdPIPResponse(stdPIPResponse);
+	}
+
+	@Override
+	public void configure(String id, Properties properties) throws PIPException {
+		super.configure(id, properties);
+		if (this.getDescription() == null) {
+			this.setDescription(DEFAULT_DESCRIPTION);
+		}
+		if (this.getIssuer() == null) {
+			this.setIssuer(DEFAULT_ISSUER);
+		}
+	}
+	
+	@Override
+	public Collection<PIPRequest> attributesRequired() {
+		List<PIPRequest> attributes = new ArrayList<>();
+		for (PIPRequest attribute: mapRequiredAttributes) {
+			attributes.add(new StdPIPRequest(attribute));
+		}
+		return attributes;
+	}
+
+	@Override
+	public Collection<PIPRequest> attributesProvided() {
+		List<PIPRequest> attributes = new ArrayList<>();
+		for (PIPRequest attribute : mapSupportedAttributes.keySet()) {
+			attributes.add(new StdPIPRequest(attribute));
+		}
+		return attributes;
+	}
+	
+}
\ No newline at end of file
diff --git a/ONAP-XACML/src/main/java/org/onap/policy/xacml/util/MetricsUtil.java b/ONAP-XACML/src/main/java/org/onap/policy/xacml/util/MetricsUtil.java
new file mode 100644
index 0000000..91e99b8
--- /dev/null
+++ b/ONAP-XACML/src/main/java/org/onap/policy/xacml/util/MetricsUtil.java
@@ -0,0 +1,80 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP-XACML
+ * ================================================================================
+ * 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.util;
+
+public class MetricsUtil {
+	
+	public static class AvgLatency {
+		private long cumLatency = 0;
+		private long count = 0;
+		
+		public void compute(long latency) {
+			cumLatency += latency;
+			count++;
+		}
+		
+		public long avg() {
+			if (count == 0)
+				return 0;
+			
+			return (cumLatency / count);
+		}
+		
+		public void reset() {
+			cumLatency = 0;
+			count = 0;
+		}
+	}
+
+	public static class MinLatency {
+		private long min = Long.MAX_VALUE;
+		
+		public synchronized void compute(long ts) {
+			if (ts < min)
+				min = ts;
+		}
+		
+		public long min() {
+			return min;
+		}
+		
+		public void reset() {
+			min = Long.MAX_VALUE;
+		}
+	}
+
+	public static class MaxLatency {
+		private long max = Long.MIN_VALUE;
+		
+		public synchronized void compute(long ts) {
+			if (ts > max)
+				max = ts;
+		}
+		
+		public long max() {
+			return max;
+		}
+		
+		public void reset() {
+			max = Long.MIN_VALUE;
+		}
+	}
+
+}
diff --git a/ONAP-XACML/src/main/java/org/onap/policy/xacml/util/XACMLPolicyScanner.java b/ONAP-XACML/src/main/java/org/onap/policy/xacml/util/XACMLPolicyScanner.java
new file mode 100644
index 0000000..b43299e
--- /dev/null
+++ b/ONAP-XACML/src/main/java/org/onap/policy/xacml/util/XACMLPolicyScanner.java
@@ -0,0 +1,722 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP-XACML
+ * ================================================================================
+ * 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.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import org.onap.policy.common.logging.eelf.MessageCodes;
+import org.onap.policy.common.logging.eelf.PolicyLogger;
+
+import com.att.research.xacml.api.AttributeAssignment;
+import com.att.research.xacml.std.IdentifierImpl;
+import com.att.research.xacml.std.StdAttribute;
+import com.att.research.xacml.std.StdAttributeAssignment;
+import com.att.research.xacml.std.StdAttributeValue;
+import com.att.research.xacml.std.StdMutableAdvice;
+import com.att.research.xacml.std.StdMutableObligation;
+import com.att.research.xacml.util.XACMLPolicyScanner.Callback;
+import com.att.research.xacml.util.XACMLPolicyScanner.CallbackResult;
+
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionsType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AllOfType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AnyOfType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeAssignmentExpressionType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeSelectorType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeValueType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.ConditionType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.IdReferenceType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.MatchType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObligationExpressionType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObligationExpressionsType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicySetType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.RuleType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.TargetType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.VariableDefinitionType;
+
+/**
+ * class XACMLPolicyScanner
+ * 
+ * This class traverses the hierarchy of a XACML 3.0 policy. You can optionally pass a Callback class
+ * and override any desired methods to retrieve information from a policy. 
+ * 
+ *
+ */
+public class XACMLPolicyScanner {
+	
+	private static final Log logger				= LogFactory.getLog(XACMLPolicyScanner.class);
+	private Object policyObject = null;
+	private Callback callback = null;
+	
+	public XACMLPolicyScanner(Path filename, Callback callback) {
+		try (InputStream is = Files.newInputStream(filename)) {
+			this.policyObject = XACMLPolicyScanner.readPolicy(is);
+		} catch (IOException e) {
+			PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "XACMLPolicyScanner", "Failed to read policy");
+		}
+		this.callback = callback;
+	}
+	
+	public XACMLPolicyScanner(InputStream filename, Callback callback) {
+		try (InputStream is = filename) {
+			this.policyObject = XACMLPolicyScanner.readPolicy(is);
+		} catch (IOException e) {
+			PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "XACMLPolicyScanner", "Failed to read policy");
+		}
+		this.callback = callback;
+	}
+	
+	public XACMLPolicyScanner(PolicySetType policySet, Callback callback) {
+		this.policyObject = policySet;
+		this.callback = callback;
+	}
+	
+	public XACMLPolicyScanner(PolicySetType policySet) {
+		this(policySet, null);
+	}
+	
+	public XACMLPolicyScanner(PolicyType policy, Callback callback) {
+		this.policyObject = policy;
+		this.callback = callback;
+	}
+	
+	public XACMLPolicyScanner(PolicyType policy) {
+		this(policy, null);
+	}
+	
+	/**
+	 * Sets the callback interface to be used.
+	 * 
+	 * @param cb
+	 */
+	public void setCallback(Callback cb) {
+		this.callback = cb;
+	}
+	
+	/**
+	 * Saves the given callback object then calls the scan() method.
+	 * 
+	 * @param cb
+	 * @return
+	 */
+	public Object scan(Callback cb) {
+		this.callback = cb;
+		return this.scan();
+	}
+	
+	/**
+	 * 
+	 * This begins the scanning of the contained object.
+	 * 
+	 * @return - The PolicySet/Policy that was scanned.
+	 */
+	public Object scan() {
+		if (this.policyObject == null) {
+			return null;
+		}
+		if (this.callback != null) {
+			if (this.callback.onBeginScan(this.policyObject) == CallbackResult.STOP) {
+				return this.policyObject;
+			}
+		}
+		if (this.policyObject instanceof PolicyType) {
+			this.scanPolicy(null, (PolicyType) this.policyObject);
+		} else if (this.policyObject instanceof PolicySetType) {
+			this.scanPolicySet(null, (PolicySetType) this.policyObject);
+		} else {
+			PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW + "Unknown class type: " + this.policyObject.getClass().getCanonicalName());
+		}
+		if (this.callback != null) {
+			this.callback.onFinishScan(this.policyObject);
+		}
+		return this.policyObject;
+	}
+	
+	/**
+	 * This performs the scan of a PolicySet
+	 * 
+	 * @param parent - Its parent PolicySet. Can be null if this is the root.
+	 * @param policySet - The PolicySet object.
+	 * @return CallbackResult - CONTINUE to continue, STOP to terminate scanning.
+	 */
+	/**
+	 * @param parent
+	 * @param policySet
+	 * @return
+	 */
+	protected CallbackResult scanPolicySet(PolicySetType parent, PolicySetType policySet) {
+		if (logger.isTraceEnabled()) {
+			logger.trace("scanning policy set: " + policySet.getPolicySetId() + " " + policySet.getDescription());
+		}
+		if (this.callback != null) {
+			if (this.callback.onPreVisitPolicySet(parent, policySet) == CallbackResult.STOP) {
+				return CallbackResult.STOP;
+			}
+		}
+		//
+		// Scan its info
+		//
+		if (this.scanTarget(policySet, policySet.getTarget()) == CallbackResult.STOP) {
+			return CallbackResult.STOP;
+		}
+		if (this.scanObligations(policySet, policySet.getObligationExpressions()) == CallbackResult.STOP) {
+			return CallbackResult.STOP;
+		}
+		if (this.scanAdvice(policySet, policySet.getAdviceExpressions()) == CallbackResult.STOP) {
+			return CallbackResult.STOP;
+		}
+		//
+		// Iterate the policy sets and/or policies
+		//
+		List<JAXBElement<?>> list = policySet.getPolicySetOrPolicyOrPolicySetIdReference();
+		for (JAXBElement<?> element: list) {
+			if (element.getName().getLocalPart().equals("PolicySet")) {
+				if (this.scanPolicySet(policySet, (PolicySetType)element.getValue()) == CallbackResult.STOP) {
+					return CallbackResult.STOP;
+				}
+			} else if (element.getName().getLocalPart().equals("Policy")) {
+				if (this.scanPolicy(policySet, (PolicyType)element.getValue()) == CallbackResult.STOP) {
+					return CallbackResult.STOP;
+				}
+			} else if (element.getValue() instanceof IdReferenceType) {
+				if (element.getName().getLocalPart().equals("PolicySetIdReference")) {
+					
+				} else if (element.getName().getLocalPart().equals("PolicyIdReference")) {
+					
+				}
+			} else {
+				logger.warn("generating policy sets found unsupported element: " + element.getName().getNamespaceURI());
+			}
+		}
+		if (this.callback != null) {
+			if (this.callback.onPostVisitPolicySet(parent, policySet) == CallbackResult.STOP) {
+				return CallbackResult.STOP;
+			}
+		}
+		return CallbackResult.CONTINUE;
+	}
+	
+	/**
+	 * 
+	 * This performs scanning of the Policy object.
+	 * 
+	 * @param parent - The parent PolicySet of the policy. This can be null if this is a root Policy.
+	 * @param policy - The policy being scanned.
+	 * @return CallbackResult - CONTINUE to continue, STOP to terminate scanning.
+	 */
+	protected CallbackResult scanPolicy(PolicySetType parent, PolicyType policy) {
+		if (logger.isTraceEnabled()) {
+			logger.trace("scanning policy: " + policy.getPolicyId() + " " + policy.getDescription());
+		}
+		if (this.callback != null) {
+			if (this.callback.onPreVisitPolicy(parent, policy) == CallbackResult.STOP) {
+				return CallbackResult.STOP;
+			}
+		}
+		//
+		// Scan its info
+		//
+		if (this.scanTarget(policy, policy.getTarget()) == CallbackResult.STOP) {
+			return CallbackResult.STOP;
+		}
+		if (this.scanVariables(policy, policy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition()) == CallbackResult.STOP) {
+			return CallbackResult.STOP;
+		}
+		if (this.scanObligations(policy, policy.getObligationExpressions()) == CallbackResult.STOP) {
+			return CallbackResult.STOP;
+		}
+		if (this.scanAdvice(policy, policy.getAdviceExpressions()) == CallbackResult.STOP) {
+			return CallbackResult.STOP;
+		}
+		//
+		// Iterate the rules
+		//
+		List<Object> list = policy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition();
+		for (Object o: list) {
+			if (o instanceof RuleType) {
+				RuleType rule = (RuleType) o;
+				if (logger.isTraceEnabled()) {
+					logger.trace("scanning rule: " + rule.getRuleId() + " " + rule.getDescription());
+				}
+				if (this.callback != null) {
+					if (this.callback.onPreVisitRule(policy, rule) == CallbackResult.STOP) {
+						return CallbackResult.STOP;
+					}
+				}
+				if (this.scanTarget(rule, rule.getTarget()) == CallbackResult.STOP) {
+					return CallbackResult.STOP;
+				}
+				if (this.scanConditions(rule, rule.getCondition()) == CallbackResult.STOP) {
+					return CallbackResult.STOP;
+				}
+				if (this.scanObligations(rule, rule.getObligationExpressions()) == CallbackResult.STOP) {
+					return CallbackResult.STOP;
+				}
+				if (this.scanAdvice(rule, rule.getAdviceExpressions()) == CallbackResult.STOP) {
+					return CallbackResult.STOP;
+				}
+				if (this.callback != null) {
+					if (this.callback.onPostVisitRule(policy, rule) == CallbackResult.STOP) {
+						return CallbackResult.STOP;
+					}
+				}
+			} else if (o instanceof VariableDefinitionType) {
+				if (this.callback != null) {
+					if (this.callback.onVariable(policy, (VariableDefinitionType) o) == CallbackResult.STOP) {
+						return CallbackResult.STOP;
+					}
+				}
+			} else {
+				if (logger.isDebugEnabled()) {
+					logger.debug("scanning policy rules found unsupported object:" + o.toString());
+				}
+			}
+		}
+		if (this.callback != null) {
+			if (this.callback.onPostVisitPolicy(parent, policy) == CallbackResult.STOP) {
+				return CallbackResult.STOP;
+			}
+		}
+		return CallbackResult.CONTINUE;
+	}
+	
+	/**
+	 * Scans the given target for attributes. Its sole purpose is to return attributes found.
+	 * 
+	 * @param parent - The parent PolicySet/Policy/Rule for the target.
+	 * @param target - The target.
+	 * @return CallbackResult - CONTINUE to continue, STOP to terminate scanning.
+	 */
+	protected CallbackResult scanTarget(Object parent, TargetType target) {
+		if (target == null) {
+			return CallbackResult.CONTINUE;
+		}
+		List<AnyOfType> anyOfList = target.getAnyOf();
+		if (anyOfList != null) {
+			Iterator<AnyOfType> iterAnyOf = anyOfList.iterator();
+			while (iterAnyOf.hasNext()) {
+				AnyOfType anyOf = iterAnyOf.next();
+				List<AllOfType> allOfList = anyOf.getAllOf();
+				if (allOfList != null) {
+					Iterator<AllOfType> iterAllOf = allOfList.iterator();
+					while (iterAllOf.hasNext()) {
+						AllOfType allOf = iterAllOf.next();
+						List<MatchType> matchList = allOf.getMatch();
+						if (matchList != null) {
+							Iterator<MatchType> iterMatch = matchList.iterator();
+							while (iterMatch.hasNext()) {
+								MatchType match = iterMatch.next();
+								//
+								// Finally down to the actual attribute
+								//
+								StdAttribute attribute = null;
+								AttributeValueType value = match.getAttributeValue();
+								if (match.getAttributeDesignator() != null && value != null) {
+									AttributeDesignatorType designator = match.getAttributeDesignator();
+									//
+									// The content may be tricky
+									//
+									attribute = new StdAttribute(new IdentifierImpl(designator.getCategory()),
+																			new IdentifierImpl(designator.getAttributeId()),
+																			new StdAttributeValue<List<?>>(new IdentifierImpl(value.getDataType()), value.getContent()),
+																			designator.getIssuer(),
+																			false);
+								} else if (match.getAttributeSelector() != null && value != null) {
+									AttributeSelectorType selector = match.getAttributeSelector();
+									attribute = new StdAttribute(new IdentifierImpl(selector.getCategory()),
+																			new IdentifierImpl(selector.getContextSelectorId()),
+																			new StdAttributeValue<List<?>>(new IdentifierImpl(value.getDataType()), value.getContent()),
+																			null,
+																			false);
+								} else {
+									logger.warn("NULL designator/selector or value for match.");
+								}
+								if (attribute != null && this.callback != null) {
+									if (this.callback.onAttribute(parent, target, attribute) == CallbackResult.STOP) {
+										return CallbackResult.STOP;
+									}
+								}
+							}
+						}
+					}
+				}
+			}
+		}
+		return CallbackResult.CONTINUE;
+	}
+	
+	/**
+	 * Scan the list of obligations.
+	 * 
+	 * @param parent - The parent PolicySet/Policy/Rule for the obligation.
+	 * @param obligationExpressionsType - All the obligation expressions.
+	 * @return CallbackResult - CONTINUE to continue, STOP to terminate scanning.
+	 */
+	protected CallbackResult scanObligations(Object parent, ObligationExpressionsType obligationExpressionsType) {
+		if (obligationExpressionsType == null) {
+			return CallbackResult.CONTINUE;
+		}
+		List<ObligationExpressionType> expressions = obligationExpressionsType.getObligationExpression();
+		if (expressions == null || expressions.size() == 0) {
+			return CallbackResult.CONTINUE;
+		}
+		for (ObligationExpressionType expression : expressions) {
+			StdMutableObligation ob = new StdMutableObligation(new IdentifierImpl(expression.getObligationId()));
+			List<AttributeAssignmentExpressionType> assignments = expression.getAttributeAssignmentExpression();
+			if (assignments != null) {
+				for (AttributeAssignmentExpressionType assignment : assignments) {
+					// category is optional and may be null
+					IdentifierImpl categoryId = null;
+					if (assignment.getCategory() != null) {
+						categoryId = new IdentifierImpl(assignment.getCategory());
+					}
+					AttributeAssignment attribute = new StdAttributeAssignment(
+												categoryId,
+												new IdentifierImpl(assignment.getAttributeId()),
+												assignment.getIssuer(),
+												new StdAttributeValue<Object>(null, null)
+												);
+					ob.addAttributeAssignment(attribute);
+				}
+			}
+			if (this.callback != null) {
+				if (this.callback.onObligation(parent, expression, ob) == CallbackResult.STOP) {
+					return CallbackResult.STOP;
+				}
+			}
+		}
+		return CallbackResult.CONTINUE;
+	}
+
+	/**
+	 * 
+	 * Scans the list of advice expressions returning each individually.
+	 * 
+	 * @param parent - The parent PolicySet/Policy/Rule for the advice.
+	 * @param adviceExpressionstype - The list of advice expressions.
+	 * @return CallbackResult - CONTINUE to continue, STOP to terminate scanning.
+	 */
+	protected CallbackResult scanAdvice(Object parent, AdviceExpressionsType adviceExpressionstype) {
+		if (adviceExpressionstype == null) {
+			return CallbackResult.CONTINUE;
+		}
+		List<AdviceExpressionType> expressions = adviceExpressionstype.getAdviceExpression();
+		if (expressions == null || expressions.size() == 0) {
+			return CallbackResult.CONTINUE;
+		}
+		for (AdviceExpressionType expression : expressions) {
+			StdMutableAdvice ob = new StdMutableAdvice(new IdentifierImpl(expression.getAdviceId()));
+			List<AttributeAssignmentExpressionType> assignments = expression.getAttributeAssignmentExpression();
+			if (assignments != null) {
+				for (AttributeAssignmentExpressionType assignment : assignments) {
+					IdentifierImpl categoryId = null;
+					if (assignment.getCategory() != null) {
+						categoryId = new IdentifierImpl(assignment.getCategory());
+					}
+					AttributeAssignment attribute = new StdAttributeAssignment(
+												categoryId,
+												new IdentifierImpl(assignment.getAttributeId()),
+												assignment.getIssuer(),
+												new StdAttributeValue<Object>(null, null)
+												);
+					ob.addAttributeAssignment(attribute);
+				}
+			}
+			if (this.callback != null) {
+				if (this.callback.onAdvice(parent, expression, ob) == CallbackResult.STOP) {
+					return CallbackResult.STOP;
+				}
+			}
+		}
+		return CallbackResult.CONTINUE;
+	}
+	
+	/**
+	 * Scans the list of variable definitions.
+	 * 
+	 * @param policy - Policy object containing the variable definition.
+	 * @param list - List of variable definitions.
+	 * @return CallbackResult - CONTINUE to continue, STOP to terminate scanning.
+	 */
+	protected CallbackResult scanVariables(PolicyType policy, List<Object> list) {
+		if (list == null) {
+			return CallbackResult.CONTINUE;
+		}
+		for (Object o : list) {
+			if (o instanceof VariableDefinitionType) {
+				if (this.callback != null) {
+					if (this.callback.onVariable(policy, (VariableDefinitionType) o) == CallbackResult.STOP) {
+						return CallbackResult.STOP;
+					}
+				}
+			}
+		}
+		
+		return CallbackResult.CONTINUE;
+	}
+	
+	/**
+	 * Scans the list of conditions.
+	 * 
+	 * @param rule
+	 * @param condition
+	 * @return
+	 */
+	protected CallbackResult scanConditions(RuleType rule, ConditionType condition) {
+		if (condition != null) {
+			if (this.callback != null) {
+				if (this.callback.onCondition(rule, condition) == CallbackResult.STOP) {
+					return CallbackResult.STOP;
+				}
+			}
+		}
+		return CallbackResult.CONTINUE;
+	}
+	
+	/**
+	 * Reads the XACML XML policy file in and returns the version contained in the root Policy/PolicySet element.
+	 * 
+	 * @param policy - The policy file.
+	 * @return - The version string from the file (uninterpreted)
+	 * @throws IOException 
+	 */
+	public static String	getVersion(Path policy) throws IOException {
+		Object data = null;
+		try (InputStream is = Files.newInputStream(policy)) {
+			data = XACMLPolicyScanner.readPolicy(is);
+		} catch (IOException e) {
+			PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "XACMLPolicyScanner", "Failed to read policy");
+			throw e;
+		}
+		if (data == null) {
+			logger.warn("Version is null.");
+			return null;
+		}
+		return getVersion(data);
+	}
+		
+	/**
+	 * Reads the Policy/PolicySet element object and returns its current version.
+	 * 
+	 * @param data - Either a PolicySet or Policy XACML type object.
+	 * @return - The integer version value. -1 if it doesn't exist or was un-parsable.
+	 */
+	public static String	getVersion(Object data) {
+		String version = null;
+		try {
+			if (data instanceof PolicySetType) {
+				version = ((PolicySetType)data).getVersion();
+			} else if (data instanceof PolicyType) {
+				version = ((PolicyType)data).getVersion();
+			} else {
+				if (data != null) {
+					PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + "Expecting a PolicySet/Policy/Rule object. Got: " + data.getClass().getCanonicalName());
+				}
+				return null;
+			}
+			if (version != null && version.length() > 0) {
+				return version;
+			} else {
+				logger.warn("No version set in policy");
+			}
+		} catch (NumberFormatException e) {
+			PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "XACMLPolicyScanner", "Invalid version contained in policy: " + version);
+			return null;
+		}
+		return null;
+	}
+	
+	/**
+	 * Returns the Policy or PolicySet ID.
+	 * 
+	 * @param data - A XACML 3.0 Policy or PolicySet element object.
+	 * @return The policy/policyset's policy ID
+	 */
+	public static String getID(Object data) {
+		if (data instanceof PolicySetType) {
+			return ((PolicySetType)data).getPolicySetId();
+		} else if (data instanceof PolicyType) {
+			return ((PolicyType)data).getPolicyId();
+		} else {
+			PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + "Expecting a PolicySet/Policy/Rule object. Got: " + data.getClass().getCanonicalName());
+			return null;
+		}
+	}
+	
+	public static List<String> getCreatedByModifiedBy(Path policyPath) throws IOException{
+		String createdBy = "";
+		String modifiedBy= "";
+		String cValue = "@CreatedBy:";
+		String mValue = "@ModifiedBy:";
+		for(String line: Files.readAllLines(policyPath)){
+			line = line.replaceAll("\\s+", "");
+			if(line.isEmpty()){
+				continue;
+			}
+			if(line.contains("<Description>") && line.contains(cValue) && line.contains(mValue)){
+				createdBy = line.substring(line.indexOf(cValue) + cValue.length(), line.lastIndexOf(cValue));
+				modifiedBy = line.substring(line.indexOf(mValue) + mValue.length(), line.lastIndexOf(mValue));
+				break;
+			}
+		}
+		return Arrays.asList(createdBy, modifiedBy);
+	}
+	
+	//get the Created Name of the User on reading the Xml file
+	public static String getCreatedBy(Path policyPath) throws IOException{
+		String userId = "";
+		String value = "@CreatedBy:";
+		for(String line: Files.readAllLines(policyPath)){
+			line = line.replaceAll("\\s+", "");
+			if(line.isEmpty()){
+				continue;
+			}
+			if(line.contains("<Description>") && line.contains(value)){
+				userId = line.substring(line.indexOf(value) + value.length(), line.lastIndexOf(value));
+				break;
+			}
+		}
+		return userId;
+	}
+	
+	//get the Modified Name of the User on reading the Xml file
+	public static String getModifiedBy(Path policyPath) throws IOException{
+		String modifiedBy = "";
+		String value = "@ModifiedBy:";
+		for(String line: Files.readAllLines(policyPath)){
+			line = line.replaceAll("\\s+", "");
+			if(line.isEmpty()){
+				continue;
+			}
+			if(line.contains("<Description>") && line.contains(value)){
+				modifiedBy = line.substring(line.indexOf(value) + value.length(), line.lastIndexOf(value));
+				break;
+			}
+		}
+		return modifiedBy;
+	}
+
+	/**
+	 * readPolicy - does the work to read in policy data from a file.
+	 * 
+	 * @param policy - The path to the policy file.
+	 * @return - The policy data object. This *should* be either a PolicySet or a Policy.
+	 */
+	public static Object readPolicy(InputStream is) {
+		try {
+			//
+			// Create a DOM parser
+			//
+			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+		    dbf.setNamespaceAware(true);
+		    DocumentBuilder db = dbf.newDocumentBuilder();
+		    //
+		    // Parse the policy file
+		    //
+		    Document doc = db.parse(is);
+		    //
+		    // Because there is no root defined in xacml,
+		    // find the first element
+		    //
+			NodeList nodes = doc.getChildNodes();
+			Node node = nodes.item(0);
+			Element e = null;
+			if (node.getNodeType() == Node.ELEMENT_NODE) {
+				e = (Element) node;
+				//
+				// Is it a 3.0 policy?
+				//
+				if (e.getNamespaceURI().equals("urn:oasis:names:tc:xacml:3.0:core:schema:wd-17")) {
+					//
+					// A policyset or policy could be the root
+					//
+					if (e.getNodeName().endsWith("Policy")) {
+						//
+						// Now we can create the context for the policy set
+						// and unmarshall the policy into a class.
+						//
+						JAXBContext context = JAXBContext.newInstance(PolicyType.class);
+						Unmarshaller um = context.createUnmarshaller();
+						JAXBElement<PolicyType> root = um.unmarshal(e, PolicyType.class);
+						//
+						// Here is our policy set class
+						//
+						return root.getValue();
+					} else if (e.getNodeName().endsWith("PolicySet")) {
+						//
+						// Now we can create the context for the policy set
+						// and unmarshall the policy into a class.
+						//
+						JAXBContext context = JAXBContext.newInstance(PolicySetType.class);
+						Unmarshaller um = context.createUnmarshaller();
+						JAXBElement<PolicySetType> root = um.unmarshal(e, PolicySetType.class);
+						//
+						// Here is our policy set class
+						//
+						return root.getValue();
+					} else {
+						if (logger.isDebugEnabled()) {
+							logger.debug("Not supported yet: " + e.getNodeName());
+						}
+					}
+				} else {
+					logger.warn("unsupported namespace: " + e.getNamespaceURI());
+				}
+			} else {
+				if (logger.isDebugEnabled()) {
+					logger.debug("No root element contained in policy " + 
+								" Name: " + node.getNodeName() + " type: " + node.getNodeType() + 
+								" Value: " + node.getNodeValue());
+				}
+			}
+		} catch (Exception e) {
+			PolicyLogger.error(MessageCodes.ERROR_SCHEMA_INVALID, e, "XACMLPolicyScanner", "Exception in readPolicy");
+		}
+		return null;
+	}
+
+	/**
+	 * @return the policyObject
+	 */
+	public Object getPolicyObject() {
+		return policyObject;
+	}
+}
diff --git a/ONAP-XACML/src/main/java/org/onap/policy/xacml/util/XACMLPolicyWriter.java b/ONAP-XACML/src/main/java/org/onap/policy/xacml/util/XACMLPolicyWriter.java
new file mode 100644
index 0000000..14c8ffd
--- /dev/null
+++ b/ONAP-XACML/src/main/java/org/onap/policy/xacml/util/XACMLPolicyWriter.java
@@ -0,0 +1,344 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP-XACML
+ * ================================================================================
+ * 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.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
+
+import org.onap.policy.common.logging.eelf.MessageCodes;
+import org.onap.policy.common.logging.eelf.PolicyLogger;
+
+
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionsType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AllOfType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AnyOfType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeAssignmentExpressionType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeValueType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.MatchType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObjectFactory;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObligationExpressionType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObligationExpressionsType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicySetType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.RuleType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.TargetType;
+
+/**
+ * Helper static class for policy writing.
+ * 
+ *
+ */
+public class XACMLPolicyWriter {
+
+	/**
+	 * Helper static class that does the work to write a policy set to a file on disk.
+	 * 
+	 *
+	 */
+	public static Path writePolicyFile(Path filename, PolicySetType policySet) {
+		JAXBElement<PolicySetType> policySetElement = new ObjectFactory().createPolicySet(policySet);		
+		try {
+			JAXBContext context = JAXBContext.newInstance(PolicySetType.class);
+			Marshaller m = context.createMarshaller();
+			m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
+			m.marshal(policySetElement, filename.toFile());
+
+			if (Files.exists(filename)) {
+				return filename;
+			} else {
+				PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + "File does not exist after marshalling.");
+				return null;
+			}
+
+		} catch (JAXBException e) {
+			PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "XACMLPolicyWriter", "writePolicyFile failed");
+			return null;
+		}
+	}
+
+	/**
+	 * Helper static class that does the work to write a policy set to an output stream.
+	 * 
+	 *
+	 */
+	public static void writePolicyFile(OutputStream os, PolicySetType policySet) {
+		JAXBElement<PolicySetType> policySetElement = new ObjectFactory().createPolicySet(policySet);
+		try {
+			JAXBContext context = JAXBContext.newInstance(PolicySetType.class);
+			Marshaller m = context.createMarshaller();
+			m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
+			m.marshal(policySetElement, os);
+		} catch (JAXBException e) {
+			PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "XACMLPolicyWriter", "writePolicyFile failed");
+		}
+	}
+
+	/**
+	 * Helper static class that does the work to write a policy to a file on disk.
+	 * 
+	 *
+	 */
+	public static Path writePolicyFile(Path filename, PolicyType policy) {
+		JAXBElement<PolicyType> policyElement = new ObjectFactory().createPolicy(policy);		
+		try {
+			JAXBContext context = JAXBContext.newInstance(PolicyType.class);
+			Marshaller m = context.createMarshaller();
+			m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
+			m.marshal(policyElement, filename.toFile());
+
+			if (Files.exists(filename)) {
+				return filename;
+			} else {
+				PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + "File does not exist after marshalling.");
+				return null;
+			}
+
+		} catch (JAXBException e) {
+			PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "XACMLPolicyWriter", "writePolicyFile failed");
+			return null;
+		}		
+	}
+
+
+	/**
+	 * Helper static class that does the work to write a policy to a file on disk.
+	 * 
+	 *
+	 */
+	public static InputStream getXmlAsInputStream(PolicyType policy) {
+		JAXBElement<PolicyType> policyElement = new ObjectFactory().createPolicy(policy);		
+		try {
+			ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();			
+			JAXBContext context = JAXBContext.newInstance(PolicyType.class);
+			Marshaller m = context.createMarshaller();
+			m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
+			m.marshal(policyElement, byteArrayOutputStream);
+			ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
+
+			return byteArrayInputStream;
+
+		} catch (JAXBException e) {
+			PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "XACMLPolicyWriter", "writePolicyFile failed");
+			return null;
+		}		
+	}
+	/**
+	 * Helper static class that does the work to write a policy set to an output stream.
+	 * 
+	 *
+	 */
+	public static void writePolicyFile(OutputStream os, PolicyType policy) {
+		JAXBElement<PolicyType> policySetElement = new ObjectFactory().createPolicy(policy);		
+		try {
+			JAXBContext context = JAXBContext.newInstance(PolicyType.class);
+			Marshaller m = context.createMarshaller();
+			m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
+			m.marshal(policySetElement, os);
+		} catch (JAXBException e) {
+			PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "XACMLPolicyWriter", "writePolicyFile failed");
+		}
+	}
+	
+	@SuppressWarnings({ "unchecked", "rawtypes" })
+	public static String changeFileNameInXmlWhenRenamePolicy(Path filename) {
+
+		PolicyType policyType = null;
+		String extension = "";
+		String domain = null;
+		String repository = "repository";
+		if(filename.toString().contains("Config_")){
+			domain = filename.toString().substring(filename.toString().indexOf(repository) + (repository.toString().length()+1), filename.toString().indexOf("Config_"));		
+		}else if(filename.toString().contains("Action_")){
+			domain = filename.toString().substring(filename.toString().indexOf(repository) + (repository.toString().length()+1), filename.toString().indexOf("Action_"));
+		}else if(filename.toString().contains("Decision_")){
+			domain = filename.toString().substring(filename.toString().indexOf(repository) + (repository.toString().length()+1), filename.toString().indexOf("Decision_"));
+		}
+		if(domain.contains(File.separator)){
+			domain =	domain.replace(File.separator, ".");
+		}
+		try {
+			JAXBContext context = JAXBContext.newInstance(PolicyType.class);
+			Unmarshaller m = context.createUnmarshaller();
+			JAXBElement<PolicyType> policyElement = (JAXBElement<PolicyType>) m.unmarshal(filename.toFile());
+			policyType = policyElement.getValue();
+			if (policyType != null) {
+				TargetType targetType = policyType.getTarget();
+				List<AnyOfType> anyOfTypes = targetType.getAnyOf();
+				for( Iterator anyOfIte = anyOfTypes.iterator(); anyOfIte.hasNext(); ){
+					AnyOfType anyOfType = (AnyOfType) anyOfIte.next();
+					List<AllOfType> allOf = anyOfType.getAllOf();
+					for( Iterator allOfIte = allOf.iterator(); allOfIte.hasNext(); ){
+						AllOfType allOfType = (AllOfType) allOfIte.next();
+						List<MatchType> match = allOfType.getMatch();						
+						for( Iterator matchIte = match.iterator(); matchIte.hasNext();) {							
+							MatchType  matchType = (MatchType) matchIte.next();
+							if(matchType.getAttributeDesignator().getAttributeId().equals("PolicyName")){
+								AttributeValueType attributeValueType = matchType.getAttributeValue();
+								List<Object> contents = attributeValueType.getContent();
+								if (contents != null && contents.size() > 0) {
+									String value = (String) contents.get(0);
+									String version = value;
+									version = version.substring(0, version.lastIndexOf("."));
+									version = version.substring(version.lastIndexOf("."));
+									if(filename.toString().contains("Config_")){
+										value = value.substring(0, value.indexOf("Config_"));
+									}else{
+										value = value.substring(0, value.indexOf("Decision_"));
+									}
+									String tmp = filename.getFileName()+"";
+									String newName = tmp.substring(0, tmp.lastIndexOf("."));
+									attributeValueType.getContent().clear();
+									attributeValueType.getContent().add(domain + newName  + "." + "xml");
+								}	
+							}
+						}
+					}
+				}
+				if(filename.toString().contains("Config_") || filename.toString().contains("Action_")){	
+					List<Object> objects = policyType.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition();
+					if (objects != null && objects.size() > 0) {
+						for (Iterator ite = objects.iterator(); ite.hasNext();) {
+
+							RuleType  ruleType = (RuleType ) ite.next();
+							AdviceExpressionsType adviceExpressionsType = ruleType.getAdviceExpressions();
+							if (adviceExpressionsType != null) {
+								List<AdviceExpressionType> adviceExpressionTypes = adviceExpressionsType.getAdviceExpression();
+								if (adviceExpressionTypes != null && adviceExpressionTypes.size() > 0) {
+									for (Iterator iterator = adviceExpressionTypes
+											.iterator(); iterator.hasNext();) {
+										AdviceExpressionType adviceExpressionType = (AdviceExpressionType) iterator
+												.next();
+										if (adviceExpressionType.getAdviceId() != null && !adviceExpressionType.getAdviceId().equals("") && (adviceExpressionType.getAdviceId().equals("configID")
+												|| adviceExpressionType.getAdviceId().equals("faultID") || adviceExpressionType.getAdviceId().equals("PMID")||adviceExpressionType.getAdviceId().equals("firewallConfigID") 
+												|| adviceExpressionType.getAdviceId().equals("MSID")) || adviceExpressionType.getAdviceId().equals("GocID")||adviceExpressionType.getAdviceId().equals("GocHPID")||adviceExpressionType.getAdviceId().equals("BRMSRAWID")
+												||adviceExpressionType.getAdviceId().equals("BRMSPARAMID")|| adviceExpressionType.getAdviceId().equals("HPSuppID") || adviceExpressionType.getAdviceId().equals("HPFlapID") || adviceExpressionType.getAdviceId().equals("HPOverID"))
+										{
+											List<AttributeAssignmentExpressionType> attributeAssignmentExpressionTypes = adviceExpressionType.getAttributeAssignmentExpression();
+											if (attributeAssignmentExpressionTypes != null && attributeAssignmentExpressionTypes.size() > 0) {
+												for (Iterator iterator2 = attributeAssignmentExpressionTypes
+														.iterator(); iterator2.hasNext();) {
+													AttributeAssignmentExpressionType attributeAssignmentExpressionType = (AttributeAssignmentExpressionType) iterator2
+															.next();
+													if (attributeAssignmentExpressionType.getAttributeId().equals("URLID")) {
+														JAXBElement<AttributeValueType> attributeValueType = (JAXBElement<AttributeValueType>) attributeAssignmentExpressionType.getExpression();
+														AttributeValueType attributeValueType1 = attributeValueType.getValue();
+														String configUrl = "$URL";
+														String urlVal = (String) attributeValueType1.getContent().get(0);   
+														String origExtension = urlVal.substring(urlVal.lastIndexOf('.')+1).trim();
+														extension = origExtension;
+														attributeValueType1.getContent().clear();
+														String txtFileName = filename.getFileName().toString();
+														txtFileName = txtFileName.substring(0, txtFileName.lastIndexOf(".")+1) + origExtension;
+														txtFileName = configUrl+ File.separator + "Config" + File.separator + domain + txtFileName;
+														attributeValueType1.getContent().add(txtFileName);	
+													} else if (attributeAssignmentExpressionType.getAttributeId().equals("PolicyName")) {
+														JAXBElement<AttributeValueType> attributeValueType = (JAXBElement<AttributeValueType>) attributeAssignmentExpressionType.getExpression();
+														AttributeValueType attributeValueType1 = attributeValueType.getValue();
+														List<Object> contents = attributeValueType1.getContent();
+														if (contents != null && contents.size() > 0) {
+															String value = (String) contents.get(0);
+															String version = value;
+															version = version.substring(0, version.lastIndexOf("."));
+															version = version.substring(version.lastIndexOf("."));
+															value = value.substring(0, value.indexOf("Config_"));
+															String tmp = filename.getFileName()+"";
+															String newName = tmp.substring(0, tmp.lastIndexOf("."));
+															attributeValueType1.getContent().clear();
+															attributeValueType1.getContent().add(domain + newName + "." + "xml");
+														}										
+
+													}
+
+												}
+											}
+										}
+									}
+								}
+							}
+						}
+						if (objects != null && objects.size() > 0) {
+							for (Iterator ite1 = objects.iterator(); ite1.hasNext();) {
+
+								RuleType  ruleType1 = (RuleType ) ite1.next();
+								ObligationExpressionsType obligationExpressionsType = ruleType1.getObligationExpressions();
+								if (obligationExpressionsType != null) {
+									List<ObligationExpressionType> obligationExpressionType = obligationExpressionsType.getObligationExpression();
+									if (obligationExpressionType != null && obligationExpressionType.size() > 0) {
+										for (Iterator iterator = obligationExpressionType
+												.iterator(); iterator.hasNext();) {
+											ObligationExpressionType obligationExpressionTypes = (ObligationExpressionType) iterator
+													.next();
+											if (obligationExpressionTypes.getObligationId() != null && !obligationExpressionTypes.getObligationId().equals("")) {
+												List<AttributeAssignmentExpressionType> attributeAssignmentExpressionTypes = obligationExpressionTypes.getAttributeAssignmentExpression();
+												if (attributeAssignmentExpressionTypes != null && attributeAssignmentExpressionTypes.size() > 0) {
+													for (Iterator iterator2 = attributeAssignmentExpressionTypes
+															.iterator(); iterator2.hasNext();) {
+														AttributeAssignmentExpressionType attributeAssignmentExpressionType = (AttributeAssignmentExpressionType) iterator2
+																.next();
+														if (attributeAssignmentExpressionType.getAttributeId().equals("body")) {
+															JAXBElement<AttributeValueType> attributeValueType = (JAXBElement<AttributeValueType>) attributeAssignmentExpressionType.getExpression();
+															AttributeValueType attributeValueType1 = attributeValueType.getValue();
+															String configUrl = "$URL";
+															String urlVal = (String) attributeValueType1.getContent().get(0);    	
+															String origExtension = urlVal.substring(urlVal.lastIndexOf('.')+1).trim();
+															extension = "json";
+															attributeValueType1.getContent().clear();
+															String txtFileName = filename.getFileName().toString();
+															txtFileName = txtFileName.substring(0, txtFileName.lastIndexOf(".")+1) + origExtension;
+															txtFileName = configUrl+ File.separator + "Action" + File.separator + domain + txtFileName;
+															attributeValueType1.getContent().add(txtFileName);	
+														} 
+
+													}
+												}
+
+											}
+
+										}
+									}
+								}
+							}
+						}
+					}
+				}
+				writePolicyFile(filename, policyType);
+			}
+		}catch (JAXBException e) {
+			PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "XACMLPolicyWriter", "writePolicyFile failed");
+		}	
+
+		return extension;
+	}
+
+}
diff --git a/ONAP-XACML/src/main/resources/META-INF/operationHistoryPU.xml b/ONAP-XACML/src/main/resources/META-INF/operationHistoryPU.xml
new file mode 100644
index 0000000..a3770d3
--- /dev/null
+++ b/ONAP-XACML/src/main/resources/META-INF/operationHistoryPU.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ============LICENSE_START=======================================================
+  PolicyEngineUtils
+  ================================================================================
+  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=========================================================
+  -->
+
+<persistence version="2.1"
+	xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
+	<persistence-unit name="OperationsHistoryPU" transaction-type="RESOURCE_LOCAL">
+		<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
+		<properties>
+			<property name="eclipselink.ddl-generation" value="create-tables" />
+			<property name="eclipselink.logging.level" value="INFO" />
+		</properties>
+	</persistence-unit>
+</persistence>
+  
\ No newline at end of file
diff --git a/ONAP-XACML/src/main/resources/xacml.properties b/ONAP-XACML/src/main/resources/xacml.properties
new file mode 100644
index 0000000..5be3939
--- /dev/null
+++ b/ONAP-XACML/src/main/resources/xacml.properties
@@ -0,0 +1,46 @@
+###
+# ============LICENSE_START=======================================================
+# ONAP-XACML
+# ================================================================================
+# 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=========================================================
+###
+
+# Default XACML Properties File
+# Standard API Factories
+#
+xacml.dataTypeFactory=org.onap.policy.xacml.std.StdDataTypeFactory
+xacml.pdpEngineFactory=com.att.research.xacmlatt.pdp.ATTPDPEngineFactory
+xacml.pepEngineFactory=org.onap.policy.xacml.std.pep.StdEngineFactory
+xacml.pipFinderFactory=org.onap.policy.xacml.std.pip.StdPIPFinderFactory
+
+# If there is a standard set of PIPEngines:
+# xacml.pip.engines=engine1,engine2,...,engineN
+# engine1.classname=com.att.research.xacmlpip.OraclePIP
+# engine1.prop1=foo
+# engine1.prop2=bar
+# ...
+# engine2.classname=com.att.research.xacmlpip.ActiveDirectoryPIP
+# ...
+
+# AT&T PDP Implementation Factories
+#
+xacml.att.evaluationContextFactory=com.att.research.xacmlatt.pdp.std.StdEvaluationContextFactory
+xacml.att.combiningAlgorithmFactory=com.att.research.xacmlatt.pdp.std.StdCombiningAlgorithmFactory
+xacml.att.functionDefinitionFactory=com.att.research.xacmlatt.pdp.std.StdFunctionDefinitionFactory
+xacml.att.policyFinderFactory=com.att.research.xacmlatt.pdp.std.StdPolicyFinderFactory
+
+# If there is a standard policy for the engine:
+# xacml.att.stdPolicyFinderFactory.rootPolicyFile=/etc/stdpolicyset.xml
diff --git a/ONAP-XACML/src/test/java/org/onap/policy/xacml/test/std/pap/StdEngineFactoryTest.java b/ONAP-XACML/src/test/java/org/onap/policy/xacml/test/std/pap/StdEngineFactoryTest.java
new file mode 100644
index 0000000..3fa4955
--- /dev/null
+++ b/ONAP-XACML/src/test/java/org/onap/policy/xacml/test/std/pap/StdEngineFactoryTest.java
@@ -0,0 +1,51 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP-XACML
+ * ================================================================================
+ * 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.test.std.pap;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.util.Properties;
+
+import org.junit.Test;
+import org.onap.policy.xacml.std.pap.StdEngineFactory;
+
+import com.att.research.xacml.api.pap.PAPException;
+import com.att.research.xacml.util.FactoryException;
+
+public class StdEngineFactoryTest {
+
+
+	@Test
+	public void testStdEngineFactory() throws FactoryException, PAPException, IOException{
+		
+		StdEngineFactory stdFactory = new StdEngineFactory();
+		System.setProperty("xacml.pap.pdps", "src/test/resources/pdps");
+		assertTrue(stdFactory.newEngine() != null);
+		Properties properties = new Properties();
+		properties.setProperty("xacml.pap.pdps", "src/test/resources/pdps");
+		assertTrue(stdFactory.newEngine(properties) != null);
+		
+		StdEngineFactory stdFactoryNew = new StdEngineFactory();
+		System.setProperty("xacml.pap.pdps", "src/test/resources/pdpstest");
+		assertTrue(stdFactoryNew.newEngine() != null);
+
+	}
+}
diff --git a/ONAP-XACML/src/test/java/org/onap/policy/xacml/test/util/AAFEngineTest.java b/ONAP-XACML/src/test/java/org/onap/policy/xacml/test/util/AAFEngineTest.java
new file mode 100644
index 0000000..65646e1
--- /dev/null
+++ b/ONAP-XACML/src/test/java/org/onap/policy/xacml/test/util/AAFEngineTest.java
@@ -0,0 +1,24 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP-XACML
+ * ================================================================================
+ * 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.test.util;
+
+public class AAFEngineTest {
+
+}
diff --git a/ONAP-XACML/src/test/java/org/onap/policy/xacml/test/util/MetricsUtilTest.java b/ONAP-XACML/src/test/java/org/onap/policy/xacml/test/util/MetricsUtilTest.java
new file mode 100644
index 0000000..041acde
--- /dev/null
+++ b/ONAP-XACML/src/test/java/org/onap/policy/xacml/test/util/MetricsUtilTest.java
@@ -0,0 +1,52 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP-XACML
+ * ================================================================================
+ * 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.test.util;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+import org.onap.policy.xacml.util.MetricsUtil;
+
+public class MetricsUtilTest {
+	
+	@Test
+	public void metricsUtilTest(){
+		MetricsUtil.AvgLatency avgLatency = new MetricsUtil.AvgLatency();
+		avgLatency.compute(0);
+		assertTrue(avgLatency.avg() == 0);
+		avgLatency.compute(2);
+		assertTrue(avgLatency.avg() == 1);
+		avgLatency.reset();
+		assertTrue(avgLatency.avg() == 0);
+		
+		MetricsUtil.MaxLatency maxLatency = new MetricsUtil.MaxLatency();
+		maxLatency.compute(2);
+		assertTrue(maxLatency.max() == 2);
+		maxLatency.reset();
+		assertTrue(maxLatency.max() < 0);
+		
+		MetricsUtil.MinLatency minLatency = new MetricsUtil.MinLatency();
+		minLatency.compute(2);
+		assertTrue(minLatency.min() == 2);
+		minLatency.reset();
+		assertTrue(minLatency.min() > 0);
+	}
+
+}
diff --git a/ONAP-XACML/src/test/java/org/onap/policy/xacml/test/util/XACMLPolicyScannerTest.java b/ONAP-XACML/src/test/java/org/onap/policy/xacml/test/util/XACMLPolicyScannerTest.java
new file mode 100644
index 0000000..09dcf83
--- /dev/null
+++ b/ONAP-XACML/src/test/java/org/onap/policy/xacml/test/util/XACMLPolicyScannerTest.java
@@ -0,0 +1,88 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP-XACML
+ * ================================================================================
+ * 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.test.util;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.policy.xacml.util.XACMLPolicyScanner;
+
+import com.att.research.xacml.util.XACMLPolicyScanner.Callback;
+
+public class XACMLPolicyScannerTest {
+
+	private static final Log logger				= LogFactory.getLog(XACMLPolicyScannerTest.class);
+	private static Path configPolicyPathValue;
+	private static Path actionPolicyPathValue;
+	
+	@Before
+	public void setUp() {
+		File templateFile;
+		ClassLoader classLoader = getClass().getClassLoader();
+        try {
+        	templateFile = new File(classLoader.getResource("Config_SampleTest1206.1.xml").getFile());
+        	configPolicyPathValue = templateFile.toPath();
+        	templateFile = new File(classLoader.getResource("Action_TestActionPolicy.1.xml").getFile());
+        	actionPolicyPathValue = templateFile.toPath();
+		} catch (Exception e1) {
+			logger.error("Exception Occured"+e1);
+		}
+	}
+	
+	@Test
+	public void xacmlPolicyScannerTest() throws IOException{
+		Callback callback = null;
+		try{
+			XACMLPolicyScanner actionScanner = new XACMLPolicyScanner(actionPolicyPathValue, callback);
+			assertTrue(actionScanner.getPolicyObject() != null);
+			Object actionObject = actionScanner.scan();
+			assertTrue(actionObject != null);
+			
+			XACMLPolicyScanner scanner = new XACMLPolicyScanner(configPolicyPathValue, callback);
+			assertTrue(scanner.getPolicyObject() != null);
+			Object object = scanner.scan();
+			assertTrue(object != null);
+			String id = XACMLPolicyScanner.getID(scanner.getPolicyObject());
+			assertTrue(id.equals("urn:com:xacml:policy:id:0b67998b-57e2-4e25-9ea9-f9154bf18df1"));
+			String version = XACMLPolicyScanner.getVersion(scanner.getPolicyObject());
+			assertTrue(version.equals("1"));
+			String versionFromPath = XACMLPolicyScanner.getVersion(configPolicyPathValue);
+			assertTrue(versionFromPath.equals("1"));
+			List<String> returnValue = XACMLPolicyScanner.getCreatedByModifiedBy(configPolicyPathValue);
+			assertTrue(returnValue.get(0).equals("test"));
+			String createdBy = XACMLPolicyScanner.getCreatedBy(configPolicyPathValue);
+			assertTrue(createdBy.equals("test"));
+			String modifiedBy = XACMLPolicyScanner.getModifiedBy(configPolicyPathValue);
+			assertTrue(modifiedBy.equals("test"));
+		}catch(Exception e){
+			fail();
+			logger.error("Exception Occured"+e);
+		}
+	}
+}
diff --git a/ONAP-XACML/src/test/java/org/onap/policy/xacml/test/util/XACMLPolicyWriterTest.java b/ONAP-XACML/src/test/java/org/onap/policy/xacml/test/util/XACMLPolicyWriterTest.java
new file mode 100644
index 0000000..c948716
--- /dev/null
+++ b/ONAP-XACML/src/test/java/org/onap/policy/xacml/test/util/XACMLPolicyWriterTest.java
@@ -0,0 +1,62 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP-XACML
+ * ================================================================================
+ * 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.test.util;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Path;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.policy.xacml.util.XACMLPolicyWriter;
+
+public class XACMLPolicyWriterTest {
+	private static final Log logger				= LogFactory.getLog(XACMLPolicyWriterTest.class);
+	private static Path configPolicyPathValue;
+	private static Path actionPolicyPathValue;
+	
+	@Before
+	public void setUp() {
+		File templateFile;
+		ClassLoader classLoader = getClass().getClassLoader();
+        try {
+        	templateFile = new File(classLoader.getResource("Config_SampleTest1206.1.xml").getFile());
+        	configPolicyPathValue = templateFile.toPath();
+        	templateFile = new File(classLoader.getResource("Action_TestActionPolicy.1.xml").getFile());
+        	actionPolicyPathValue = templateFile.toPath();
+		} catch (Exception e1) {
+			logger.error("Exception Occured"+e1);
+		}
+	}
+	
+	@SuppressWarnings("static-access")
+	@Test
+	public void xacmlPolicyWriterTest() throws IOException{
+		XACMLPolicyWriter writer = new XACMLPolicyWriter();
+		String configResponseValue = writer.changeFileNameInXmlWhenRenamePolicy(configPolicyPathValue);
+		assertTrue(configResponseValue.equals("txt"));
+		String actionResponseValue = writer.changeFileNameInXmlWhenRenamePolicy(actionPolicyPathValue);
+		assertTrue(actionResponseValue.equals("json"));
+	}
+}
diff --git a/ONAP-XACML/src/test/resources/Action_TestActionPolicy.1.xml b/ONAP-XACML/src/test/resources/Action_TestActionPolicy.1.xml
new file mode 100644
index 0000000..a3b483f
--- /dev/null
+++ b/ONAP-XACML/src/test/resources/Action_TestActionPolicy.1.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+ <Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="urn:xacml:policy:id:b8e180de-3dcc-4b5b-814d-925e674e573c" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:permit-overrides">
+     <Description>TestActionPolicy@CreatedBy:test@CreatedBy:@ModifiedBy:test@ModifiedBy:</Description>
+     <Target>
+         <AnyOf>
+             <AllOf>
+                 <Match MatchId="org.onap.function.regex-match">
+                     <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">12</AttributeValue>
+                     <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="SamplTest" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+                 </Match>
+             </AllOf>
+         </AnyOf>
+     </Target>
+     <Rule RuleId="" Effect="Permit">
+         <Target/>
+         <Condition>
+             <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
+                 <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case">
+                     <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+                         <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="SamplTest" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+                     </Apply>
+                     <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">test</AttributeValue>
+                 </Apply>
+                 <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case">
+                     <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+                         <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="SamplTest" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+                     </Apply>
+                     <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Sample</AttributeValue>
+                 </Apply>
+             </Apply>
+         </Condition>
+         <ObligationExpressions>
+             <ObligationExpression ObligationId="Test" FulfillOn="Permit">
+                 <AttributeAssignmentExpression AttributeId="performer" Category="urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject">
+                     <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">PEPAction</AttributeValue>
+                 </AttributeAssignmentExpression>
+                 <AttributeAssignmentExpression AttributeId="type" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource">
+                     <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">REST</AttributeValue>
+                 </AttributeAssignmentExpression>
+                 <AttributeAssignmentExpression AttributeId="url" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource">
+                     <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#anyURI">http://localhost.com</AttributeValue>
+                 </AttributeAssignmentExpression>
+                 <AttributeAssignmentExpression AttributeId="method" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource">
+                     <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">GET</AttributeValue>
+                 </AttributeAssignmentExpression>
+                 <AttributeAssignmentExpression AttributeId="body" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource">
+                     <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#anyURI">$URL/Action/com.Action_TestActionPolicy.1.xml.json</AttributeValue>
+                 </AttributeAssignmentExpression>
+             </ObligationExpression>
+         </ObligationExpressions>
+     </Rule>
+ </Policy>
\ No newline at end of file
diff --git a/ONAP-XACML/src/test/resources/CSVPolicy.xml b/ONAP-XACML/src/test/resources/CSVPolicy.xml
new file mode 100644
index 0000000..6396e66
--- /dev/null
+++ b/ONAP-XACML/src/test/resources/CSVPolicy.xml
@@ -0,0 +1,205 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+  ============LICENSE_START=======================================================
+  ONAP-XACML
+  ================================================================================
+  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=========================================================
+  -->
+
+<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="urn:com:xacml:policy:id:fb9e6bed-b5dd-430c-acd4-1baed0c1f1cf" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-unless-permit">
+    <Description>This Policy handles the Take action and Advice action operations. </Description>
+    <Target />
+	<!--<Target>
+        <AnyOf>
+            <AllOf>
+                <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">VM</AttributeValue>
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+                </Match>
+            </AllOf>
+        </AnyOf>
+    </Target> -->
+    <VariableDefinition VariableId="doesItRequireNewVM">
+        <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:or">
+            <Description>Check the CPU Utilization or Network Load</Description>
+            <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-greater-than">
+                <Description>Load</Description>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:labs:onap:resource:vm:load" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="true"/>
+                </Apply>
+				<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">95</AttributeValue>
+                <!--<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+                    <AttributeDesignator Category="com:att:research:xacml:test:pip:csv:category:server" AttributeId="com:att:research:xacml:test:pip:csv:server:loadval" DataType="http://www.w3.org/2001/XMLSchema#integer" Issuer="com:att:research:xacml:test:pip:csv" MustBePresent="false"/>
+                </Apply> -->
+            </Apply>
+            <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-greater-than">
+                <Description>CPU</Description>
+                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:labs:onap:resource:vm:cpu" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="true"/>
+                </Apply>
+				<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">95</AttributeValue>
+                <!-- <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+                    <AttributeDesignator Category="com:att:research:xacml:test:pip:csv:category:server" AttributeId="com:att:research:xacml:test:pip:csv:server:cpuval" DataType="http://www.w3.org/2001/XMLSchema#integer" Issuer="com:att:research:xacml:test:pip:csv" MustBePresent="false"/>
+                </Apply> -->
+            </Apply>
+        </Apply>
+    </VariableDefinition>
+	<Rule RuleId="urn:com:xacml:rule:id:9f8e2241-8205-4656-b6f6-143637cc0c66" Effect="Permit">
+        <Description>Permit to create a new VM with Obligation</Description>
+        <Target />
+		<!--<Target>
+			<AnyOf>
+				<AllOf>
+					<Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+						<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">create_Action</AttributeValue>
+						<AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+					</Match>
+				</AllOf>
+			</AnyOf>
+		</Target> -->
+		<Condition>
+            <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+                <Description>If the Requirement has met create the VM</Description>
+                <VariableReference VariableId="doesItRequireNewVM"/>
+                <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue>
+            </Apply>
+        </Condition>
+		<ObligationExpressions>
+            <ObligationExpression ObligationId="com.att.research.nvp.test.obligation" FulfillOn="Permit">
+                <AttributeAssignmentExpression AttributeId="com.att.research.nvp.test.obligation.key" Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Action_Info</AttributeValue>
+                </AttributeAssignmentExpression>
+            </ObligationExpression>
+            <ObligationExpression ObligationId="com.att.research.nvp.test.multiobligation" FulfillOn="Permit">
+                <AttributeAssignmentExpression AttributeId="com.att.research.nvp.obligation.value" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Create_NEW_VM</AttributeValue>
+                </AttributeAssignmentExpression>
+            </ObligationExpression>
+        </ObligationExpressions>
+    </Rule>
+    <Rule RuleId="urn:com:xacml:rule:id:6dd4c4b2-8864-4bae-b497-7472b464ffe7" Effect="Permit">
+        <Description>Permit to create a new VM with Advice</Description>
+        <Target>
+			<AnyOf>
+				<AllOf>
+					<Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+						<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">create_adviceAction</AttributeValue>
+						<AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+					</Match>
+				</AllOf>
+			</AnyOf>
+		</Target>
+		<Condition>
+            <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+                <Description>If the Requirement has met create the VM</Description>
+                <VariableReference VariableId="doesItRequireNewVM"/>
+                <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue>
+            </Apply>
+        </Condition>
+		<AdviceExpressions>
+            <AdviceExpression AdviceId="com.att.research.nvp.test.advice.multi" AppliesTo="Permit">
+                <AttributeAssignmentExpression AttributeId="com.att.research.nvp.test.advice.key">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Action_Info</AttributeValue>
+                </AttributeAssignmentExpression>
+            </AdviceExpression>
+            <AdviceExpression AdviceId="com.att.research.nvp.test.advice.multiadvice" AppliesTo="Permit">
+				<AttributeAssignmentExpression AttributeId="com.att.research.nvp.test.advice.multival">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Created New VM</AttributeValue>
+                </AttributeAssignmentExpression>
+				<AttributeAssignmentExpression AttributeId="com.att.research.nvp.test.advice.val" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#anyURI">http://localhost:8080/pdp/?type=hb</AttributeValue>
+                </AttributeAssignmentExpression>
+            </AdviceExpression>
+        </AdviceExpressions>
+    </Rule>
+	<VariableDefinition VariableId="removeVM">
+        <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than">
+            <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+                <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:pip:csv:resource:cpu" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="true"/>
+            </Apply>
+            <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+                <AttributeDesignator Category="com:att:research:xacml:test:pip:csv:category:server" AttributeId="com:att:research:xacml:test:pip:csv:server:minval" DataType="http://www.w3.org/2001/XMLSchema#integer" Issuer="com:att:research:xacml:test:pip:csv" MustBePresent="false"/>
+            </Apply>
+        </Apply>
+    </VariableDefinition>
+    <Rule RuleId="urn:com:xacml:rule:id:262fc3fd-f3f3-4aaa-8b9c-504f89be5ba2" Effect="Permit">
+        <Description>Permit to remove a VM with Obligation</Description>
+        <Target>
+			<AnyOf>
+				<AllOf>
+					<Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+						<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">remove_Action</AttributeValue>
+						<AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+					</Match>
+				</AllOf>
+			</AnyOf>
+		</Target>
+		<Condition>
+            <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+                <Description>If the resource usage is low then remove the VM</Description>
+                <VariableReference VariableId="removeVM"/>
+                <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue>
+            </Apply>
+        </Condition>
+		<ObligationExpressions>
+            <ObligationExpression ObligationId="com.att.research.nvp.test.obligation" FulfillOn="Permit">
+                <AttributeAssignmentExpression AttributeId="com.att.research.nvp.test.obligation.key" Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Action_Info</AttributeValue>
+                </AttributeAssignmentExpression>
+            </ObligationExpression>
+            <ObligationExpression ObligationId="com.att.research.nvp.test.multiobligation" FulfillOn="Permit">
+                <AttributeAssignmentExpression AttributeId="com.att.research.nvp.obligation.value" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Remove_VM</AttributeValue>
+                </AttributeAssignmentExpression>
+            </ObligationExpression>
+        </ObligationExpressions>
+    </Rule>
+    <Rule RuleId="urn:com:xacml:rule:id:6b17c532-6b43-4577-b499-30c862bc7df3" Effect="Permit">
+        <Description>Permit to remove a VM with Advice</Description>
+        <Target>
+			<AnyOf>
+				<AllOf>
+					<Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+						<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">remove_adviceAction</AttributeValue>
+						<AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+					</Match>
+				</AllOf>
+			</AnyOf>
+		</Target>
+		<Condition>
+            <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+                <Description>If the resource usage is low then remove the VM</Description>
+                <VariableReference VariableId="removeVM"/>
+                <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue>
+            </Apply>
+        </Condition>
+		<AdviceExpressions>
+            <AdviceExpression AdviceId="com.att.research.nvp.test.advice.multi" AppliesTo="Permit">
+                <AttributeAssignmentExpression AttributeId="com.att.research.nvp.test.advice.key">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Action_Info</AttributeValue>
+                </AttributeAssignmentExpression>
+            </AdviceExpression>
+            <AdviceExpression AdviceId="com.att.research.nvp.test.advice.multiadvice" AppliesTo="Permit">
+				<AttributeAssignmentExpression AttributeId="com.att.research.nvp.test.advice.multival">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Removed VM</AttributeValue>
+                </AttributeAssignmentExpression>
+				<AttributeAssignmentExpression AttributeId="com.att.research.nvp.test.advice.val" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#anyURI">http://localhost:8080/pdp/?type=hb</AttributeValue>
+                </AttributeAssignmentExpression>
+            </AdviceExpression>
+        </AdviceExpressions>
+    </Rule>
+</Policy>
diff --git a/ONAP-XACML/src/test/resources/Config_SampleTest1206.1.xml b/ONAP-XACML/src/test/resources/Config_SampleTest1206.1.xml
new file mode 100644
index 0000000..dcfd0c5
--- /dev/null
+++ b/ONAP-XACML/src/test/resources/Config_SampleTest1206.1.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="urn:com:xacml:policy:id:0b67998b-57e2-4e25-9ea9-f9154bf18df1" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:permit-overrides">
+    <Description>SampleTest1206@CreatedBy:test@CreatedBy:@ModifiedBy:test@ModifiedBy:</Description>
+    <Target>
+        <AnyOf>
+            <AllOf>
+                <Match MatchId="org.onap.function.regex-match">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">com.Config_SampleTest1206.1.xml</AttributeValue>
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="PolicyName" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+                </Match>
+            </AllOf>
+            <AllOf>
+                <Match MatchId="org.onap.function.regex-match">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">success</AttributeValue>
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="ONAPName" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+                </Match>
+                <Match MatchId="org.onap.function.regex-match">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">PROD</AttributeValue>
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="RiskType" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+                </Match>
+                <Match MatchId="org.onap.function.regex-match">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">1</AttributeValue>
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="RiskLevel" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+                </Match>
+                <Match MatchId="org.onap.function.regex-match">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">True</AttributeValue>
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="guard" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+                </Match>
+                <Match MatchId="org.onap.function.regex-match">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">08-06-2017</AttributeValue>
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="TTLDate" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+                </Match>
+                <Match MatchId="org.onap.function.regex-match">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">SampleTest1206</AttributeValue>
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="ConfigName" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+                </Match>
+            </AllOf>
+        </AnyOf>
+    </Target>
+    <Rule RuleId="urn:com:xacml:rule:id:7e46d503-af54-4ea5-a86c-9eb6dd1f4f43" Effect="Permit">
+        <Target>
+            <AnyOf>
+                <AllOf>
+                    <Match MatchId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case">
+                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">ACCESS</AttributeValue>
+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+                    </Match>
+                    <Match MatchId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case">
+                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Config</AttributeValue>
+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+                    </Match>
+                </AllOf>
+            </AnyOf>
+        </Target>
+        <AdviceExpressions>
+            <AdviceExpression AdviceId="configID" AppliesTo="Permit">
+                <AttributeAssignmentExpression AttributeId="type" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" Issuer="">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Configuration</AttributeValue>
+                </AttributeAssignmentExpression>
+                <AttributeAssignmentExpression AttributeId="URLID" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" Issuer="">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#anyURI">$URL/Config/com.Config_SampleTest1206.1.txt</AttributeValue>
+                </AttributeAssignmentExpression>
+                <AttributeAssignmentExpression AttributeId="PolicyName" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" Issuer="">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">com.Config_SampleTest1206.1.xml</AttributeValue>
+                </AttributeAssignmentExpression>
+                <AttributeAssignmentExpression AttributeId="VersionNumber" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" Issuer="">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">1</AttributeValue>
+                </AttributeAssignmentExpression>
+                <AttributeAssignmentExpression AttributeId="matching:ONAPName" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" Issuer="">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">success</AttributeValue>
+                </AttributeAssignmentExpression>
+                <AttributeAssignmentExpression AttributeId="matching:ConfigName" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" Issuer="">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">SampleTest1206</AttributeValue>
+                </AttributeAssignmentExpression>
+                <AttributeAssignmentExpression AttributeId="RiskType" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" Issuer="">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">PROD</AttributeValue>
+                </AttributeAssignmentExpression>
+                <AttributeAssignmentExpression AttributeId="RiskLevel" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" Issuer="">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">1</AttributeValue>
+                </AttributeAssignmentExpression>
+                <AttributeAssignmentExpression AttributeId="guard" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" Issuer="">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">True</AttributeValue>
+                </AttributeAssignmentExpression>
+                <AttributeAssignmentExpression AttributeId="TTLDate" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" Issuer="">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">08-06-2017</AttributeValue>
+                </AttributeAssignmentExpression>
+            </AdviceExpression>
+        </AdviceExpressions>
+    </Rule>
+</Policy>
diff --git a/ONAP-XACML/src/test/resources/log4j.properties b/ONAP-XACML/src/test/resources/log4j.properties
new file mode 100644
index 0000000..ee9cfa3
--- /dev/null
+++ b/ONAP-XACML/src/test/resources/log4j.properties
@@ -0,0 +1,42 @@
+###
+# ============LICENSE_START=======================================================
+# ONAP-XACML
+# ================================================================================
+# 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=========================================================
+###
+
+#
+# Use this properties for debugging and development.
+#
+#
+# Set root logger level to DEBUG and its only appender to A1.
+log4j.rootLogger=INFO, MAIN_LOG
+
+# A1 is set to be a ConsoleAppender.
+log4j.appender.MAIN_LOG=org.apache.log4j.ConsoleAppender
+
+# A1 uses PatternLayout.
+log4j.appender.MAIN_LOG.layout=org.apache.log4j.PatternLayout
+log4j.appender.MAIN_LOG.layout.ConversionPattern=%d{yyyy_MM_dd_HH_mm_ss_SSS} [%t] %-5p %l- %m%n
+
+#
+# This is specifically for Xacml request/response logging
+#
+log4j.logger.xacml.request=INFO, REQUEST_LOG
+
+log4j.appender.REQUEST_LOG=org.apache.log4j.ConsoleAppender
+log4j.appender.REQUEST_LOG.layout=org.apache.log4j.PatternLayout
+log4j.appender.REQUEST_LOG.layout.ConversionPattern=%d{yyyy_MM_dd_HH_mm_ss_SSS} %m%n
diff --git a/ONAP-XACML/src/test/resources/logback.xml b/ONAP-XACML/src/test/resources/logback.xml
new file mode 100644
index 0000000..cd8e694
--- /dev/null
+++ b/ONAP-XACML/src/test/resources/logback.xml
@@ -0,0 +1,253 @@
+<!--
+  ============LICENSE_START=======================================================
+  ONAP-XACML
+  ================================================================================
+  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=========================================================
+  -->
+
+<configuration scan="true" scanPeriod="3 seconds" debug="true">
+  <!--<jmxConfigurator /> -->
+  <!-- directory path for all other type logs -->
+  <property name="logDir" value="logs" />
+  
+  <!-- directory path for debugging type logs -->
+  <property name="debugDir" value="logs" />
+  
+  <!--  specify the component name 
+    <ONAP-component-name>::= "MSO" | "DCAE" | "ASDC " | "AAI" |"Policy" | "SDNC" | "AC"  -->
+  <property name="componentName" value="Policy"></property>
+  <property name="subComponentName" value="XACML"></property>
+  
+  <!--  log file names -->
+  <property name="errorLogName" value="error" />
+  <property name="metricsLogName" value="metrics" />
+  <property name="auditLogName" value="audit" />
+  <property name="debugLogName" value="debug" />
+  
+  
+     <!-- modified time stamp format -->
+ 
+   <!--    A U D I T 
+           <property name="defaultAuditPattern" value="%X{BeginTimestamp}|%X{EndTimestamp}|%X{RequestId}|%X{ServiceInstanceId}|%thread|%X{ServerName}|%X{ServiceName}|%X{PartnerName}|%X{StatusCode}|%X{ResponseCode}|%X{ResponseDescription}|%X{InstanceUUID}|%.-5level|%X{AlertSeverity}|%X{ServerIPAddress}|%X{ElapsedTime}|%X{ServerFQDN}|%X{RemoteHost}|%X{ClassName}||%X{ProcessKey}|%X{TargetVirtualEntity}|%X{CustomField1}|%X{CustomField2}|%X{CustomField3}|%X{CustomField4}|%msg%n" />
+           <property name="defaultAuditPattern" value="%X{BeginTimestamp}|%X{EndTimestamp}|%X{requestId}|%X{serviceInstanceId}|%t|%X{serverName}|%X{serviceName}|%X{PartnerName}|%X{StatusCode}|%X{ResponseCode}|%X{ResponseDescription}|%X{instanceUuid}|%p|%X{severity}|%X{serverIpAddress}|%X{ElapsedTime}|%X{server}|%X{clientIpAddress}|%c||%X{ProcessKey}|%X{TargetVirtualEntity}|%X{CustomField1}|%X{CustomField2}|%X{CustomField3}|%X{CustomField4}|%msg%n" />
+   -->
+   <property name="defaultAuditPattern" value="%X{TransactionBeginTimestamp}|%X{TransactionEndTimestamp}|%X{requestId}|%X{serviceInstanceId}|%t|%X{serverName}|%X{serviceName}|%X{partnerName}|%X{statusCode}|%X{ResponseCode}|%X{ResponseDescription}|%X{instanceUuid}|%p|%X{severity}|%X{serverIpAddress}|%X{TransactionElapsedTime}|%X{server}|%X{clientIpAddress}|%c||%X{ProcessKey}|%X{CustomField1}|%X{CustomField2}|%X{CustomField3}|%X{CustomField4}|%msg%n" />
+  
+  
+  
+   <!--    M E T R I C 
+          <property name="defaultMetricPattern" value="%X{BeginTimestamp}|%X{EndTimestamp}|%X{RequestId}|%X{ServiceInstanceId}|%thread|%X{ServerName}|%X{ServiceName}|%X{PartnerName}|%X{TargetEntity}|%X{TargetServiceName}|%X{StatusCode}|%X{ResponseCode}|%X{ResponseDescription}|%X{InstanceUUID}|%.-5level|%X{AlertSeverity}|%X{ServerIPAddress}|%X{ElapsedTime}|%X{ServerFQDN}|%X{RemoteHost}|%X{ClassName}||%X{ProcessKey}|%X{TargetVirtualEntity}|%X{CustomField1}|%X{CustomField2}|%X{CustomField3}|%X{CustomField4}|%msg%n" />
+   -->
+   <property name="defaultMetricPattern" value="%X{MetricBeginTimestamp}|%X{MetricEndTimestamp}|%X{requestId}|%X{serviceInstanceId}|%t|%X{serverName}|%X{serviceName}|%X{partnerName}|%X{targetEntity}|%X{targetServiceName}|%X{statusCode}|%X{ResponseCode}|%X{ResponseDescription}|%X{InstanceUUID}|%p|%X{severity}|%X{serverIpAddress}|%X{MetricElapsedTime}|%X{server}|%X{clientIpAddress}|%c||%X{ProcessKey}|%X{TargetVirtualEntity}|%X{CustomField1}|%X{CustomField2}|%X{CustomField3}|%X{CustomField4}|%msg%n" />
+  
+  
+     
+   
+   <!--   E R R O R
+          <property name="defaultErrorPattern" value="%d{yyyy-MM-dd'T'HH:mm:ss.SSS+00:00, UTC}|%X{RequestId}|%thread|%X{ServiceName}|%X{PartnerName}|%X{TargetEntity}|%X{TargetServiceName}|%X{ErrorCategory}|%X{ErrorCode}|%X{ErrorDesciption}|%msg%n" />
+   -->
+   <property name="defaultErrorPattern" value="%d{yyyy-MM-dd'T'HH:mm:ss.SSS+00:00, UTC}|%X{requestId}|%t|%X{serviceName}|%X{PartnerName}|%X{TargetEntity}|%X{TargetServiceName}|%X{ErrorCategory}|%X{ErrorCode}|%X{ErrorDesciption}|%msg%n" />
+  
+  
+  
+   <!--   D E B U G
+          <property name="debugLoggerPatternOld" value="%d{MM/dd-HH:mm:ss.SSS}|%X{RequestId}|%X{ServiceInstanceId}|%thread|%X{ServiceName}|%X{InstanceUUID}|%.-5level|%X{AlertSeverity}|%X{ServerIPAddress}|%X{ServerFQDN}|%X{RemoteHost}|%X{Timer}|[%caller{3}]|%msg%n" />
+          <property name="debugLoggerPattern" value="%X{BeginTimestamp}|%X{EndTimestamp}|%X{RequestId}|%X{ServiceInstanceId}|%thread|%X{ServerName}|%X{ServiceName}|%X{PartnerName}|%X{StatusCode}|%X{ResponseCode}|%X{ResponseDescription}|%X{ServiceName}|%X{InstanceUUID}|%.-5level|%X{AlertSeverity}|%X{ServerIPAddress}|%X{ElapsedTime}|%X{ServerFQDN}|%X{RemoteHost}|%X{ClassName}||%X{ProcessKey}|%X{CustomField1}|%X{CustomField2}|%X{CustomField3}|%X{CustomField4}|%msg%n" /> -->
+   -->
+   <property name="debugLoggerPattern" value="%d{yyyy-MM-dd'T'HH:mm:ss.SSS+00:00, UTC}|%X{RequestId}|%msg%n" />  
+   
+ 
+   
+   <!--   D E F A U L T 
+          <property name="defaultPatternOld" value="%d{MM/dd-HH:mm:ss.SSS}|%logger|%X{RequestId}|%X{ServiceInstanceId}|%thread|%X{ServiceName}|%X{InstanceUUID}|%.-5level|%X{AlertSeverity}|%X{ServerIPAddress}|%X{ServerFQDN}|%X{RemoteHost}|%X{ClassName}|%X{Timer}|%msg%n" />
+          <property name="defaultPattern" value="%X{BeginTimestamp}|%X{EndTimestamp}|%X{RequestId}|%X{ServiceInstanceId}|%thread|%X{ServerName}|%X{ServiceName}|%X{PartnerName}|%X{TargetEntity}|%X{TargetServiceName}|%X{StatusCode}|%X{ResponseCode}|%X{ResponseDescription}|%X{InstanceUUID}|%.-5level|%X{AlertSeverity}|%X{ServerIPAddress}|%X{ElapsedTime}|%X{ServerFQDN}|%X{RemoteHost}|%X{ClassName}||%X{ProcessKey}|%X{TargetVirtualEntity}|%X{CustomField1}|%X{CustomField2}|%X{CustomField3}|%X{CustomField4}|%msg%n" />
+   -->
+   <property name="defaultPattern" value="%d{&quot;yyyy-MM-dd'T'HH:mm:ss.SSSXXX&quot;, UTC}|%X{requestId}|%X{serviceInstanceId}|%t|%X{serverName}|%X{serviceName}|%X{instanceUuid}|%p|%X{severity}|%X{serverIpAddress}|%X{server}|%X{clientIpAddress}|%c||%msg%n" />
+   
+ 
+ 
+   <!--   P A T H
+          <property name="logDirectory" value="${catalina.base}/${logDir}/${componentName}/${subComponentName}" />
+          <property name="debugLogDirectory" value="${catalina.base}/${debugDir}/${componentName}/${subComponentName}" />   
+   -->   
+   <property name="logDirectory" value="${logDir}/${componentName}/${subComponentName}" />
+   <property name="debugLogDirectory" value="${debugDir}/${componentName}/${subComponentName}" />
+   
+
+ 
+ 
+  <!-- Example evaluator filter applied against console appender -->
+  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+    <encoder>
+      <pattern>${defaultPattern}</pattern>
+    </encoder>
+  </appender>
+
+  <!-- ============================================================================ -->
+  <!-- EELF Appenders -->
+  <!-- ============================================================================ -->
+
+  <!-- The EELFAppender is used to record events to the general application 
+    log -->
+        
+  <!-- EELF Audit Appender. This appender is used to record audit engine 
+    related logging events. The audit logger and appender are specializations 
+    of the EELF application root logger and appender. This can be used to segregate 
+    Policy engine events from other components, or it can be eliminated to record 
+    these events as part of the application root log. -->
+    
+  <appender name="EELFAudit"
+    class="ch.qos.logback.core.rolling.RollingFileAppender">
+    <file>${logDirectory}/${auditLogName}.log</file>
+    <rollingPolicy
+      class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+      <fileNamePattern>${logDirectory}/${auditLogName}.%i.log.zip
+      </fileNamePattern>
+      <minIndex>1</minIndex>
+      <maxIndex>9</maxIndex>
+    </rollingPolicy>
+    <triggeringPolicy
+      class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+      <maxFileSize>5MB</maxFileSize>
+    </triggeringPolicy>
+    <encoder>
+         <pattern>${defaultAuditPattern}</pattern>
+    </encoder>
+  </appender>
+
+  <appender name="asyncEELFAudit" class="ch.qos.logback.classic.AsyncAppender">
+    <queueSize>256</queueSize>
+    <appender-ref ref="EELFAudit" />
+  </appender>
+
+
+
+
+<appender name="EELFMetrics"
+    class="ch.qos.logback.core.rolling.RollingFileAppender">
+    <file>${logDirectory}/${metricsLogName}.log</file>
+    <rollingPolicy
+      class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+      <fileNamePattern>${logDirectory}/${metricsLogName}.%i.log.zip
+      </fileNamePattern>
+      <minIndex>1</minIndex>
+      <maxIndex>9</maxIndex>
+    </rollingPolicy>
+    <triggeringPolicy
+      class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+      <maxFileSize>5MB</maxFileSize>
+    </triggeringPolicy>
+    <encoder>
+      <!-- <pattern>"%d{HH:mm:ss.SSS} [%thread] %-5level %logger{1024} - 
+        %msg%n"</pattern> -->
+      <pattern>${defaultMetricPattern}</pattern>
+    </encoder>
+  </appender>
+  
+  <appender name="asyncEELFMetrics" class="ch.qos.logback.classic.AsyncAppender">
+    <queueSize>256</queueSize>
+    <appender-ref ref="EELFMetrics"/>
+  </appender>
+
+
+
+   
+  <appender name="EELFError"
+    class="ch.qos.logback.core.rolling.RollingFileAppender">
+    <file>${logDirectory}/${errorLogName}.log</file>
+    <rollingPolicy
+      class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+      <fileNamePattern>${logDirectory}/${errorLogName}.%i.log.zip
+      </fileNamePattern>
+      <minIndex>1</minIndex>
+      <maxIndex>9</maxIndex>
+    </rollingPolicy>
+    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+     <level>ERROR</level>
+     </filter>
+    <triggeringPolicy
+      class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+      <maxFileSize>5MB</maxFileSize>
+    </triggeringPolicy>
+    <encoder>
+      <pattern>${defaultErrorPattern}</pattern>
+    </encoder>
+  </appender>
+  
+  <appender name="asyncEELFError" class="ch.qos.logback.classic.AsyncAppender">
+    <queueSize>256</queueSize>
+    <appender-ref ref="EELFError"/>
+  </appender>
+
+
+  
+  <appender name="EELFDebug"
+    class="ch.qos.logback.core.rolling.RollingFileAppender">
+    <file>${debugLogDirectory}/${debugLogName}.log</file>
+    <rollingPolicy
+      class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+      <fileNamePattern>${debugLogDirectory}/${debugLogName}.%i.log.zip
+      </fileNamePattern>
+      <minIndex>1</minIndex>
+      <maxIndex>9</maxIndex>
+    </rollingPolicy>
+    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+     <level>INFO</level>
+     </filter>
+    <triggeringPolicy
+      class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+      <maxFileSize>5MB</maxFileSize>
+    </triggeringPolicy>
+    <encoder>
+      <pattern>${debugLoggerPattern}</pattern>
+    </encoder>
+  </appender>
+  
+  <appender name="asyncEELFDebug" class="ch.qos.logback.classic.AsyncAppender">
+    <queueSize>256</queueSize>
+    <appender-ref ref="EELFDebug" />
+    <includeCallerData>true</includeCallerData>
+  </appender>
+ 
+  
+  <!-- ============================================================================ -->
+  <!--  EELF loggers -->
+  <!-- ============================================================================ -->
+ 
+  <logger name="com.att.eelf.audit" level="info" additivity="false">
+    <appender-ref ref="asyncEELFAudit" />
+  </logger>
+  
+  <logger name="com.att.eelf.metrics" level="info" additivity="false">
+        <appender-ref ref="asyncEELFMetrics" />
+  </logger>
+ 
+    <logger name="com.att.eelf.error" level="error" additivity="false">
+  <appender-ref ref="asyncEELFError" />
+  </logger>
+  
+   <logger name="com.att.eelf.debug" level="info" additivity="false">
+        <appender-ref ref="asyncEELFDebug" />
+  </logger>
+  
+  
+  
+  <root level="INFO">
+        <appender-ref ref="asyncEELFDebug" />
+        <appender-ref ref="asyncEELFError" />
+  </root>
+
+</configuration>
diff --git a/ONAP-XACML/src/test/resources/logging.properties b/ONAP-XACML/src/test/resources/logging.properties
new file mode 100644
index 0000000..ff9840f
--- /dev/null
+++ b/ONAP-XACML/src/test/resources/logging.properties
@@ -0,0 +1,32 @@
+###
+# ============LICENSE_START=======================================================
+# ONAP-XACML
+# ================================================================================
+# 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=========================================================
+###
+
+handlers = java.util.logging.ConsoleHandler, java.util.logging.FileHandler
+
+.level = FINE
+
+java.util.logging.SimpleFormatter.format=%4$s: %5$s %n
+
+java.util.logging.ConsoleHandler.level = FINEST
+java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
+
+java.util.logging.FileHandler.level = SEVERE
+java.util.logging.FileHandler.pattern=%h/xacml_log%u.log
+java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
diff --git a/ONAP-XACML/src/test/resources/pdps/default/com.Config_BRMS_Param_BRMSParamvFWDemoPolicy.1.xml b/ONAP-XACML/src/test/resources/pdps/default/com.Config_BRMS_Param_BRMSParamvFWDemoPolicy.1.xml
new file mode 100644
index 0000000..e27f163
--- /dev/null
+++ b/ONAP-XACML/src/test/resources/pdps/default/com.Config_BRMS_Param_BRMSParamvFWDemoPolicy.1.xml
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="urn:com:xacml:policy:id:0f246245-4e4e-4fb4-87f2-c95ebc0b6c30" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:permit-overrides">
+    <Description>vFW Demo Policy@CreatedBy:@CreatedBy:@ModifiedBy:@ModifiedBy:</Description>
+    <Target>
+        <AnyOf>
+            <AllOf>
+                <Match MatchId="org.onap.function.regex-match">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">com.Config_BRMS_Param_BRMSParamvFWDemoPolicy.1.xml</AttributeValue>
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="PolicyName" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+                </Match>
+            </AllOf>
+            <AllOf>
+                <Match MatchId="org.onap.function.regex-match">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">DROOLS</AttributeValue>
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="ONAPName" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+                </Match>
+                <Match MatchId="org.onap.function.regex-match">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">BRMS_PARAM_RULE</AttributeValue>
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="ConfigName" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+                </Match>
+                <Match MatchId="org.onap.function.regex-match">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">SampleRiskType</AttributeValue>
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="RiskType" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+                </Match>
+                <Match MatchId="org.onap.function.regex-match">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">1</AttributeValue>
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="RiskLevel" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+                </Match>
+                <Match MatchId="org.onap.function.regex-match">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">False</AttributeValue>
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="guard" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+                </Match>
+                <Match MatchId="org.onap.function.regex-match">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">NA</AttributeValue>
+                    <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="TTLDate" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+                </Match>
+            </AllOf>
+        </AnyOf>
+    </Target>
+    <Rule RuleId="urn:com:xacml:rule:id:d4281b8e-698f-4860-b96f-aa85f70710a6" Effect="Permit">
+        <Target>
+            <AnyOf>
+                <AllOf>
+                    <Match MatchId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case">
+                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">ACCESS</AttributeValue>
+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+                    </Match>
+                    <Match MatchId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case">
+                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Config</AttributeValue>
+                        <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+                    </Match>
+                </AllOf>
+            </AnyOf>
+        </Target>
+        <AdviceExpressions>
+            <AdviceExpression AdviceId="BRMSPARAMID" AppliesTo="Permit">
+                <AttributeAssignmentExpression AttributeId="type" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" Issuer="">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Configuration</AttributeValue>
+                </AttributeAssignmentExpression>
+                <AttributeAssignmentExpression AttributeId="URLID" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" Issuer="">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#anyURI">$URL/Config/com.Config_BRMS_Param_BRMSParamvFWDemoPolicy.1.txt</AttributeValue>
+                </AttributeAssignmentExpression>
+                <AttributeAssignmentExpression AttributeId="PolicyName" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" Issuer="">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">com.Config_BRMS_Param_BRMSParamvFWDemoPolicy.1.xml</AttributeValue>
+                </AttributeAssignmentExpression>
+                <AttributeAssignmentExpression AttributeId="VersionNumber" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" Issuer="">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">1</AttributeValue>
+                </AttributeAssignmentExpression>
+                <AttributeAssignmentExpression AttributeId="matching:ONAPName" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" Issuer="">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">DROOLS</AttributeValue>
+                </AttributeAssignmentExpression>
+                <AttributeAssignmentExpression AttributeId="matching:ConfigName" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" Issuer="">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">BRMS_PARAM_RULE</AttributeValue>
+                </AttributeAssignmentExpression>
+                <AttributeAssignmentExpression AttributeId="key:controller" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" Issuer="">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">vFW</AttributeValue>
+                </AttributeAssignmentExpression>
+                <AttributeAssignmentExpression AttributeId="RiskType" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" Issuer="">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">SampleRiskType</AttributeValue>
+                </AttributeAssignmentExpression>
+                <AttributeAssignmentExpression AttributeId="RiskLevel" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" Issuer="">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">1</AttributeValue>
+                </AttributeAssignmentExpression>
+                <AttributeAssignmentExpression AttributeId="guard" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" Issuer="">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">False</AttributeValue>
+                </AttributeAssignmentExpression>
+                <AttributeAssignmentExpression AttributeId="TTLDate" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" Issuer="">
+                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">NA</AttributeValue>
+                </AttributeAssignmentExpression>
+            </AdviceExpression>
+        </AdviceExpressions>
+    </Rule>
+</Policy>
\ No newline at end of file
diff --git a/ONAP-XACML/src/test/resources/pdps/default/xacml.pip.properties b/ONAP-XACML/src/test/resources/pdps/default/xacml.pip.properties
new file mode 100644
index 0000000..846848f
--- /dev/null
+++ b/ONAP-XACML/src/test/resources/pdps/default/xacml.pip.properties
@@ -0,0 +1,6 @@
+#
+#Tue Feb 07 10:35:08 EST 2017
+AAF.description=AAFEngine to communicate with AAF to take decisions
+AAF.classname=org.onap.policy.xacml.std.pip.engines.aaf.AAFEngine
+AAF.name=AAFEngine
+xacml.pip.engines=AAF
\ No newline at end of file
diff --git a/ONAP-XACML/src/test/resources/pdps/default/xacml.policy.properties b/ONAP-XACML/src/test/resources/pdps/default/xacml.policy.properties
new file mode 100644
index 0000000..1dc2aab
--- /dev/null
+++ b/ONAP-XACML/src/test/resources/pdps/default/xacml.policy.properties
@@ -0,0 +1,5 @@
+#
+#Tue Feb 07 10:35:08 EST 2017
+com.Config_BRMS_Param_BRMSParamvFWDemoPolicy.1.xml.name=Config_BRMS_Param_BRMSParamvFWDemoPolicy
+xacml.referencedPolicies=
+xacml.rootPolicies=com.Config_BRMS_Param_BRMSParamvFWDemoPolicy.1.xml
\ No newline at end of file
diff --git a/ONAP-XACML/src/test/resources/pdps/xacml.properties b/ONAP-XACML/src/test/resources/pdps/xacml.properties
new file mode 100644
index 0000000..aa1ece0
--- /dev/null
+++ b/ONAP-XACML/src/test/resources/pdps/xacml.properties
@@ -0,0 +1,7 @@
+#
+#Tue Feb 07 10:37:51 EST 2017
+default.description=The default group where new PDP's are put.
+default.name=default
+default.pdps=
+xacml.pap.groups=default
+xacml.pap.groups.default=default
\ No newline at end of file
diff --git a/ONAP-XACML/src/test/resources/xacml.pip.properties b/ONAP-XACML/src/test/resources/xacml.pip.properties
new file mode 100644
index 0000000..ac17477
--- /dev/null
+++ b/ONAP-XACML/src/test/resources/xacml.pip.properties
@@ -0,0 +1,23 @@
+###
+# ============LICENSE_START=======================================================
+# ONAP-XACML
+# ================================================================================
+# 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=========================================================
+###
+
+#
+#Fri Mar 06 12:06:30 EST 2015
+xacml.pip.engines=
diff --git a/ONAP-XACML/src/test/resources/xacml.policy.properties b/ONAP-XACML/src/test/resources/xacml.policy.properties
new file mode 100644
index 0000000..8538b23
--- /dev/null
+++ b/ONAP-XACML/src/test/resources/xacml.policy.properties
@@ -0,0 +1,25 @@
+###
+# ============LICENSE_START=======================================================
+# ONAP-XACML
+# ================================================================================
+# 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=========================================================
+###
+
+#
+#Fri Mar 06 12:06:30 EST 2015
+xacml.referencedPolicies=
+xacml.rootPolicies=
+