Merge "AAF integration in Policy SDK"
diff --git a/ONAP-SDK-APP/pom.xml b/ONAP-SDK-APP/pom.xml
index f08b76d..9e845b9 100644
--- a/ONAP-SDK-APP/pom.xml
+++ b/ONAP-SDK-APP/pom.xml
@@ -30,7 +30,7 @@
     <packaging>war</packaging>
     <properties>
         <encoding>UTF-8</encoding>
-        <epsdk.version>2.3.1</epsdk.version>
+        <epsdk.version>2.4.0</epsdk.version>
         <springframework.version>4.2.0.RELEASE</springframework.version>
         <hibernate.version>4.3.11.Final</hibernate.version>
         <!-- Skip assembling the zip; assemble via mvn -Dskipassembly=false .. -->
diff --git a/ONAP-SDK-APP/src/main/resources/portal.properties b/ONAP-SDK-APP/src/main/resources/portal.properties
index 04d39c1..fd65b3e 100644
--- a/ONAP-SDK-APP/src/main/resources/portal.properties
+++ b/ONAP-SDK-APP/src/main/resources/portal.properties
@@ -2,7 +2,7 @@
 # ================================================================================
 # onap Portal SDK
 # ================================================================================
-# Copyright (C) 2017 AT&T Intellectual Property
+# Copyright (C) 2017-2018 AT&T Intellectual Property
 # ================================================================================
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -50,3 +50,11 @@
 # If key ueb_listeners_enable is set to false,
 # then only the ueb_app_key is required.
 ueb_app_key = REPLACE-ME-UEB-APP-KEY-EPSDK-APP-OS
+
+#INFO: Once the Roles onboarded by Portal to AAF, we need to enable this property.
+# Use this tag if the app is centralized
+#role_access_centralized = remote
+
+# Connection and Read timeout values
+ext_req_connection_timeout = 15000
+ext_req_read_timeout = 20000
\ No newline at end of file
diff --git a/POLICY-SDK-APP/pom.xml b/POLICY-SDK-APP/pom.xml
index 5964a64..d14cf10 100644
--- a/POLICY-SDK-APP/pom.xml
+++ b/POLICY-SDK-APP/pom.xml
@@ -67,7 +67,7 @@
     </build>
     <properties>
         <encoding>UTF-8</encoding>
-        <epsdk.version>2.3.1</epsdk.version>
+        <epsdk.version>2.4.0</epsdk.version>
         <springframework.version>4.2.0.RELEASE</springframework.version>
         <hibernate.version>4.3.11.Final</hibernate.version>
         <logback.version>1.2.3</logback.version>
diff --git a/POLICY-SDK-APP/src/main/java/org/onap/policy/components/HumanPolicyComponent.java b/POLICY-SDK-APP/src/main/java/org/onap/policy/components/HumanPolicyComponent.java
index 23392bd..ea0dce2 100644
--- a/POLICY-SDK-APP/src/main/java/org/onap/policy/components/HumanPolicyComponent.java
+++ b/POLICY-SDK-APP/src/main/java/org/onap/policy/components/HumanPolicyComponent.java
@@ -2,7 +2,7 @@
  * ============LICENSE_START=======================================================
  * ONAP Policy Engine
  * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2017-2018 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.
@@ -20,6 +20,12 @@
 
 package org.onap.policy.components;
 
+import com.att.research.xacml.api.AttributeValue;
+import com.att.research.xacml.std.IdentifierImpl;
+import com.att.research.xacml.std.StdAttribute;
+import com.att.research.xacml.std.StdAttributeValue;
+import com.att.research.xacml.util.XACMLPolicyScanner.CallbackResult;
+import com.att.research.xacml.util.XACMLPolicyScanner.SimpleCallback;
 
 import java.io.File;
 import java.io.FileInputStream;
@@ -32,25 +38,7 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-
 import javax.xml.bind.JAXBElement;
-
-import org.apache.commons.io.FilenameUtils;
-import org.json.JSONObject;
-import org.onap.policy.common.logging.flexlogger.FlexLogger;
-import org.onap.policy.common.logging.flexlogger.Logger;
-import org.onap.policy.controller.PolicyController;
-import org.onap.policy.rest.jpa.FunctionDefinition;
-import org.onap.policy.xacml.api.XACMLErrorConstants;
-import org.onap.policy.xacml.util.XACMLPolicyScanner;
-
-import com.att.research.xacml.api.AttributeValue;
-import com.att.research.xacml.std.IdentifierImpl;
-import com.att.research.xacml.std.StdAttribute;
-import com.att.research.xacml.std.StdAttributeValue;
-import com.att.research.xacml.util.XACMLPolicyScanner.CallbackResult;
-import com.att.research.xacml.util.XACMLPolicyScanner.SimpleCallback;
-
 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;
@@ -68,888 +56,892 @@
 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.VariableReferenceType;
+import org.apache.commons.io.FilenameUtils;
+import org.json.JSONObject;
+import org.onap.policy.common.logging.flexlogger.FlexLogger;
+import org.onap.policy.common.logging.flexlogger.Logger;
+import org.onap.policy.controller.PolicyController;
+import org.onap.policy.rest.jpa.FunctionDefinition;
+import org.onap.policy.xacml.api.XACMLErrorConstants;
+import org.onap.policy.xacml.util.XACMLPolicyScanner;
 
 
 
-public class HumanPolicyComponent{
-	
-	private static final Logger LOGGER = FlexLogger.getLogger(HumanPolicyComponent.class);
-	
-	// Constants Used in XML Creation
-		public static final String CATEGORY_RECIPIENT_SUBJECT = "urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject";
-		public static final String CATEGORY_RESOURCE = "urn:oasis:names:tc:xacml:3.0:attribute-category:resource";
-		public static final String CATEGORY_ACTION = "urn:oasis:names:tc:xacml:3.0:attribute-category:action";
-		public static final String CATEGORY_ACCESS_SUBJECT = "urn:oasis:names:tc:xacml:1.0:subject-category:access-subject";
-		public static final String ACTION_ID = "urn:oasis:names:tc:xacml:1.0:action:action-id";
-		public static final String SUBJECT_ID = "urn:oasis:names:tc:xacml:1.0:subject:subject-id";
-		public static final String RESOURCE_ID = "urn:oasis:names:tc:xacml:1.0:resource:resource-id";
-		public static final String FUNTION_INTEGER_ONE_AND_ONLY = "urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only";
-		public static final String FUNCTION_STRING_ONE_AND_ONLY = "urn:oasis:names:tc:xacml:1.0:function:string-one-and-only";
-		public static final String FUNCTION_STRING_EQUAL = "urn:oasis:names:tc:xacml:1.0:function:string-equal";
-		public static final String FUNCTION_STRING_REGEX_MATCH = "org.onap.function.regex-match";
-		public static final String FUNCTION_STRING_EQUAL_IGNORE = "urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case";
-		public static final String INTEGER_DATATYPE = "http://www.w3.org/2001/XMLSchema#integer";
-		public static final String BOOLEAN_DATATYPE = "http://www.w3.org/2001/XMLSchema#boolean";
-		public static final String STRING_DATATYPE = "http://www.w3.org/2001/XMLSchema#string";
-		public static final String URI_DATATYPE = "http://www.w3.org/2001/XMLSchema#anyURI";
-		public static final String RULE_VARIABLE = "var:";
-		public static final String EMPTY_STRING = "";
+public class HumanPolicyComponent {
 
-	private static HtmlProcessor htmlProcessor;
-	
-	private static File policyFile;
-	
-	private HumanPolicyComponent(){
-		//Default Constructor
-	}
-	
-	public static JSONObject DescribePolicy(final File policyFile) {
-		if (LOGGER.isTraceEnabled()) 
-			LOGGER.trace("ENTER");
-		
-		HumanPolicyComponent.policyFile = policyFile;	
-		return humanPolicyLayout();		
+    private static final Logger LOGGER = FlexLogger.getLogger(HumanPolicyComponent.class);
 
-	}
-	
-	private static JSONObject humanPolicyLayout() {
-		if (LOGGER.isTraceEnabled())
-			LOGGER.trace("ENTER");
-		
-		try {
-			String html = processPolicy();
-			JSONObject result = new JSONObject();
-			result.put("html", html);
-			return result;
-			
-		} catch (IllegalArgumentException e) {
-			LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "cannot build html area por policy", e);
-		}
-		return null;
-	}
-	
-	private static String processPolicy() {	
-		if (LOGGER.isTraceEnabled()) {
-			LOGGER.trace("ENTER");
-		}
-		try (FileInputStream pIS = new FileInputStream(policyFile)){
-			Object policy = XACMLPolicyScanner.readPolicy(pIS);
-			if (policy == null)
-				throw new IllegalArgumentException("Policy File " +  policyFile.getName() + 
-						                           " cannot be unmarshalled");
-			
-			HumanPolicyComponent.htmlProcessor =  
-					new HtmlProcessor(HumanPolicyComponent.policyFile, policy);
-			
-			Path policyPath = Paths.get(policyFile.getAbsolutePath());
-			XACMLPolicyScanner xacmlScanner = new XACMLPolicyScanner(policyPath, htmlProcessor);
-			xacmlScanner.scan();
-			String html = htmlProcessor.html();
-			if (LOGGER.isDebugEnabled())
-				LOGGER.debug(policyPath + System.lineSeparator() + html);
-			
-			return html;
-			
-		} catch (Exception e) {	
-			String msg = "Exception reading policy: " + policyFile.getAbsolutePath() + 
-					     ": " + e.getMessage();
-			LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + msg, e);	
-			throw new IllegalArgumentException(msg);
-		}
-	}
-	
+    // Constants Used in XML Creation
+    public static final String CATEGORY_RECIPIENT_SUBJECT =
+            "urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject";
+    public static final String CATEGORY_RESOURCE = "urn:oasis:names:tc:xacml:3.0:attribute-category:resource";
+    public static final String CATEGORY_ACTION = "urn:oasis:names:tc:xacml:3.0:attribute-category:action";
+    public static final String CATEGORY_ACCESS_SUBJECT = "urn:oasis:names:tc:xacml:1.0:subject-category:access-subject";
+    public static final String ACTION_ID = "urn:oasis:names:tc:xacml:1.0:action:action-id";
+    public static final String SUBJECT_ID = "urn:oasis:names:tc:xacml:1.0:subject:subject-id";
+    public static final String RESOURCE_ID = "urn:oasis:names:tc:xacml:1.0:resource:resource-id";
+    public static final String FUNTION_INTEGER_ONE_AND_ONLY =
+            "urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only";
+    public static final String FUNCTION_STRING_ONE_AND_ONLY =
+            "urn:oasis:names:tc:xacml:1.0:function:string-one-and-only";
+    public static final String FUNCTION_STRING_EQUAL = "urn:oasis:names:tc:xacml:1.0:function:string-equal";
+    public static final String FUNCTION_STRING_REGEX_MATCH = "org.onap.function.regex-match";
+    public static final String FUNCTION_STRING_EQUAL_IGNORE =
+            "urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case";
+    public static final String INTEGER_DATATYPE = "http://www.w3.org/2001/XMLSchema#integer";
+    public static final String BOOLEAN_DATATYPE = "http://www.w3.org/2001/XMLSchema#boolean";
+    public static final String STRING_DATATYPE = "http://www.w3.org/2001/XMLSchema#string";
+    public static final String URI_DATATYPE = "http://www.w3.org/2001/XMLSchema#anyURI";
+    public static final String RULE_VARIABLE = "var:";
+    public static final String EMPTY_STRING = "";
+    private static final String ENTER = "ENTER";
+
+
+    private static HtmlProcessor htmlProcessor;
+
+    private static File policyFile;
+
+    private HumanPolicyComponent() {
+        // Default Constructor
+    }
+
+    public static JSONObject DescribePolicy(final File policyFile) {
+        if (LOGGER.isTraceEnabled())
+            LOGGER.trace(ENTER);
+
+        HumanPolicyComponent.policyFile = policyFile;
+        return humanPolicyLayout();
+
+    }
+
+    private static JSONObject humanPolicyLayout() {
+        if (LOGGER.isTraceEnabled())
+            LOGGER.trace(ENTER);
+
+        try {
+            String html = processPolicy();
+            JSONObject result = new JSONObject();
+            result.put("html", html);
+            return result;
+
+        } catch (IllegalArgumentException e) {
+            LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "cannot build html area por policy", e);
+        }
+        return null;
+    }
+
+    private static String processPolicy() {
+        if (LOGGER.isTraceEnabled()) {
+            LOGGER.trace(ENTER);
+        }
+        try (FileInputStream pIS = new FileInputStream(policyFile)) {
+            Object policy = XACMLPolicyScanner.readPolicy(pIS);
+            if (policy == null)
+                throw new IllegalArgumentException("Policy File " + policyFile.getName() + " cannot be unmarshalled");
+
+            HumanPolicyComponent.htmlProcessor = new HtmlProcessor(HumanPolicyComponent.policyFile, policy);
+
+            Path policyPath = Paths.get(policyFile.getAbsolutePath());
+            XACMLPolicyScanner xacmlScanner = new XACMLPolicyScanner(policyPath, htmlProcessor);
+            xacmlScanner.scan();
+            String html = htmlProcessor.html();
+            if (LOGGER.isDebugEnabled())
+                LOGGER.debug(policyPath + System.lineSeparator() + html);
+
+            return html;
+
+        } catch (Exception e) {
+            String msg = "Exception reading policy: " + policyFile.getAbsolutePath() + ": " + e.getMessage();
+            LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + msg, e);
+            throw new IllegalArgumentException(msg);
+        }
+    }
+
 }
 
+
 class HtmlProcessor extends SimpleCallback {
-	
-	private static final Logger LOGGER = FlexLogger.getLogger(HtmlProcessor.class);
-	
-	private static Map<String, String> function2human;
-	static {
-		function2human = new HashMap<>();
-		function2human.put(HumanPolicyComponent.FUNCTION_STRING_EQUAL, "equal");
-		function2human.put(HumanPolicyComponent.FUNCTION_STRING_EQUAL_IGNORE, "equal");
-		function2human.put(HumanPolicyComponent.FUNCTION_STRING_ONE_AND_ONLY, "one-and-only");
-		function2human.put(HumanPolicyComponent.FUNCTION_STRING_REGEX_MATCH, "matching regular expression");
-		function2human.put(HumanPolicyComponent.FUNTION_INTEGER_ONE_AND_ONLY, "one-and-only");
-	}
-	
-	private static Map<String, String> combiningAlgo2human;
-	static {
-		combiningAlgo2human = new HashMap<>();
-		combiningAlgo2human.put("deny-overrides", "to deny if any $placeholder$ below evaluates to <i>deny</i>");
-		combiningAlgo2human.put("permit-overrides", "to permit if any $placeholder$ below evaluates to <i>permit</i>");
 
-		combiningAlgo2human.put("ordered-deny-overrides", "to deny if any $placeholder$ below evaluates to <i>deny</i>");
-		combiningAlgo2human.put("ordered-permit-overrides", "to permit if any $placeholder$ below evaluates to <i>permit</i>");
-		combiningAlgo2human.put("deny-unless-permit", "to permit if any $placeholder$ below evaluates to <i>deny</i> and not <i>indeterminate</i>");
+    private static final Logger LOGGER = FlexLogger.getLogger(HtmlProcessor.class);
 
-		combiningAlgo2human.put("permit-unless-deny", "to deny if any $placeholder$ below evaluates to is <i>permit</i> and not <i>indeterminate</i>");
-		combiningAlgo2human.put("first-applicable", "to honour the result of the first successfully evaluated $placeholder$ in order");
-		combiningAlgo2human.put("only-one-applicable", "to honour the result of the first successfully evaluated $placeholder$ in order");
-	}	
-	
-	private Map<String, AttributeIdentifiers> attributeIdentifiersMap = new HashMap<>();
-	
-	private final StringWriter stringWriter = new StringWriter();
-	private final PrintWriter htmlOut = new PrintWriter(stringWriter);
-	private final String policyName;
-	private final Object rootPolicyObject;
-	
-	public HtmlProcessor(File policyFile, Object policyObject) {
-		if (LOGGER.isTraceEnabled())
-			LOGGER.trace("ENTER");
-		
-		if (policyFile == null) {
-			LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Null Policy File");
-			throw new IllegalArgumentException("Null Policy File");
-		}
-		
-		if (!policyFile.exists() || !policyFile.canRead()) {
-			String msg = "Can't access " + policyFile.getAbsolutePath();
-			LOGGER.error(XACMLErrorConstants.ERROR_PERMISSIONS + msg);
-			throw new IllegalArgumentException(msg);
-		}
-		
-		if (policyObject == null || 
-			(!(policyObject instanceof PolicySetType) && !(policyObject instanceof PolicyType))) {
-			String msg = "Invalid unmarshalled object: " + policyObject;
-			LOGGER.error(XACMLErrorConstants.ERROR_SCHEMA_INVALID + msg);
-			throw new IllegalArgumentException(msg);			
-		}
-		
-		this.policyName = FilenameUtils.removeExtension(policyFile.getName());
-		this.rootPolicyObject = policyObject;
-		
-		String version = "-";		
-		if (policyObject instanceof PolicyType) {
-			PolicyType policy = (PolicyType) policyObject;
-			version = policy.getVersion();
-			htmlOut.println("<h1>Policy:   " + policyName + 
-					        "  (version " + version + ") </h1>");
-			
-		} else {
-			PolicySetType policySet = (PolicySetType) policyObject;
-			version = policySet.getVersion();
-			htmlOut.println("<h1>Policy Set:   " + policyName + 
-					        "  (v" + version + ") </h1>");
-		}
-		
-		htmlOut.println("<h3><b>Location: </b>" + policyFile.getPath() + "</h3>");
-		htmlOut.println("<hr>");
-		
-		if (rootPolicyObject instanceof PolicySetType) {
-			if (policyName.startsWith("Config_")) {
-				htmlOut.println("<p>This is a <b>config</b> policy set.</p>");
-			} else if (policyName.startsWith("Action_")) {
-				htmlOut.println("<p>This is an <b>action</b> policy set.</p>");
-			}
-			htmlOut.println("<dl>");
-		} else {
-			if (policyName.startsWith("Config_")) {
-				htmlOut.println("<p>This is a <b>config</b> policy.</p>");
-			} else if (policyName.startsWith("Action_")) {
-				htmlOut.println("<p>This is an <b>action</b> policy.</p>");
-			}
-			htmlOut.println("<ol>");
-		}
-	}
-	
-	/**
-	 * @return the attributeIdentifiersMap
-	 */
-	public Map<String, AttributeIdentifiers> getAttributeIdentifiersMap() {
-		return attributeIdentifiersMap;
-	}
+    private static final String ENTER = "ENTER";
+    private static Map<String, String> function2human;
+    static {
+        function2human = new HashMap<>();
+        function2human.put(HumanPolicyComponent.FUNCTION_STRING_EQUAL, "equal");
+        function2human.put(HumanPolicyComponent.FUNCTION_STRING_EQUAL_IGNORE, "equal");
+        function2human.put(HumanPolicyComponent.FUNCTION_STRING_ONE_AND_ONLY, "one-and-only");
+        function2human.put(HumanPolicyComponent.FUNCTION_STRING_REGEX_MATCH, "matching regular expression");
+        function2human.put(HumanPolicyComponent.FUNTION_INTEGER_ONE_AND_ONLY, "one-and-only");
+    }
 
-	@Override
-	public void onFinishScan(Object root) {
-		if (LOGGER.isTraceEnabled())
-			LOGGER.trace("ENTER");
-		
-		if (rootPolicyObject instanceof PolicySetType) {
-			htmlOut.println("</dl>");
-		} else {
-			htmlOut.println("</ol>");
-		}
-		
-		htmlOut.println("<hr>");
-		
-		htmlOut.println("<h3>Attribute Table:</h3>");
-		
-		htmlOut.println("<table border=\"3\" style=\"width:100%\">");
-		htmlOut.println("<tr>");
-		htmlOut.print("<th>Category</th>");
-		htmlOut.print("<th>Type</th>");
-		htmlOut.print("<th>Identifier</th>");
-		htmlOut.println("</tr>");
-		for(Map.Entry<String, AttributeIdentifiers> entry : this.attributeIdentifiersMap.entrySet()){
-			AttributeIdentifiers value = entry.getValue();
-			htmlOut.println("<tr>");
-			htmlOut.print("<td><a name=\"" + entry.getKey() + "\"></a>" + value.category + "</td>");
-			htmlOut.print("<td>" + value.getType() + "</td>");
-			htmlOut.print("<td>" + value.id + "</td>");
-			htmlOut.println("</tr>");
-		}
-		htmlOut.println("</table>");
-		
-		htmlOut.println("<p></p>");
-		
-		// Not necessary for the user, uncomment if desired at some point
-		// writeRawXACML()
-		
-		super.onFinishScan(root);
-	}
-	
-	@Override
-	public CallbackResult onPreVisitPolicySet(PolicySetType parent, PolicySetType policySet) {
-		if (LOGGER.isTraceEnabled())
-			LOGGER.trace("PolicySet: " + policySet.getPolicySetId() + " Version: " + policySet.getVersion());
-				
-		if (parent != null  && LOGGER.isTraceEnabled())
-			LOGGER.trace("PolicySet: " + policySet.getPolicySetId() + 
-					     "Parent PolicySet: " + parent.getPolicySetId() + " Version: " + parent.getVersion());
-		
-		String description = policySet.getDescription();
-		if (description != null && LOGGER.isTraceEnabled())
-			LOGGER.trace("PolicySet: " + policySet.getPolicySetId() + 
-					     " Description: " + policySet.getDescription());
-		
-		if (parent == null) // root
-			policySet(policySet, "dl");
-		else
-			policySet(policySet, "li");
-		
-		if (!policySet.getPolicySetOrPolicyOrPolicySetIdReference().isEmpty())
-			htmlOut.println("<ol>");
+    private static Map<String, String> combiningAlgo2human;
+    static {
+        combiningAlgo2human = new HashMap<>();
+        combiningAlgo2human.put("deny-overrides", "to deny if any $placeholder$ below evaluates to <i>deny</i>");
+        combiningAlgo2human.put("permit-overrides", "to permit if any $placeholder$ below evaluates to <i>permit</i>");
 
-		return super.onPreVisitPolicySet(parent, policySet);
-	}
-	
-	@Override
-	public CallbackResult onPostVisitPolicySet(PolicySetType parent, PolicySetType policySet) {
-		if (LOGGER.isTraceEnabled())
-			LOGGER.trace("PolicySet: " + policySet.getPolicySetId() + " Version: " + policySet.getVersion());
-				
-		if (parent != null  && LOGGER.isTraceEnabled())
-			LOGGER.trace("PolicySet: " + policySet.getPolicySetId() + 
-					     "Parent PolicySet: " + parent.getPolicySetId() + " Version: " + parent.getVersion());
-		
-		String description = policySet.getDescription();
-		if (description != null && LOGGER.isTraceEnabled())
-			LOGGER.trace("PolicySet: " + policySet.getPolicySetId() + 
-					     " Description: " + policySet.getDescription());	
-		
-		if (!policySet.getPolicySetOrPolicyOrPolicySetIdReference().isEmpty())
-			htmlOut.println("</ol>");
-		
-		htmlOut.println("<p></p>");
-		
-		return super.onPostVisitPolicySet(parent, policySet);
-	}
-	
-	public void policySet(PolicySetType policySet, String htmlListElement) {
-		if (LOGGER.isTraceEnabled())
-			LOGGER.trace("PolicySet: " + policySet.getPolicySetId());
-		
-		String combiningAlgorithm = "-";
-		String id = "-";
-		String version = "-";
-		
+        combiningAlgo2human.put("ordered-deny-overrides",
+                "to deny if any $placeholder$ below evaluates to <i>deny</i>");
+        combiningAlgo2human.put("ordered-permit-overrides",
+                "to permit if any $placeholder$ below evaluates to <i>permit</i>");
+        combiningAlgo2human.put("deny-unless-permit",
+                "to permit if any $placeholder$ below evaluates to <i>deny</i> and not <i>indeterminate</i>");
 
-		if (policySet.getPolicyCombiningAlgId() != null)
-			combiningAlgorithm = extractLastIdentifier(policySet.getPolicyCombiningAlgId(), ":");
-		
-		if (policySet.getPolicySetId() != null)
-			id = extractLastIdentifier(policySet.getPolicySetId(), ":");
-		
-		if (policySet.getVersion() != null)
-			version = policySet.getVersion();
-			
-		
-		htmlOut.println("<" + htmlListElement + "><b>Policy Set ID</b>: <i>" + id + 
-					    "</i>  (v" + version + ") " + "</" + htmlListElement + ">");
-		
-		if (policySet.getTarget() == null || 
-			policySet.getTarget().getAnyOf() == null ||
-			policySet.getTarget().getAnyOf().isEmpty()) {
-				htmlOut.println("<p>This policy set applies to all requests.</p>");
-		} else {	
-			htmlOut.print("<p>");
-			htmlOut.print("This policy set applies to requests with attributes ");
-			
-			List<AnyOfType> anyOf_s = policySet.getTarget().getAnyOf();
-			target(anyOf_s);	
-			htmlOut.println(".</p>");
-		}
-		
-		if (policySet.getPolicySetOrPolicyOrPolicySetIdReference() != null &&
-			!policySet.getPolicySetOrPolicyOrPolicySetIdReference().isEmpty()) {
-			String algoDesc = combiningAlgo2human.get(combiningAlgorithm);
-			if (algoDesc != null) {
-				algoDesc = algoDesc.replace("$placeholder$", "policy") + " (" + "<i>" + combiningAlgorithm + "</i>)";
-			} else {
-				algoDesc = combiningAlgorithm;
-			}
-			
-			htmlOut.println("<p>The result is " + algoDesc + ": </p>");
-		}
-	}
-	
-	@Override
-	public CallbackResult onPreVisitPolicy(PolicySetType parent, PolicyType policy) {
-		if (LOGGER.isTraceEnabled())
-			LOGGER.trace("PolicySet: " + policy.getPolicyId() + " Version: " + policy.getVersion());
-				
-		if (parent != null  && LOGGER.isTraceEnabled())
-			LOGGER.trace("PolicySet: " + policy.getPolicyId() + 
-					     "Parent PolicySet: " + parent.getPolicySetId() + " Version: " + parent.getVersion());
-		
-		String description = policy.getDescription();
-		if (description != null && LOGGER.isTraceEnabled())
-			LOGGER.trace("PolicySet: " + policy.getPolicyId() + 
-					     " Description: " + policy.getDescription());
-		
-		policy(policy);
-		
-		if (!policy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().isEmpty())
-			htmlOut.println("<ol type=\"i\">");
-		
-		return super.onPreVisitPolicy(parent, policy);
-	}
-	
-	@Override
-	public CallbackResult onPostVisitPolicy(PolicySetType parent, PolicyType policy) {
-		if (LOGGER.isTraceEnabled())
-			LOGGER.trace("PolicySet: " + policy.getPolicyId() + " Version: " + policy.getVersion());
-				
-		if (parent != null  && LOGGER.isTraceEnabled())
-			LOGGER.trace("PolicySet: " + policy.getPolicyId() + 
-					     "Parent PolicySet: " + parent.getPolicySetId() + " Version: " + parent.getVersion());
-		
-		if (!policy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().isEmpty())
-			htmlOut.println("</ol>");
-		
-		htmlOut.println("<p></p>");
-		return super.onPostVisitPolicy(parent, policy);
-	}
-	
-	public void policy(PolicyType policy) {
-		if (LOGGER.isTraceEnabled())
-			LOGGER.trace("Policy: " + policy.getPolicyId());
-		
-		String combiningAlgorithm = "-";
-		String id = "-";
-		String version = "-";
-		
+        combiningAlgo2human.put("permit-unless-deny",
+                "to deny if any $placeholder$ below evaluates to is <i>permit</i> and not <i>indeterminate</i>");
+        combiningAlgo2human.put("first-applicable",
+                "to honour the result of the first successfully evaluated $placeholder$ in order");
+        combiningAlgo2human.put("only-one-applicable",
+                "to honour the result of the first successfully evaluated $placeholder$ in order");
+    }
 
-		if (policy.getRuleCombiningAlgId() != null)
-			combiningAlgorithm = extractLastIdentifier(policy.getRuleCombiningAlgId(), ":");
-		
-		if (policy.getPolicyId() != null)
-			id = extractLastIdentifier(policy.getPolicyId(), ":");
-		
-		if (policy.getVersion() != null)
-			version = policy.getVersion();
-		
-		htmlOut.println("<li><b>Policy ID</b>: <i>" + id + 
-			            "</i>  (v" + version + ") " + "</li>");
-		
-		if (policy.getTarget() == null || 
-			policy.getTarget().getAnyOf() == null ||
-			policy.getTarget().getAnyOf().isEmpty()) {
-			htmlOut.println("<p>This policy applies to all requests.</p>");
-		} else {	
-			htmlOut.print("<p>");
-			htmlOut.print("This policy applies to requests with attributes ");
-			
-			List<AnyOfType> anyOf_s = policy.getTarget().getAnyOf();
-			target(anyOf_s);	
-			htmlOut.println(".</p>");
-		}
-		
-		if (policy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition() != null &&
-			!policy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().isEmpty()) {
-			String algoDesc = combiningAlgo2human.get(combiningAlgorithm);
-			if (algoDesc != null) {
-				algoDesc = algoDesc.replace("$placeholder$", "rule") + " (<i>" + combiningAlgorithm + "</i>)";
-			} else {
-				algoDesc = combiningAlgorithm;
-			}
-			htmlOut.println("<p>The result is " + algoDesc + ": </p>");
-		}
-	}
-	
-	
-	@Override
-	public CallbackResult onPreVisitRule(PolicyType parent, RuleType rule) {
-		if (LOGGER.isTraceEnabled())
-			LOGGER.trace("Rule: " + rule.getRuleId());
-		
-		if (parent != null && LOGGER.isTraceEnabled())
-			LOGGER.trace("Parent Policy: " + parent.getPolicyId() + " Version: " + parent.getVersion());
-		
-		String description = rule.getDescription();
-		if (description != null && LOGGER.isTraceEnabled()) {
-			LOGGER.trace("Rule: " + rule.getRuleId() + 
-				         " Description: " + rule.getDescription());
-		}
-		
-		rule(rule);
-		
-		return super.onPreVisitRule(parent, rule);
-	}
-	
-	@Override
-	public CallbackResult onPostVisitRule(PolicyType parent, RuleType rule) {
-		if (LOGGER.isTraceEnabled())
-			LOGGER.trace("Rule: " + rule.getRuleId());
-		
-		if (parent != null && LOGGER.isTraceEnabled())
-			LOGGER.trace("Parent Policy: " + parent.getPolicyId() + " Version: " + parent.getVersion());
-		
-		return super.onPostVisitRule(parent, rule);
-	}
-	
-	public void rule(RuleType rule) {
-		if (LOGGER.isTraceEnabled())
-			LOGGER.trace("Rule: " + rule.getRuleId());
-		
-		String id = "-";
-		
-		if (rule.getRuleId() != null)
-			id = extractLastIdentifier(rule.getRuleId(), ":");
-		
-		htmlOut.println("<li><b>Rule ID</b>: <i>" + id + "</i></li>");
-		
-		htmlOut.println("<dl>");
-		
-		htmlOut.print("<p>");
-		htmlOut.print(rule.getEffect().value());
-		
-		if (rule.getTarget() == null || 
-				rule.getTarget().getAnyOf() == null ||
-				rule.getTarget().getAnyOf().isEmpty()) {
-				htmlOut.print(" for all requests");
-		} else {	
-			List<AnyOfType> anyOf_s = rule.getTarget().getAnyOf();
-			htmlOut.print(" for requests with attributes ");
-			target(anyOf_s);	
-		}
-		
-		if (rule.getCondition() != null) {
-			htmlOut.print(" when ");
-			htmlOut.println(this.stringifyCondition(rule.getCondition()) + " ");
-		} else {
-			htmlOut.print(" with no conditions ");
-		}
-		
-		if (rule.getAdviceExpressions() != null) {
-			advice(rule.getAdviceExpressions());
-			if (rule.getObligationExpressions() != null)
-				htmlOut.println(" and ");
-		}
-		
-		if (rule.getObligationExpressions() != null) {
-			obligation(rule.getObligationExpressions());
-		}
-		
-		htmlOut.println("</p>");
-	}
-	
-	private void advice(AdviceExpressionsType adviceExpressions) {
-		if (LOGGER.isTraceEnabled())
-			LOGGER.trace("ENTER");
-		
-		List<AdviceExpressionType> ae = adviceExpressions.getAdviceExpression();
-		for (AdviceExpressionType expression : ae) {
-			htmlOut.println(" with <b>advice</b> (<i>" + expression.getAdviceId() + "</i>) on <i>" +
-					        expression.getAppliesTo().value() + "</i>:" );
-			htmlOut.println("<ol type=\"a\">");
-			List<AttributeAssignmentExpressionType> assignments = expression.getAttributeAssignmentExpression();
-			if (assignments != null) {
-				processAttributeAssignments(assignments);
-			}
-			htmlOut.println("</ol>");
-		}
-	}
-	
-	private void obligation(ObligationExpressionsType obligationExpressions) {
-		if (LOGGER.isTraceEnabled())
-			LOGGER.trace("ENTER");
-		
-		List<ObligationExpressionType> oe = obligationExpressions.getObligationExpression();
-		for (ObligationExpressionType expression : oe) {
-			htmlOut.println(" with <b>obligations</b> (<i>" + expression.getObligationId() + "</i>) to be fullfilled on <i>" +
-					        expression.getFulfillOn().value() + "</i>:" );
-			htmlOut.println("<ol type=\"a\">");
-			List<AttributeAssignmentExpressionType> assignments = expression.getAttributeAssignmentExpression();
-			if (assignments != null) {
-				processAttributeAssignments(assignments);
-			}
-			htmlOut.println("</ol>");
-		}
-	}
+    private Map<String, AttributeIdentifiers> attributeIdentifiersMap = new HashMap<>();
 
-	/**
-	 * @param assignments
-	 */
-	private void processAttributeAssignments(List<AttributeAssignmentExpressionType> assignments) {
-		if (LOGGER.isTraceEnabled())
-			LOGGER.trace("ENTER");
-		
-		for (AttributeAssignmentExpressionType assignment : assignments) {
-			String succintIdentifier = extractLastIdentifier(assignment.getCategory(), ":") +
-                                       ":" + extractLastIdentifier(assignment.getAttributeId(), ":");
-			AttributeIdentifiers attributeIdentifiers = null;
-			if (!this.attributeIdentifiersMap.containsKey(succintIdentifier)) {
-				// Note Attribute Assignments do not have an Attribute Type, assume string
-				// but note this case is unlikely since attributeMap should have been populated
-				// during parsing of target and conditions, and not in this case for Advice and
-				// Obligations.
-				attributeIdentifiers = new AttributeIdentifiers(assignment.getCategory(),
-						                                           "NA",
-						                                           assignment.getAttributeId());			
-				this.attributeIdentifiersMap.put(succintIdentifier, attributeIdentifiers);
-			}
-			
-			htmlOut.print("<li><i><a href=\"#" + succintIdentifier + "\">" + succintIdentifier + "</a></i> is ");
-			// AttributeValueType
-			JAXBElement<?> jaxbExp = assignment.getExpression();
-			Object assignmentObject = jaxbExp.getValue();
-			if (assignmentObject instanceof AttributeValueType) {
-				AttributeValueType avt = (AttributeValueType) assignmentObject;
-				if (attributeIdentifiers != null) {
-					attributeIdentifiers.setType(avt.getDataType());
-				}
-				int numContent = avt.getContent().size();
-				int countContent = 0;
-				for (Object c: avt.getContent()) {
-					countContent++;
-					htmlOut.print("<i>" + c + "</i>");
-					if (countContent < numContent) 
-						htmlOut.print(" or ");
-				}
-				htmlOut.println("</li>");
-			} else if (assignmentObject instanceof AttributeDesignatorType) {
-				htmlOut.println("NA");
-			} else if (assignmentObject instanceof AttributeSelectorType) {
-				htmlOut.println("NA");
-			} else if (assignmentObject instanceof ApplyType) {
-				htmlOut.println("NA");
-			} else {		
-				htmlOut.println("Unexpected");
-			}
-		}
-	}
+    private final StringWriter stringWriter = new StringWriter();
+    private final PrintWriter htmlOut = new PrintWriter(stringWriter);
+    private final String policyName;
+    private final Object rootPolicyObject;
 
-	/**
-	 * 
-	 * @param anyOfList
-	 */
-	public void target(List<AnyOfType> anyOfList) {
-		if (LOGGER.isTraceEnabled())
-			LOGGER.trace("ENTER");
-		
-		if (anyOfList != null) {
-			Iterator<AnyOfType> iterAnyOf = anyOfList.iterator();
-			StringBuilder targetInHuman = new StringBuilder();
-			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();
-							if (matchList.size() > 1)
-								targetInHuman.append("(");
-							while (iterMatch.hasNext()) {
-								MatchType match = iterMatch.next();
-								//
-								// Finally down to the actual attribute
-								//
-								StdAttribute attribute = null;
-								AttributeValueType value = match.getAttributeValue();
-								String attributeDataType;
-								if (match.getAttributeDesignator() != null && value != null) {
-									AttributeDesignatorType designator = match.getAttributeDesignator();
-									attribute = new StdAttribute(new IdentifierImpl(designator.getCategory()),
-																			new IdentifierImpl(designator.getAttributeId()),
-																			new StdAttributeValue<List<?>>(new IdentifierImpl(value.getDataType()), value.getContent()),
-																			designator.getIssuer(),
-																			false);
-									attributeDataType = designator.getDataType();
-								} 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);
-									attributeDataType = selector.getDataType();
-								} else {
-									LOGGER.warn("NULL designator/selector or value for match.");
-									attributeDataType = "NA";
-								}
-								
-								String functionName = getHumanFunction(match.getMatchId());
-								if(attribute != null){
-									String succintIdentifier = extractLastIdentifier(attribute.getCategory().stringValue(), ":") +
-											":" + extractLastIdentifier(attribute.getAttributeId().stringValue(), ":");
-									AttributeIdentifiers ai = new AttributeIdentifiers(attribute.getCategory().stringValue(), 
-											attributeDataType,
-											attribute.getAttributeId().stringValue());
-									this.attributeIdentifiersMap.put(succintIdentifier,ai);
+    public HtmlProcessor(File policyFile, Object policyObject) {
+        if (LOGGER.isTraceEnabled())
+            LOGGER.trace(ENTER);
 
-									targetInHuman.append("<i><a href=\"#" + succintIdentifier + "\">" + succintIdentifier + "</a></i> " + functionName + " ");
+        if (policyFile == null) {
+            LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Null Policy File");
+            throw new IllegalArgumentException("Null Policy File");
+        }
 
-									int numAttributes = attribute.getValues().size();
-									int count = 0;
-									for (AttributeValue<?> v: attribute.getValues()) {
-										count++;						
-										if (v.getValue() instanceof Collection<?>) {
-											Collection<?> value_s = (Collection<?>) v.getValue();
-											int numValues = value_s.size();
-											int countValues = 0;
-											for (Object o : value_s) {
-												countValues++;
-												targetInHuman.append(" <I>" + o + "</I>");
-												if (countValues < numValues) {
-													targetInHuman.append(", or");
-												}
-											}
-										} else {
-											targetInHuman.append(" <I>" + v.getValue() + "</I>");
-											if (count < numAttributes) {
-												targetInHuman.append(", or ");
-											}
-										}
-									}
-								}
-								
-								if (iterMatch.hasNext()) {
-									targetInHuman.append(" and ");
-								}
-							} // end iterMatch
-							if (matchList.size() > 1) {
-								targetInHuman.append(")");
-							}
-						}
-						if (iterAllOf.hasNext()) {
-							targetInHuman.append(" or ");
-						}
-					} // end iterAllOf 
-				}
-				if (iterAnyOf.hasNext()) {
-					targetInHuman = new StringBuilder();
-					targetInHuman.append("(" + targetInHuman + ")" + " or ");
-				} else {
-					if (anyOfList.size() > 1) {
-						targetInHuman.append(")");
-					}
-				}
-			} // end iterAnyOf
-			htmlOut.println(targetInHuman);
-		}
-	}
-	
-	private String getHumanFunction(String matchId) {
-		if (HtmlProcessor.function2human.containsKey(matchId)) {
-			return HtmlProcessor.function2human.get(matchId);
-		}
-		
-		FunctionDefinition function = PolicyController.getFunctionIDMap().get(matchId);
-		String functionName = function.getShortname();
-		
-		if (LOGGER.isDebugEnabled()) {
-			LOGGER.debug(functionName + 
-					     ": #args[" + function.getArgLb() + "," + function.getArgUb() +"]");
-		}
-		
-		return extractLastIdentifier(removePrimitives(functionName), ":");
-	}
+        if (!policyFile.exists() || !policyFile.canRead()) {
+            String msg = "Can't access " + policyFile.getAbsolutePath();
+            LOGGER.error(XACMLErrorConstants.ERROR_PERMISSIONS + msg);
+            throw new IllegalArgumentException(msg);
+        }
 
-	public String html() {
-		this.htmlOut.flush();
-		return this.stringWriter.toString();
-	}
-	
-	private String extractLastIdentifier(String in, String separator) {
-		int lastIndex = in.lastIndexOf(separator);
-		if (lastIndex < 0)
-			return in;
-		else
-			return in.substring(lastIndex+1);
-	}
-	
-	private String removePrimitives(String in) {
-		String newIn = in;
-		newIn = newIn.replace("string-", "");
-		newIn = newIn.replace("integer-", "");
-		newIn = newIn.replace("double-", "");
-		newIn = newIn.replace("boolean-", "");
-		return newIn;
-	}
-	
-	private String stringifyCondition(ConditionType condition) {
-		if (condition.getExpression() == null) {
-			return "";
-		}
-		
-		return stringifyExpression(condition.getExpression().getValue());
-	}
+        if (policyObject == null
+                || (!(policyObject instanceof PolicySetType) && !(policyObject instanceof PolicyType))) {
+            String msg = "Invalid unmarshalled object: " + policyObject;
+            LOGGER.error(XACMLErrorConstants.ERROR_SCHEMA_INVALID + msg);
+            throw new IllegalArgumentException(msg);
+        }
 
-	private String stringifyExpression(Object expression) {
-		if (expression instanceof ApplyType) {
-			ApplyType apply = (ApplyType) expression;
-			FunctionDefinition function = PolicyController.getFunctionIDMap().get(apply.getFunctionId());
-			String functionName = function.getShortname();
-			
-			if (LOGGER.isDebugEnabled()) {
-				LOGGER.debug(functionName + 
-						     ": #args[" + function.getArgLb() + "," + function.getArgUb() +"]");
-			}
-			
-			if (functionName.contains("one-and-only")) {
-				if (LOGGER.isDebugEnabled()) {
-					LOGGER.debug("one-and-only found: " + functionName);
-				}
-				
-				List<JAXBElement<?>> exps = apply.getExpression();
-				if (exps == null || exps.isEmpty())
-					return "";
-				else {
-					StringBuilder forResult = new StringBuilder();
-					for (JAXBElement<?> e : exps) {
-						Object v = e.getValue();
-						if (LOGGER.isDebugEnabled()) {
-							LOGGER.debug("one-and-only children: " + v);
-						}
-						if (v != null) {
-							forResult.append(stringifyExpression(v));
-						}
-					}
-					return forResult.toString(); 
-				}
-			}
-			
-			final int numExpr = (apply.getExpression() == null) ? -1 : apply.getExpression().size();			
-			if (numExpr <= 0) {
-				if (LOGGER.isDebugEnabled()) {
-					LOGGER.debug(functionName + " 0 expressions: " + numExpr);
-				}
-				return "";
-			} else if (numExpr == 1) {
-				// eg: not
-				if (LOGGER.isDebugEnabled()) {
-					LOGGER.debug(functionName + " 1 expression: " + numExpr);
-				}
-				StringBuilder applySubresult = new StringBuilder();
-				for (JAXBElement<?> e : apply.getExpression()) {
-					Object v = e.getValue();
-					if (v != null) {
-						applySubresult.append(this.stringifyExpression(e.getValue()));
-					}
-				}
-				return " " + removePrimitives(functionName) + " (" + applySubresult.toString() + ")";
-			} else { 
-				// > 1 arguments
-				if (LOGGER.isDebugEnabled()) {
-					LOGGER.debug(functionName + " > 1 expressions: " + numExpr);
-				}
-				StringBuilder applySubresult = new StringBuilder();
-				int exprCount = 0;
-				for (JAXBElement<?> e : apply.getExpression()) {
-					exprCount++;
-					Object ev = e.getValue();
-					if (ev != null) {
-						if (ev instanceof ApplyType) {
-							if (((ApplyType) ev).getFunctionId().contains("one-and-only")) {
-								applySubresult.append(this.stringifyExpression(e.getValue()));
-							} else {
-								applySubresult.append("(" + this.stringifyExpression(e.getValue()) + ")");
-							}
-						} else {
-							applySubresult.append(this.stringifyExpression(e.getValue()));
-						}
-						
-						if (exprCount < numExpr) {
-							applySubresult.append(" " + removePrimitives(functionName) + " ");
-						}
-					}
-				}
-				return applySubresult.toString();
-			}
-		}
-		if (expression instanceof AttributeDesignatorType) {
-			AttributeDesignatorType adt = (AttributeDesignatorType) expression;
-			
-			String succintIdentifier = extractLastIdentifier(adt.getCategory(), ":") +
-	                                   ":" + extractLastIdentifier(adt.getAttributeId(), ":");
-			AttributeIdentifiers ai = new AttributeIdentifiers(adt.getCategory(), 
-					                                           adt.getDataType(),
-					                                           adt.getAttributeId());			
-			this.attributeIdentifiersMap.put(succintIdentifier,ai);
+        this.policyName = FilenameUtils.removeExtension(policyFile.getName());
+        this.rootPolicyObject = policyObject;
 
-			return "<a href=\"#" + succintIdentifier + "\">" + succintIdentifier + "</a>";
-		}
-		if (expression instanceof AttributeSelectorType) {
-			AttributeSelectorType ast = (AttributeSelectorType) expression;
-			
-			String attrName = ast.getPath();
-			if (attrName == null || (attrName.length() == 0)) {
-				return "";
-			}
-			
-			String textSelector = "/text()";
-			if (attrName.endsWith(textSelector)) {
-				attrName = attrName.substring(0, attrName.length() - textSelector.length());
-			}
-			
-			attrName = extractLastIdentifier(attrName, "/");
-			attrName = extractLastIdentifier(attrName, ":");
-			return " " + attrName;
-		}
-		if (expression instanceof AttributeValueType) {
-			AttributeValueType avt = (AttributeValueType) expression;
-			List<Object> content = avt.getContent();
-			StringBuilder value_s = new StringBuilder();
-			for (Object o: content) {
-				value_s.append(" " + o.toString());
-			}
-			return " " + value_s.toString();
-		}
-		if (expression instanceof VariableReferenceType) {
-			//
-			// Really unknown - the variable may or may not have been defined
-			//
-			return " VARIABLEREF-NOT-HANDLED";
-		} else {
-			throw new IllegalArgumentException("Unexpected input expression");
-		}
-	}
+        String version = "-";
+        if (policyObject instanceof PolicyType) {
+            PolicyType policy = (PolicyType) policyObject;
+            version = policy.getVersion();
+            htmlOut.println("<h1>Policy:   " + policyName + "  (version " + version + ") </h1>");
+
+        } else {
+            PolicySetType policySet = (PolicySetType) policyObject;
+            version = policySet.getVersion();
+            htmlOut.println("<h1>Policy Set:   " + policyName + "  (v" + version + ") </h1>");
+        }
+
+        htmlOut.println("<h3><b>Location: </b>" + policyFile.getPath() + "</h3>");
+        htmlOut.println("<hr>");
+
+        if (rootPolicyObject instanceof PolicySetType) {
+            if (policyName.startsWith("Config_")) {
+                htmlOut.println("<p>This is a <b>config</b> policy set.</p>");
+            } else if (policyName.startsWith("Action_")) {
+                htmlOut.println("<p>This is an <b>action</b> policy set.</p>");
+            }
+            htmlOut.println("<dl>");
+        } else {
+            if (policyName.startsWith("Config_")) {
+                htmlOut.println("<p>This is a <b>config</b> policy.</p>");
+            } else if (policyName.startsWith("Action_")) {
+                htmlOut.println("<p>This is an <b>action</b> policy.</p>");
+            }
+            htmlOut.println("<ol>");
+        }
+    }
+
+    /**
+     * @return the attributeIdentifiersMap
+     */
+    public Map<String, AttributeIdentifiers> getAttributeIdentifiersMap() {
+        return attributeIdentifiersMap;
+    }
+
+    @Override
+    public void onFinishScan(Object root) {
+        if (LOGGER.isTraceEnabled())
+            LOGGER.trace(ENTER);
+
+        if (rootPolicyObject instanceof PolicySetType) {
+            htmlOut.println("</dl>");
+        } else {
+            htmlOut.println("</ol>");
+        }
+
+        htmlOut.println("<hr>");
+
+        htmlOut.println("<h3>Attribute Table:</h3>");
+
+        htmlOut.println("<table border=\"3\" style=\"width:100%\">");
+        htmlOut.println("<tr>");
+        htmlOut.print("<th>Category</th>");
+        htmlOut.print("<th>Type</th>");
+        htmlOut.print("<th>Identifier</th>");
+        htmlOut.println("</tr>");
+        for (Map.Entry<String, AttributeIdentifiers> entry : this.attributeIdentifiersMap.entrySet()) {
+            AttributeIdentifiers value = entry.getValue();
+            htmlOut.println("<tr>");
+            htmlOut.print("<td><a name=\"" + entry.getKey() + "\"></a>" + value.category + "</td>");
+            htmlOut.print("<td>" + value.getType() + "</td>");
+            htmlOut.print("<td>" + value.id + "</td>");
+            htmlOut.println("</tr>");
+        }
+        htmlOut.println("</table>");
+
+        htmlOut.println("<p></p>");
+
+        // Not necessary for the user, uncomment if desired at some point
+        // writeRawXACML()
+
+        super.onFinishScan(root);
+    }
+
+    @Override
+    public CallbackResult onPreVisitPolicySet(PolicySetType parent, PolicySetType policySet) {
+        if (LOGGER.isTraceEnabled())
+            LOGGER.trace("PolicySet: " + policySet.getPolicySetId() + " Version: " + policySet.getVersion());
+
+        if (parent != null && LOGGER.isTraceEnabled())
+            LOGGER.trace("PolicySet: " + policySet.getPolicySetId() + "Parent PolicySet: " + parent.getPolicySetId()
+                    + " Version: " + parent.getVersion());
+
+        String description = policySet.getDescription();
+        if (description != null && LOGGER.isTraceEnabled())
+            LOGGER.trace("PolicySet: " + policySet.getPolicySetId() + " Description: " + policySet.getDescription());
+
+        if (parent == null) // root
+            policySet(policySet, "dl");
+        else
+            policySet(policySet, "li");
+
+        if (!policySet.getPolicySetOrPolicyOrPolicySetIdReference().isEmpty())
+            htmlOut.println("<ol>");
+
+        return super.onPreVisitPolicySet(parent, policySet);
+    }
+
+    @Override
+    public CallbackResult onPostVisitPolicySet(PolicySetType parent, PolicySetType policySet) {
+        if (LOGGER.isTraceEnabled())
+            LOGGER.trace("PolicySet: " + policySet.getPolicySetId() + " Version: " + policySet.getVersion());
+
+        if (parent != null && LOGGER.isTraceEnabled())
+            LOGGER.trace("PolicySet: " + policySet.getPolicySetId() + "Parent PolicySet: " + parent.getPolicySetId()
+                    + " Version: " + parent.getVersion());
+
+        String description = policySet.getDescription();
+        if (description != null && LOGGER.isTraceEnabled())
+            LOGGER.trace("PolicySet: " + policySet.getPolicySetId() + " Description: " + policySet.getDescription());
+
+        if (!policySet.getPolicySetOrPolicyOrPolicySetIdReference().isEmpty())
+            htmlOut.println("</ol>");
+
+        htmlOut.println("<p></p>");
+
+        return super.onPostVisitPolicySet(parent, policySet);
+    }
+
+    public void policySet(PolicySetType policySet, String htmlListElement) {
+        if (LOGGER.isTraceEnabled())
+            LOGGER.trace("PolicySet: " + policySet.getPolicySetId());
+
+        String combiningAlgorithm = "-";
+        String id = "-";
+        String version = "-";
+
+
+        if (policySet.getPolicyCombiningAlgId() != null)
+            combiningAlgorithm = extractLastIdentifier(policySet.getPolicyCombiningAlgId(), ":");
+
+        if (policySet.getPolicySetId() != null)
+            id = extractLastIdentifier(policySet.getPolicySetId(), ":");
+
+        if (policySet.getVersion() != null)
+            version = policySet.getVersion();
+
+
+        htmlOut.println("<" + htmlListElement + "><b>Policy Set ID</b>: <i>" + id + "</i>  (v" + version + ") " + "</"
+                + htmlListElement + ">");
+
+        if (policySet.getTarget() == null || policySet.getTarget().getAnyOf() == null
+                || policySet.getTarget().getAnyOf().isEmpty()) {
+            htmlOut.println("<p>This policy set applies to all requests.</p>");
+        } else {
+            htmlOut.print("<p>");
+            htmlOut.print("This policy set applies to requests with attributes ");
+
+            List<AnyOfType> anyOf_s = policySet.getTarget().getAnyOf();
+            target(anyOf_s);
+            htmlOut.println(".</p>");
+        }
+
+        if (policySet.getPolicySetOrPolicyOrPolicySetIdReference() != null
+                && !policySet.getPolicySetOrPolicyOrPolicySetIdReference().isEmpty()) {
+            String algoDesc = combiningAlgo2human.get(combiningAlgorithm);
+            if (algoDesc != null) {
+                algoDesc = algoDesc.replace("$placeholder$", "policy") + " (" + "<i>" + combiningAlgorithm + "</i>)";
+            } else {
+                algoDesc = combiningAlgorithm;
+            }
+
+            htmlOut.println("<p>The result is " + algoDesc + ": </p>");
+        }
+    }
+
+    @Override
+    public CallbackResult onPreVisitPolicy(PolicySetType parent, PolicyType policy) {
+        if (LOGGER.isTraceEnabled())
+            LOGGER.trace("PolicySet: " + policy.getPolicyId() + " Version: " + policy.getVersion());
+
+        if (parent != null && LOGGER.isTraceEnabled())
+            LOGGER.trace("PolicySet: " + policy.getPolicyId() + "Parent PolicySet: " + parent.getPolicySetId()
+                    + " Version: " + parent.getVersion());
+
+        String description = policy.getDescription();
+        if (description != null && LOGGER.isTraceEnabled())
+            LOGGER.trace("PolicySet: " + policy.getPolicyId() + " Description: " + policy.getDescription());
+
+        policy(policy);
+
+        if (!policy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().isEmpty())
+            htmlOut.println("<ol type=\"i\">");
+
+        return super.onPreVisitPolicy(parent, policy);
+    }
+
+    @Override
+    public CallbackResult onPostVisitPolicy(PolicySetType parent, PolicyType policy) {
+        if (LOGGER.isTraceEnabled())
+            LOGGER.trace("PolicySet: " + policy.getPolicyId() + " Version: " + policy.getVersion());
+
+        if (parent != null && LOGGER.isTraceEnabled())
+            LOGGER.trace("PolicySet: " + policy.getPolicyId() + "Parent PolicySet: " + parent.getPolicySetId()
+                    + " Version: " + parent.getVersion());
+
+        if (!policy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().isEmpty())
+            htmlOut.println("</ol>");
+
+        htmlOut.println("<p></p>");
+        return super.onPostVisitPolicy(parent, policy);
+    }
+
+    public void policy(PolicyType policy) {
+        if (LOGGER.isTraceEnabled())
+            LOGGER.trace("Policy: " + policy.getPolicyId());
+
+        String combiningAlgorithm = "-";
+        String id = "-";
+        String version = "-";
+
+
+        if (policy.getRuleCombiningAlgId() != null)
+            combiningAlgorithm = extractLastIdentifier(policy.getRuleCombiningAlgId(), ":");
+
+        if (policy.getPolicyId() != null)
+            id = extractLastIdentifier(policy.getPolicyId(), ":");
+
+        if (policy.getVersion() != null)
+            version = policy.getVersion();
+
+        htmlOut.println("<li><b>Policy ID</b>: <i>" + id + "</i>  (v" + version + ") " + "</li>");
+
+        if (policy.getTarget() == null || policy.getTarget().getAnyOf() == null
+                || policy.getTarget().getAnyOf().isEmpty()) {
+            htmlOut.println("<p>This policy applies to all requests.</p>");
+        } else {
+            htmlOut.print("<p>");
+            htmlOut.print("This policy applies to requests with attributes ");
+
+            List<AnyOfType> anyOf_s = policy.getTarget().getAnyOf();
+            target(anyOf_s);
+            htmlOut.println(".</p>");
+        }
+
+        if (policy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition() != null
+                && !policy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().isEmpty()) {
+            String algoDesc = combiningAlgo2human.get(combiningAlgorithm);
+            if (algoDesc != null) {
+                algoDesc = algoDesc.replace("$placeholder$", "rule") + " (<i>" + combiningAlgorithm + "</i>)";
+            } else {
+                algoDesc = combiningAlgorithm;
+            }
+            htmlOut.println("<p>The result is " + algoDesc + ": </p>");
+        }
+    }
+
+
+    @Override
+    public CallbackResult onPreVisitRule(PolicyType parent, RuleType rule) {
+        if (LOGGER.isTraceEnabled())
+            LOGGER.trace("Rule: " + rule.getRuleId());
+
+        if (parent != null && LOGGER.isTraceEnabled())
+            LOGGER.trace("Parent Policy: " + parent.getPolicyId() + " Version: " + parent.getVersion());
+
+        String description = rule.getDescription();
+        if (description != null && LOGGER.isTraceEnabled()) {
+            LOGGER.trace("Rule: " + rule.getRuleId() + " Description: " + rule.getDescription());
+        }
+
+        rule(rule);
+
+        return super.onPreVisitRule(parent, rule);
+    }
+
+    @Override
+    public CallbackResult onPostVisitRule(PolicyType parent, RuleType rule) {
+        if (LOGGER.isTraceEnabled())
+            LOGGER.trace("Rule: " + rule.getRuleId());
+
+        if (parent != null && LOGGER.isTraceEnabled())
+            LOGGER.trace("Parent Policy: " + parent.getPolicyId() + " Version: " + parent.getVersion());
+
+        return super.onPostVisitRule(parent, rule);
+    }
+
+    public void rule(RuleType rule) {
+        if (LOGGER.isTraceEnabled())
+            LOGGER.trace("Rule: " + rule.getRuleId());
+
+        String id = "-";
+
+        if (rule.getRuleId() != null)
+            id = extractLastIdentifier(rule.getRuleId(), ":");
+
+        htmlOut.println("<li><b>Rule ID</b>: <i>" + id + "</i></li>");
+
+        htmlOut.println("<dl>");
+
+        htmlOut.print("<p>");
+        htmlOut.print(rule.getEffect().value());
+
+        if (rule.getTarget() == null || rule.getTarget().getAnyOf() == null || rule.getTarget().getAnyOf().isEmpty()) {
+            htmlOut.print(" for all requests");
+        } else {
+            List<AnyOfType> anyOf_s = rule.getTarget().getAnyOf();
+            htmlOut.print(" for requests with attributes ");
+            target(anyOf_s);
+        }
+
+        if (rule.getCondition() != null) {
+            htmlOut.print(" when ");
+            htmlOut.println(this.stringifyCondition(rule.getCondition()) + " ");
+        } else {
+            htmlOut.print(" with no conditions ");
+        }
+
+        if (rule.getAdviceExpressions() != null) {
+            advice(rule.getAdviceExpressions());
+            if (rule.getObligationExpressions() != null)
+                htmlOut.println(" and ");
+        }
+
+        if (rule.getObligationExpressions() != null) {
+            obligation(rule.getObligationExpressions());
+        }
+
+        htmlOut.println("</p>");
+    }
+
+    private void advice(AdviceExpressionsType adviceExpressions) {
+        if (LOGGER.isTraceEnabled())
+            LOGGER.trace(ENTER);
+
+        List<AdviceExpressionType> ae = adviceExpressions.getAdviceExpression();
+        for (AdviceExpressionType expression : ae) {
+            htmlOut.println(" with <b>advice</b> (<i>" + expression.getAdviceId() + "</i>) on <i>"
+                    + expression.getAppliesTo().value() + "</i>:");
+            htmlOut.println("<ol type=\"a\">");
+            List<AttributeAssignmentExpressionType> assignments = expression.getAttributeAssignmentExpression();
+            if (assignments != null) {
+                processAttributeAssignments(assignments);
+            }
+            htmlOut.println("</ol>");
+        }
+    }
+
+    private void obligation(ObligationExpressionsType obligationExpressions) {
+        if (LOGGER.isTraceEnabled())
+            LOGGER.trace(ENTER);
+
+        List<ObligationExpressionType> oe = obligationExpressions.getObligationExpression();
+        for (ObligationExpressionType expression : oe) {
+            htmlOut.println(" with <b>obligations</b> (<i>" + expression.getObligationId()
+                    + "</i>) to be fullfilled on <i>" + expression.getFulfillOn().value() + "</i>:");
+            htmlOut.println("<ol type=\"a\">");
+            List<AttributeAssignmentExpressionType> assignments = expression.getAttributeAssignmentExpression();
+            if (assignments != null) {
+                processAttributeAssignments(assignments);
+            }
+            htmlOut.println("</ol>");
+        }
+    }
+
+    /**
+     * @param assignments
+     */
+    private void processAttributeAssignments(List<AttributeAssignmentExpressionType> assignments) {
+        if (LOGGER.isTraceEnabled())
+            LOGGER.trace(ENTER);
+
+        for (AttributeAssignmentExpressionType assignment : assignments) {
+            String succintIdentifier = extractLastIdentifier(assignment.getCategory(), ":") + ":"
+                    + extractLastIdentifier(assignment.getAttributeId(), ":");
+            AttributeIdentifiers attributeIdentifiers = null;
+            if (!this.attributeIdentifiersMap.containsKey(succintIdentifier)) {
+                // Note Attribute Assignments do not have an Attribute Type, assume string
+                // but note this case is unlikely since attributeMap should have been populated
+                // during parsing of target and conditions, and not in this case for Advice and
+                // Obligations.
+                attributeIdentifiers =
+                        new AttributeIdentifiers(assignment.getCategory(), "NA", assignment.getAttributeId());
+                this.attributeIdentifiersMap.put(succintIdentifier, attributeIdentifiers);
+            }
+
+            htmlOut.print("<li><i><a href=\"#" + succintIdentifier + "\">" + succintIdentifier + "</a></i> is ");
+            // AttributeValueType
+            JAXBElement<?> jaxbExp = assignment.getExpression();
+            Object assignmentObject = jaxbExp.getValue();
+            if (assignmentObject instanceof AttributeValueType) {
+                AttributeValueType avt = (AttributeValueType) assignmentObject;
+                if (attributeIdentifiers != null) {
+                    attributeIdentifiers.setType(avt.getDataType());
+                }
+                int numContent = avt.getContent().size();
+                int countContent = 0;
+                for (Object c : avt.getContent()) {
+                    countContent++;
+                    htmlOut.print("<i>" + c + "</i>");
+                    if (countContent < numContent)
+                        htmlOut.print(" or ");
+                }
+                htmlOut.println("</li>");
+            } else if (assignmentObject instanceof AttributeDesignatorType
+                    || assignmentObject instanceof AttributeSelectorType || assignmentObject instanceof ApplyType) {
+                htmlOut.println("NA");
+            } else {
+                htmlOut.println("Unexpected");
+            }
+        }
+    }
+
+    /**
+     * 
+     * @param anyOfList
+     */
+    public void target(List<AnyOfType> anyOfList) {
+        if (LOGGER.isTraceEnabled())
+            LOGGER.trace(ENTER);
+
+        if (anyOfList != null) {
+            Iterator<AnyOfType> iterAnyOf = anyOfList.iterator();
+            StringBuilder targetInHuman = new StringBuilder();
+            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();
+                            if (matchList.size() > 1)
+                                targetInHuman.append("(");
+                            while (iterMatch.hasNext()) {
+                                MatchType match = iterMatch.next();
+                                //
+                                // Finally down to the actual attribute
+                                //
+                                StdAttribute attribute = null;
+                                AttributeValueType value = match.getAttributeValue();
+                                String attributeDataType;
+                                if (match.getAttributeDesignator() != null && value != null) {
+                                    AttributeDesignatorType designator = match.getAttributeDesignator();
+                                    attribute = new StdAttribute(new IdentifierImpl(designator.getCategory()),
+                                            new IdentifierImpl(designator.getAttributeId()),
+                                            new StdAttributeValue<List<?>>(new IdentifierImpl(value.getDataType()),
+                                                    value.getContent()),
+                                            designator.getIssuer(), false);
+                                    attributeDataType = designator.getDataType();
+                                } 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);
+                                    attributeDataType = selector.getDataType();
+                                } else {
+                                    LOGGER.warn("NULL designator/selector or value for match.");
+                                    attributeDataType = "NA";
+                                }
+
+                                String functionName = getHumanFunction(match.getMatchId());
+                                if (attribute != null) {
+                                    String succintIdentifier = extractLastIdentifier(
+                                            attribute.getCategory().stringValue(), ":") + ":"
+                                            + extractLastIdentifier(attribute.getAttributeId().stringValue(), ":");
+                                    AttributeIdentifiers ai =
+                                            new AttributeIdentifiers(attribute.getCategory().stringValue(),
+                                                    attributeDataType, attribute.getAttributeId().stringValue());
+                                    this.attributeIdentifiersMap.put(succintIdentifier, ai);
+
+                                    targetInHuman.append("<i><a href=\"#" + succintIdentifier + "\">"
+                                            + succintIdentifier + "</a></i> " + functionName + " ");
+
+                                    int numAttributes = attribute.getValues().size();
+                                    int count = 0;
+                                    for (AttributeValue<?> v : attribute.getValues()) {
+                                        count++;
+                                        if (v.getValue() instanceof Collection<?>) {
+                                            Collection<?> value_s = (Collection<?>) v.getValue();
+                                            int numValues = value_s.size();
+                                            int countValues = 0;
+                                            for (Object o : value_s) {
+                                                countValues++;
+                                                targetInHuman.append(" <I>" + o + "</I>");
+                                                if (countValues < numValues) {
+                                                    targetInHuman.append(", or");
+                                                }
+                                            }
+                                        } else {
+                                            targetInHuman.append(" <I>" + v.getValue() + "</I>");
+                                            if (count < numAttributes) {
+                                                targetInHuman.append(", or ");
+                                            }
+                                        }
+                                    }
+                                }
+
+                                if (iterMatch.hasNext()) {
+                                    targetInHuman.append(" and ");
+                                }
+                            } // end iterMatch
+                            if (matchList.size() > 1) {
+                                targetInHuman.append(")");
+                            }
+                        }
+                        if (iterAllOf.hasNext()) {
+                            targetInHuman.append(" or ");
+                        }
+                    } // end iterAllOf
+                }
+                if (iterAnyOf.hasNext()) {
+                    targetInHuman = new StringBuilder();
+                    targetInHuman.append("(" + targetInHuman + ")" + " or ");
+                } else {
+                    if (anyOfList.size() > 1) {
+                        targetInHuman.append(")");
+                    }
+                }
+            } // end iterAnyOf
+            htmlOut.println(targetInHuman);
+        }
+    }
+
+    private String getHumanFunction(String matchId) {
+        if (HtmlProcessor.function2human.containsKey(matchId)) {
+            return HtmlProcessor.function2human.get(matchId);
+        }
+
+        FunctionDefinition function = PolicyController.getFunctionIdMap().get(matchId);
+        String functionName = function.getShortname();
+
+        if (LOGGER.isDebugEnabled()) {
+            LOGGER.debug(functionName + ": #args[" + function.getArgLb() + "," + function.getArgUb() + "]");
+        }
+
+        return extractLastIdentifier(removePrimitives(functionName), ":");
+    }
+
+    public String html() {
+        this.htmlOut.flush();
+        return this.stringWriter.toString();
+    }
+
+    private String extractLastIdentifier(String in, String separator) {
+        int lastIndex = in.lastIndexOf(separator);
+        if (lastIndex < 0) {
+            return in;
+        } else {
+            return in.substring(lastIndex + 1);
+        }
+    }
+
+    private String removePrimitives(String in) {
+        String newIn = in;
+        newIn = newIn.replace("string-", "");
+        newIn = newIn.replace("integer-", "");
+        newIn = newIn.replace("double-", "");
+        newIn = newIn.replace("boolean-", "");
+        return newIn;
+    }
+
+    private String stringifyCondition(ConditionType condition) {
+        if (condition.getExpression() == null) {
+            return "";
+        }
+
+        return stringifyExpression(condition.getExpression().getValue());
+    }
+
+    private String stringifyExpression(Object expression) {
+        if (expression instanceof ApplyType) {
+            ApplyType apply = (ApplyType) expression;
+            FunctionDefinition function = PolicyController.getFunctionIdMap().get(apply.getFunctionId());
+            String functionName = function.getShortname();
+
+            if (LOGGER.isDebugEnabled()) {
+                LOGGER.debug(functionName + ": #args[" + function.getArgLb() + "," + function.getArgUb() + "]");
+            }
+
+            if (functionName.contains("one-and-only")) {
+                if (LOGGER.isDebugEnabled()) {
+                    LOGGER.debug("one-and-only found: " + functionName);
+                }
+
+                List<JAXBElement<?>> exps = apply.getExpression();
+                if (exps == null || exps.isEmpty()) {
+                    return "";
+                } else {
+                    StringBuilder forResult = new StringBuilder();
+                    for (JAXBElement<?> e : exps) {
+                        Object v = e.getValue();
+                        if (LOGGER.isDebugEnabled()) {
+                            LOGGER.debug("one-and-only children: " + v);
+                        }
+                        if (v != null) {
+                            forResult.append(stringifyExpression(v));
+                        }
+                    }
+                    return forResult.toString();
+                }
+            }
+
+            final int numExpr = (apply.getExpression() == null) ? -1 : apply.getExpression().size();
+            if (numExpr <= 0) {
+                if (LOGGER.isDebugEnabled()) {
+                    LOGGER.debug(functionName + " 0 expressions: " + numExpr);
+                }
+                return "";
+            } else if (numExpr == 1) {
+                // eg: not
+                if (LOGGER.isDebugEnabled()) {
+                    LOGGER.debug(functionName + " 1 expression: " + numExpr);
+                }
+                StringBuilder applySubresult = new StringBuilder();
+                for (JAXBElement<?> e : apply.getExpression()) {
+                    Object v = e.getValue();
+                    if (v != null) {
+                        applySubresult.append(this.stringifyExpression(e.getValue()));
+                    }
+                }
+                return " " + removePrimitives(functionName) + " (" + applySubresult.toString() + ")";
+            } else {
+                // > 1 arguments
+                if (LOGGER.isDebugEnabled()) {
+                    LOGGER.debug(functionName + " > 1 expressions: " + numExpr);
+                }
+                StringBuilder applySubresult = new StringBuilder();
+                int exprCount = 0;
+                for (JAXBElement<?> e : apply.getExpression()) {
+                    exprCount++;
+                    Object ev = e.getValue();
+                    if (ev != null) {
+                        if (ev instanceof ApplyType) {
+                            if (((ApplyType) ev).getFunctionId().contains("one-and-only")) {
+                                applySubresult.append(this.stringifyExpression(e.getValue()));
+                            } else {
+                                applySubresult.append("(" + this.stringifyExpression(e.getValue()) + ")");
+                            }
+                        } else {
+                            applySubresult.append(this.stringifyExpression(e.getValue()));
+                        }
+
+                        if (exprCount < numExpr) {
+                            applySubresult.append(" " + removePrimitives(functionName) + " ");
+                        }
+                    }
+                }
+                return applySubresult.toString();
+            }
+        }
+        if (expression instanceof AttributeDesignatorType) {
+            AttributeDesignatorType adt = (AttributeDesignatorType) expression;
+
+            String succintIdentifier = extractLastIdentifier(adt.getCategory(), ":") + ":"
+                    + extractLastIdentifier(adt.getAttributeId(), ":");
+            AttributeIdentifiers ai =
+                    new AttributeIdentifiers(adt.getCategory(), adt.getDataType(), adt.getAttributeId());
+            this.attributeIdentifiersMap.put(succintIdentifier, ai);
+
+            return "<a href=\"#" + succintIdentifier + "\">" + succintIdentifier + "</a>";
+        }
+        if (expression instanceof AttributeSelectorType) {
+            AttributeSelectorType ast = (AttributeSelectorType) expression;
+
+            String attrName = ast.getPath();
+            if (attrName == null || (attrName.length() == 0)) {
+                return "";
+            }
+
+            String textSelector = "/text()";
+            if (attrName.endsWith(textSelector)) {
+                attrName = attrName.substring(0, attrName.length() - textSelector.length());
+            }
+
+            attrName = extractLastIdentifier(attrName, "/");
+            attrName = extractLastIdentifier(attrName, ":");
+            return " " + attrName;
+        }
+        if (expression instanceof AttributeValueType) {
+            AttributeValueType avt = (AttributeValueType) expression;
+            List<Object> content = avt.getContent();
+            StringBuilder value_s = new StringBuilder();
+            for (Object o : content) {
+                value_s.append(" " + o.toString());
+            }
+            return " " + value_s.toString();
+        }
+        if (expression instanceof VariableReferenceType) {
+            //
+            // Really unknown - the variable may or may not have been defined
+            //
+            return " VARIABLEREF-NOT-HANDLED";
+        } else {
+            throw new IllegalArgumentException("Unexpected input expression");
+        }
+    }
 }
 
 
 class AttributeIdentifiers {
-	public final String category;
-	private String type;
-	public final String id;
-	
-	public AttributeIdentifiers(String category, String type, String id) {
-		this.category = category;
-		this.setType(type);
-		this.id = id;
-	}
+    public final String category;
+    private String type;
+    public final String id;
 
-	public String getType() {
-		return type;
-	}
+    public AttributeIdentifiers(String category, String type, String id) {
+        this.category = category;
+        this.setType(type);
+        this.id = id;
+    }
 
-	public void setType(String type) {
-		this.type = type;
-	}
-}	
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+}
diff --git a/POLICY-SDK-APP/src/main/java/org/onap/policy/controller/PolicyController.java b/POLICY-SDK-APP/src/main/java/org/onap/policy/controller/PolicyController.java
index 2200eae..3b4d03d 100644
--- a/POLICY-SDK-APP/src/main/java/org/onap/policy/controller/PolicyController.java
+++ b/POLICY-SDK-APP/src/main/java/org/onap/policy/controller/PolicyController.java
@@ -21,7 +21,8 @@
 
 package org.onap.policy.controller;
 
-
+import com.att.research.xacml.util.XACMLProperties;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
@@ -32,13 +33,13 @@
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Properties;
-
+import java.util.Set;
+import java.util.TreeMap;
 import javax.annotation.PostConstruct;
 import javax.mail.MessagingException;
 import javax.script.SimpleBindings;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-
 import org.json.JSONObject;
 import org.onap.policy.admin.PolicyNotificationMail;
 import org.onap.policy.admin.RESTfulPAPEngine;
@@ -53,9 +54,11 @@
 import org.onap.policy.rest.jpa.PolicyEntity;
 import org.onap.policy.rest.jpa.PolicyVersion;
 import org.onap.policy.rest.jpa.UserInfo;
+import org.onap.policy.utils.UserUtils.Pair;
 import org.onap.policy.xacml.api.XACMLErrorConstants;
 import org.onap.policy.xacml.api.pap.PAPPolicyEngine;
 import org.onap.portalsdk.core.controller.RestrictedBaseController;
+import org.onap.portalsdk.core.domain.UserApp;
 import org.onap.portalsdk.core.web.support.JsonMessage;
 import org.onap.portalsdk.core.web.support.UserUtils;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -65,14 +68,11 @@
 import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.servlet.ModelAndView;
 
-import com.att.research.xacml.util.XACMLProperties;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
 
 @Controller
 @RequestMapping("/")
 public class PolicyController extends RestrictedBaseController {
-    private static final Logger	policyLogger	= FlexLogger.getLogger(PolicyController.class);
+    private static final Logger policyLogger = FlexLogger.getLogger(PolicyController.class);
 
     private static CommonClassDao commonClassDao;
     //
@@ -83,6 +83,7 @@
     private static String logTableLimit;
     private static String systemAlertTableLimit;
     protected static Map<String, String> dropDownMap = new HashMap<>();
+
     public static Map<String, String> getDropDownMap() {
         return dropDownMap;
     }
@@ -99,49 +100,49 @@
     private static Map<Datatype, List<FunctionDefinition>> mapDatatype2Function = null;
     private static Map<String, FunctionDefinition> mapID2Function = null;
 
-    //Constant variables used across Policy-sdk
+    // Constant variables used across Policy-sdk
     private static final String policyData = "policyData";
     private static final String characterEncoding = "UTF-8";
     private static final String contentType = "application/json";
     private static final String file = "file";
 
-    //Smtp Java Mail Properties
+    // Smtp Java Mail Properties
     private static String smtpHost = null;
     private static String smtpPort = null;
     private static String smtpUsername = null;
     private static String smtpPassword = null;
     private static String smtpApplicationName = null;
     private static String smtpEmailExtension = null;
-    //log db Properties
+    // log db Properties
     private static String logdbDriver = null;
     private static String logdbUrl = null;
     private static String logdbUserName = null;
     private static String logdbPassword = null;
     private static String logdbDialect = null;
-    //Xacml db properties
+    // Xacml db properties
     private static String xacmldbUrl = null;
     private static String xacmldbUserName = null;
     private static String xacmldbPassword = null;
 
-    //AutoPush feature.
+    // AutoPush feature.
     private static String autoPushAvailable;
     private static String autoPushDSClosedLoop;
     private static String autoPushDSFirewall;
     private static String autoPushDSMicroservice;
     private static String autoPushPDPGroup;
 
-    //papURL
+    // papURL
     private static String papUrl;
 
-    //MicroService Model Properties
+    // MicroService Model Properties
     private static String msOnapName;
     private static String msPolicyName;
 
-    //WebApp directories
+    // WebApp directories
     private static String configHome;
     private static String actionHome;
 
-    //File upload size
+    // File upload size
     private static long fileSizeLimit;
 
     private static boolean jUnit = false;
@@ -156,7 +157,7 @@
     }
 
     @Autowired
-    private PolicyController(CommonClassDao commonClassDao){
+    private PolicyController(CommonClassDao commonClassDao) {
         PolicyController.commonClassDao = commonClassDao;
     }
 
@@ -164,26 +165,30 @@
         // Empty constructor
     }
 
+    /**
+     * init method to load the properties.
+     */
     @PostConstruct
-    public void init(){
+    public void init() {
         Properties prop = new Properties();
 
         try {
             String fileName;
-            if(jUnit){
-                fileName = new File(".").getCanonicalPath() + File.separator + "src"+ File.separator + "test" + File.separator + "resources" + File.separator + "JSONConfig.json";
+            if (jUnit) {
+                fileName = new File(".").getCanonicalPath() + File.separator + "src" + File.separator + "test"
+                        + File.separator + "resources" + File.separator + "JSONConfig.json";
             } else {
                 fileName = "xacml.admin.properties";
             }
 
-            try(InputStream input = new FileInputStream(fileName)) {
+            try (InputStream input = new FileInputStream(fileName)) {
                 // load a properties file
                 prop.load(input);
             }
 
-            //file upload size limit property
+            // file upload size limit property
             setFileSizeLimit(prop.getProperty("file.size.limit"));
-            //pap url
+            // pap url
             setPapUrl(prop.getProperty("xacml.rest.pap.url"));
             // get the property values
             setSmtpHost(prop.getProperty("onap.smtp.host"));
@@ -192,60 +197,67 @@
             setSmtpPassword(prop.getProperty("onap.smtp.password"));
             setSmtpApplicationName(prop.getProperty("onap.application.name"));
             setSmtpEmailExtension(prop.getProperty("onap.smtp.emailExtension"));
-            //Log Database Properties
+            // Log Database Properties
             setLogdbDriver(prop.getProperty("xacml.log.db.driver"));
             setLogdbUrl(prop.getProperty("xacml.log.db.url"));
             setLogdbUserName(prop.getProperty("xacml.log.db.user"));
             setLogdbPassword(prop.getProperty("xacml.log.db.password"));
             setLogdbDialect(prop.getProperty("onap.dialect"));
-            //Xacml Database Properties
+            // Xacml Database Properties
             setXacmldbUrl(prop.getProperty("javax.persistence.jdbc.url"));
             setXacmldbUserName(prop.getProperty("javax.persistence.jdbc.user"));
             setXacmldbPassword(prop.getProperty("javax.persistence.jdbc.password"));
-            //AutoPuh
+            // AutoPuh
             setAutoPushAvailable(prop.getProperty("xacml.automatic.push"));
             setAutoPushDSClosedLoop(prop.getProperty("xacml.autopush.closedloop"));
             setAutoPushDSFirewall(prop.getProperty("xacml.autopush.firewall"));
             setAutoPushDSMicroservice(prop.getProperty("xacml.autopush.microservice"));
             setAutoPushPDPGroup(prop.getProperty("xacml.autopush.pdpGroup"));
-            //Micro Service Properties
+            // Micro Service Properties
             setMsOnapName(prop.getProperty("xacml.policy.msOnapName"));
-            if(getMsOnapName() == null){
+            if (getMsOnapName() == null) {
                 setMsOnapName(prop.getProperty("xacml.policy.msEcompName"));
             }
             policyLogger.info("getMsOnapName => " + getMsOnapName());
             setMsPolicyName(prop.getProperty("xacml.policy.msPolicyName"));
             policyLogger.info("setMsPolicyName => " + getMsPolicyName());
-            //WebApp directories
+            // WebApp directories
             setConfigHome(prop.getProperty("xacml.rest.config.webapps") + "Config");
             setActionHome(prop.getProperty("xacml.rest.config.webapps") + "Action");
-            //Get the Property Values for Dashboard tab Limit
-            try{
+            // Get the Property Values for Dashboard tab Limit
+            try {
                 setLogTableLimit(prop.getProperty("xacml.onap.dashboard.logTableLimit"));
                 setSystemAlertTableLimit(prop.getProperty("xacml.onap.dashboard.systemAlertTableLimit"));
-            }catch(Exception e){
-                policyLogger.error(XACMLErrorConstants.ERROR_DATA_ISSUE+"Dashboard tab Property fields are missing" +e);
+            } catch (Exception e) {
+                policyLogger
+                        .error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Dashboard tab Property fields are missing" + e);
                 setLogTableLimit("5000");
                 setSystemAlertTableLimit("2000");
             }
             System.setProperty(XACMLProperties.XACML_PROPERTIES_NAME, "xacml.admin.properties");
         } catch (IOException ex) {
-            policyLogger.error(XACMLErrorConstants.ERROR_DATA_ISSUE+"Exception Occured while reading the Smtp properties from xacml.admin.properties file" +ex);
+            policyLogger.error(XACMLErrorConstants.ERROR_DATA_ISSUE
+                    + "Exception Occured while reading the Smtp properties from xacml.admin.properties file" + ex);
         }
 
-        //Initialize the FunctionDefinition table at Server Start up
+        // Initialize the FunctionDefinition table at Server Start up
         Map<Datatype, List<FunctionDefinition>> functionMap = getFunctionDatatypeMap();
-        for ( Entry<Datatype, List<FunctionDefinition>> entry : functionMap.entrySet()) {
+        for (Entry<Datatype, List<FunctionDefinition>> entry : functionMap.entrySet()) {
             List<FunctionDefinition> functionDefinations = entry.getValue();
             for (FunctionDefinition functionDef : functionDefinations) {
-                dropDownMap.put(functionDef.getShortname(),functionDef.getXacmlid());
+                dropDownMap.put(functionDef.getShortname(), functionDef.getXacmlid());
             }
         }
 
     }
 
-    public static  Map<Datatype, List<FunctionDefinition>>	getFunctionDatatypeMap() {
-        synchronized(mapAccess) {
+    /**
+     * Get FunctionData Type from DB.
+     * 
+     * @return list of FunctionData.
+     */
+    public static Map<Datatype, List<FunctionDefinition>> getFunctionDatatypeMap() {
+        synchronized (mapAccess) {
             if (mapDatatype2Function == null) {
                 buildFunctionMaps();
             }
@@ -253,8 +265,13 @@
         return mapDatatype2Function;
     }
 
-    public static Map<String, FunctionDefinition> getFunctionIDMap() {
-        synchronized(mapAccess) {
+    /**
+     * Get Function ID.
+     * 
+     * @return Function ID.
+     */
+    public static Map<String, FunctionDefinition> getFunctionIdMap() {
+        synchronized (mapAccess) {
             if (mapID2Function == null) {
                 buildFunctionMaps();
             }
@@ -262,11 +279,11 @@
         return mapID2Function;
     }
 
-    private static  void buildFunctionMaps() {
+    private static void buildFunctionMaps() {
         mapDatatype2Function = new HashMap<>();
-        mapID2Function = new  HashMap<>();
+        mapID2Function = new HashMap<>();
         List<Object> functiondefinitions = commonClassDao.getData(FunctionDefinition.class);
-        for (int i = 0; i < functiondefinitions.size(); i ++) {
+        for (int i = 0; i < functiondefinitions.size(); i++) {
             FunctionDefinition value = (FunctionDefinition) functiondefinitions.get(i);
             mapID2Function.put(value.getXacmlid(), value);
             if (!mapDatatype2Function.containsKey(value.getDatatypeBean())) {
@@ -276,42 +293,53 @@
         }
     }
 
-    @RequestMapping(value={"/get_FunctionDefinitionDataByName"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
-    public void getFunctionDefinitionData(HttpServletRequest request, HttpServletResponse response){
-        try{
+    /**
+     * Get Functional Definition data.
+     * 
+     * @param request HttpServletRequest.
+     * @param response HttpServletResponse.
+     */
+    @RequestMapping(value = {"/get_FunctionDefinitionDataByName"},
+            method = {org.springframework.web.bind.annotation.RequestMethod.GET},
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    public void getFunctionDefinitionData(HttpServletRequest request, HttpServletResponse response) {
+        try {
             Map<String, Object> model = new HashMap<>();
             ObjectMapper mapper = new ObjectMapper();
-            model.put("functionDefinitionDatas", mapper.writeValueAsString(commonClassDao.getDataByColumn(FunctionDefinition.class, "shortname")));
+            model.put("functionDefinitionDatas",
+                    mapper.writeValueAsString(commonClassDao.getDataByColumn(FunctionDefinition.class, "shortname")));
             JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
             JSONObject j = new JSONObject(msg);
             response.getWriter().write(j.toString());
-        }
-        catch (Exception e){
-            policyLogger.error(XACMLErrorConstants.ERROR_DATA_ISSUE +"Error while retriving the Function Definition data"+e);
+        } catch (Exception e) {
+            policyLogger.error(
+                    XACMLErrorConstants.ERROR_DATA_ISSUE + "Error while retriving the Function Definition data" + e);
         }
     }
 
-    public PolicyEntity getPolicyEntityData(String scope, String policyName){
+    /**
+     * Get PolicyEntity Data from db.
+     * 
+     * @param scope scopeName.
+     * @param policyName policyName.
+     * @return policyEntity data.
+     */
+    public PolicyEntity getPolicyEntityData(String scope, String policyName) {
         String key = scope + ":" + policyName;
         List<Object> data = commonClassDao.getDataById(PolicyEntity.class, "scope:policyName", key);
         return (PolicyEntity) data.get(0);
     }
 
-    public static Map<String, Roles> getUserRoles(String userId) {
-        Map<String, Roles> scopes = new HashMap<>();
-        List<Object> roles = commonClassDao.getDataById(Roles.class, "loginId", userId);
-        if (roles != null && !roles.isEmpty()) {
-            for (Object role : roles) {
-                scopes.put(((Roles) role).getScope(), (Roles) role);
-            }
-        }
-        return scopes;
-    }
-
+    /**
+     * Get Policy User Roles from db.
+     * 
+     * @param userId LoginID.
+     * @return list of Roles.
+     */
     public List<String> getRolesOfUser(String userId) {
         List<String> rolesList = new ArrayList<>();
         List<Object> roles = commonClassDao.getDataById(Roles.class, "loginId", userId);
-        for (Object role: roles) {
+        for (Object role : roles) {
             rolesList.add(((Roles) role).getRole());
         }
         return rolesList;
@@ -321,10 +349,17 @@
         return commonClassDao.getDataById(Roles.class, "loginId", userId);
     }
 
-    //Get List of User Roles
-    @RequestMapping(value={"/get_UserRolesData"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
-    public void getUserRolesEntityData(HttpServletRequest request, HttpServletResponse response){
-        try{
+    /**
+     * Get List of User Roles.
+     * 
+     * @param request HttpServletRequest.
+     * @param response HttpServletResponse.
+     */
+    @RequestMapping(value = {"/get_UserRolesData"},
+            method = {org.springframework.web.bind.annotation.RequestMethod.GET},
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    public void getUserRolesEntityData(HttpServletRequest request, HttpServletResponse response) {
+        try {
             String userId = UserUtils.getUserSession(request).getOrgUserId();
             Map<String, Object> model = new HashMap<>();
             ObjectMapper mapper = new ObjectMapper();
@@ -332,27 +367,112 @@
             JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
             JSONObject j = new JSONObject(msg);
             response.getWriter().write(j.toString());
-        }
-        catch (Exception e){
-            policyLogger.error("Exception Occured"+e);
+        } catch (Exception e) {
+            policyLogger.error("Exception Occured" + e);
         }
     }
 
-    //Policy tabs Model and View
-    @RequestMapping(value= {"/policy", "/policy/Editor" } , method = RequestMethod.GET)
-    public ModelAndView view(HttpServletRequest request){
-        String myRequestURL = request.getRequestURL().toString();
+    /**
+     * Policy tabs Model and View.
+     * 
+     * @param request Request input.
+     * @return view model.
+     */
+    @RequestMapping(value = {"/policy", "/policy/Editor"}, method = RequestMethod.GET)
+    public ModelAndView view(HttpServletRequest request) {
+        getUserRoleFromSession(request);
+        String myRequestUrl = request.getRequestURL().toString();
         try {
             //
             // Set the URL for the RESTful PAP Engine
             //
-            setPapEngine((PAPPolicyEngine) new RESTfulPAPEngine(myRequestURL));
-            new PDPGroupContainer((PAPPolicyEngine) new RESTfulPAPEngine(myRequestURL));
+            setPapEngine((PAPPolicyEngine) new RESTfulPAPEngine(myRequestUrl));
+            new PDPGroupContainer((PAPPolicyEngine) new RESTfulPAPEngine(myRequestUrl));
         } catch (Exception e) {
-            policyLogger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR+"Exception Occured while loading PAP"+e);
+            policyLogger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Exception Occured while loading PAP" + e);
         }
         Map<String, Object> model = new HashMap<>();
-        return new ModelAndView("policy_Editor","model", model);
+        return new ModelAndView("policy_Editor", "model", model);
+    }
+
+    /**
+     * Read the role from session.
+     * 
+     * @param request Request input.
+     */
+    public void getUserRoleFromSession(HttpServletRequest request) {
+        // While user landing on Policy page, fetch the userId and Role from
+        // session.
+        // And, Query the Roles table and if user not exists or else modified
+        // update the Roles table.
+        List<String> roles;
+        List<String> newRoles = new ArrayList<>();
+        String userId = UserUtils.getUserSession(request).getOrgUserId();
+        String name = UserUtils.getUserSession(request).getFullName();
+        @SuppressWarnings("unchecked")
+        Set<UserApp> userApps = UserUtils.getUserSession(request).getUserApps();
+        for (UserApp userApp : userApps) {
+            newRoles.add(userApp.getRole().getName());
+        }
+        List<Object> userRoles = getRoles(userId);
+        String filteredRole = filterRole(newRoles);
+        if (userRoles == null || userRoles.isEmpty()) {
+            savePolicyRoles(name, filteredRole, userId);
+        } else {
+            Pair<Set<String>, List<String>> pair = org.onap.policy.utils.UserUtils.checkRoleAndScope(userRoles);
+            roles = pair.u;
+            if (!roles.contains(filteredRole)) {
+                String query = "delete from Roles where loginid='" + userId + "'";
+                commonClassDao.updateQuery(query);
+                savePolicyRoles(name, filteredRole, userId);
+            }
+        }
+    }
+
+    /**
+     * Save the Role to DB.
+     * 
+     * @param name User Name.
+     * @param filteredRole Role Name.
+     * @param userId User LoginID.
+     */
+    private void savePolicyRoles(String name, String filteredRole, String userId) {
+        UserInfo userInfo = new UserInfo();
+        userInfo.setUserLoginId(userId);
+        userInfo.setUserName(name);
+        commonClassDao.save(userInfo);
+        Roles role = new Roles();
+        role.setName(name);
+        role.setRole(filteredRole);
+        role.setLoginId(userId);
+        commonClassDao.save(role);
+    }
+
+    /**
+     * Filter the list of roles hierarchy wise.
+     * 
+     * @param newRoles list of roles from request.
+     * @return
+     */
+    private String filterRole(List<String> newRoles) {
+        Map<Integer, String> roleMap = new TreeMap<>();
+        roleMap.put(6, "guest");
+        for (String role : newRoles) {
+            if ("Policy Super Admin".equalsIgnoreCase(role.trim())
+                    || "System Administrator".equalsIgnoreCase(role.trim())
+                    || "Standard User".equalsIgnoreCase(role.trim())) {
+                roleMap.put(1, "super-admin");
+            } else if ("Policy Super Editor".equalsIgnoreCase(role.trim())) {
+                roleMap.put(2, "super-editor");
+            } else if ("Policy Super Guest".equalsIgnoreCase(role.trim())) {
+                roleMap.put(3, "super-guest");
+            } else if ("Policy Admin".equalsIgnoreCase(role.trim())) {
+                roleMap.put(4, "admin");
+            } else if ("Policy Editor".equalsIgnoreCase(role.trim())) {
+                roleMap.put(5, "editor");
+            }
+        }
+        return roleMap.entrySet().iterator().next().getValue();
     }
 
     public PAPPolicyEngine getPapEngine() {
@@ -363,18 +483,25 @@
         PolicyController.papEngine = papEngine;
     }
 
+    /**
+     * Get UserName based on LoginID.
+     * 
+     * @param createdBy loginID.
+     * @return name.
+     */
     public String getUserName(String createdBy) {
         String loginId = createdBy;
         List<Object> data = commonClassDao.getDataById(UserInfo.class, "loginId", loginId);
         return data.get(0).toString();
     }
 
+    /**
+     * Check if the Policy is Active or not.
+     * @param query sql query.
+     * @return boolean.
+     */
     public static boolean getActivePolicy(String query) {
-        if(!commonClassDao.getDataByQuery(query, new SimpleBindings()).isEmpty()){
-            return true;
-        }else{
-            return false;
-        }
+        return !commonClassDao.getDataByQuery(query, new SimpleBindings()).isEmpty();
     }
 
     public void executeQuery(String query) {
@@ -393,61 +520,76 @@
         commonClassDao.delete(entity);
     }
 
-    public List<Object> getData(@SuppressWarnings("rawtypes") Class className){
+    public List<Object> getData(@SuppressWarnings("rawtypes") Class className) {
         return commonClassDao.getData(className);
     }
 
-    public PolicyVersion getPolicyEntityFromPolicyVersion(String query){
+    public PolicyVersion getPolicyEntityFromPolicyVersion(String query) {
         return (PolicyVersion) commonClassDao.getEntityItem(PolicyVersion.class, "policyName", query);
     }
 
-    public List<Object> getDataByQuery(String query, SimpleBindings params){
+    public List<Object> getDataByQuery(String query, SimpleBindings params) {
         return commonClassDao.getDataByQuery(query, params);
     }
 
 
     @SuppressWarnings("rawtypes")
-    public Object getEntityItem(Class className, String columname, String key){
+    public Object getEntityItem(Class className, String columname, String key) {
         return commonClassDao.getEntityItem(className, columname, key);
     }
 
 
-    public void watchPolicyFunction(PolicyVersion entity, String policyName, String mode){
+    /**
+     * Watch Policy Function.
+     * 
+     * @param entity PolicyVersion entity.
+     * @param policyName updated policy name.
+     * @param mode type of action rename/delete/import.
+     */
+    public void watchPolicyFunction(PolicyVersion entity, String policyName, String mode) {
         PolicyNotificationMail email = new PolicyNotificationMail();
         try {
             email.sendMail(entity, policyName, mode, commonClassDao);
         } catch (MessagingException e) {
-            policyLogger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Excepton Occured while Renaming/Deleting a Policy or Scope" + e);
+            policyLogger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR
+                    + "Excepton Occured while Renaming/Deleting a Policy or Scope" + e);
         }
     }
 
-    //Switch Version
-    public JSONObject switchVersionPolicyContent(String policyName) {
+    /**
+     * Switch Version Policy Content.
+     * 
+     * @param pName which is used to find associated versions.
+     * @return list of available versions based on policy name.
+     */
+    public JSONObject switchVersionPolicyContent(String pName) {
+        String policyName = pName;
         String dbCheckName = policyName.replace("/", ".");
-        if(dbCheckName.contains("Config_")){
+        if (dbCheckName.contains("Config_")) {
             dbCheckName = dbCheckName.replace(".Config_", ":Config_");
-        }else if(dbCheckName.contains("Action_")){
+        } else if (dbCheckName.contains("Action_")) {
             dbCheckName = dbCheckName.replace(".Action_", ":Action_");
-        }else if(dbCheckName.contains("Decision_")){
+        } else if (dbCheckName.contains("Decision_")) {
             dbCheckName = dbCheckName.replace(".Decision_", ":Decision_");
         }
-        String[] splitDBCheckName = dbCheckName.split(":");
-        String query =   "FROM PolicyEntity where policyName like :splitDBCheckName1 and scope = :splitDBCheckName0";
+        String[] splitDbCheckName = dbCheckName.split(":");
+        String query = "FROM PolicyEntity where policyName like :splitDBCheckName1 and scope = :splitDBCheckName0";
         SimpleBindings params = new SimpleBindings();
-        params.put("splitDBCheckName1", splitDBCheckName[1] + "%");
-        params.put("splitDBCheckName0", splitDBCheckName[0]);
+        params.put("splitDBCheckName1", splitDbCheckName[1] + "%");
+        params.put("splitDBCheckName0", splitDbCheckName[0]);
         List<Object> policyEntity = commonClassDao.getDataByQuery(query, params);
         List<String> av = new ArrayList<>();
-        for(Object entity : policyEntity){
+        for (Object entity : policyEntity) {
             PolicyEntity pEntity = (PolicyEntity) entity;
             String removeExtension = pEntity.getPolicyName().replace(".xml", "");
-            String version = removeExtension.substring(removeExtension.lastIndexOf('.')+1);
+            String version = removeExtension.substring(removeExtension.lastIndexOf('.') + 1);
             av.add(version);
         }
-        if(policyName.contains("/")){
+        if (policyName.contains("/")) {
             policyName = policyName.replace("/", File.separator);
         }
-        PolicyVersion entity = (PolicyVersion) commonClassDao.getEntityItem(PolicyVersion.class, "policyName", policyName);
+        PolicyVersion entity =
+                (PolicyVersion) commonClassDao.getEntityItem(PolicyVersion.class, "policyName", policyName);
         JSONObject el = new JSONObject();
         el.put("activeVersion", entity.getActiveVersion());
         el.put("availableVersions", av);
@@ -707,12 +849,16 @@
         return file;
     }
 
+    /**
+     * Set File Size limit.
+     * 
+     * @param uploadSize value.
+     */
     public static void setFileSizeLimit(String uploadSize) {
-        //Default size limit is 30MB
+        // Default size limit is 30MB
         if (uploadSize == null || uploadSize.isEmpty()) {
             fileSizeLimit = 30000000;
-        }
-        else {
+        } else {
             fileSizeLimit = Long.parseLong(uploadSize);
         }
     }
@@ -720,9 +866,16 @@
     public static long getFileSizeLimit() {
         return fileSizeLimit;
     }
+
+    /**
+     * Function to convert date.
+     * 
+     * @param dateTTL input date value.
+     * @return
+     */
     public String convertDate(String dateTTL) {
         String formateDate = null;
-        if(dateTTL.contains("-")){
+        if (dateTTL.contains("-")) {
             formateDate = dateTTL.replace("-", "/");
         }
         return formateDate;
diff --git a/packages/base/src/files/install/mysql/data/181003_upgrade_script.sql b/packages/base/src/files/install/mysql/data/181003_upgrade_script.sql
new file mode 100644
index 0000000..b060292
--- /dev/null
+++ b/packages/base/src/files/install/mysql/data/181003_upgrade_script.sql
@@ -0,0 +1,20 @@
+-- ============LICENSE_START=======================================================
+-- ONAP Policy Engine
+-- ================================================================================
+-- Copyright (C) 2018 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 onap_sdk;
+update fn_app set APP_PASSWORD = '/xMjAl0TB1FgnHih2qA4V5gUkFQNZaK1fiNf3QlRaLI=' where app_id =1;
+commit;
\ No newline at end of file
diff --git a/packages/base/src/files/install/servers/onap/WEB-INF/classes/portal.properties b/packages/base/src/files/install/servers/onap/WEB-INF/classes/portal.properties
index 1edaf6d..46ece6e 100644
--- a/packages/base/src/files/install/servers/onap/WEB-INF/classes/portal.properties
+++ b/packages/base/src/files/install/servers/onap/WEB-INF/classes/portal.properties
@@ -2,7 +2,7 @@
 # ============LICENSE_START=======================================================
 # ONAP Policy Engine
 # ================================================================================
-# Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+# Copyright (C) 2017-2018 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.
@@ -66,3 +66,11 @@
 ueb_app_consumer_group_name = {UUID}
 
 decryption_key				  = AGLDdG4D04BKm2IxIWEr8o==
+
+#INFO: Once the Roles onboarded by Portal to AAF, we need to enable this property.
+# Use this tag if the app is centralized
+#role_access_centralized = remote
+
+# Connection and Read timeout values
+ext_req_connection_timeout = 15000
+ext_req_read_timeout = 20000
\ No newline at end of file