Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/incubator-openaz
diff --git a/.gitignore b/.gitignore
index 4ebc016..f7b27b2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
+.DS_Store
 target
 .project
 .classpath
diff --git a/openaz-xacml-pap-admin/pom.xml b/openaz-xacml-pap-admin/pom.xml
index b027045..c6fd4f3 100644
--- a/openaz-xacml-pap-admin/pom.xml
+++ b/openaz-xacml-pap-admin/pom.xml
@@ -23,4 +23,287 @@
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <artifactId>openaz-xacml-pap-admin</artifactId>
+    <packaging>war</packaging>
+
+    <repositories>
+        <repository>
+            <id>vaadin-addons</id>
+            <url>http://maven.vaadin.com/vaadin-addons</url>
+        </repository>
+        <repository>
+            <id>vaadin-snapshots</id>
+            <url>http://oss.sonatype.org/content/repositories/vaadin-snapshots/</url>
+            <releases>
+                <enabled>false</enabled>
+            </releases>
+            <snapshots>
+                <enabled>true</enabled>
+            </snapshots>
+        </repository>
+    </repositories>
+
+    <!--
+    <pluginRepositories>
+        <pluginRepository>
+            <id>vaadin-snapshots</id>
+            <url>http://oss.sonatype.org/content/repositories/vaadin-snapshots/</url>
+            <releases>
+                <enabled>false</enabled>
+            </releases>
+            <snapshots>
+                <enabled>true</enabled>
+            </snapshots>
+        </pluginRepository>
+    </pluginRepositories>
+    -->
+
+    <properties>
+        <vaadin.version>7.1.11</vaadin.version>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.openaz</groupId>
+            <artifactId>openaz-xacml</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.openaz</groupId>
+            <artifactId>openaz-xacml-pdp</artifactId>
+        </dependency>
+
+
+        <!-- The core server part of Vaadin -->
+        <dependency>
+            <groupId>com.vaadin</groupId>
+            <artifactId>vaadin-server</artifactId>
+            <version>${vaadin.version}</version>
+        </dependency>
+
+        <!-- Vaadin themes -->
+        <dependency>
+            <groupId>com.vaadin</groupId>
+            <artifactId>vaadin-themes</artifactId>
+            <version>${vaadin.version}</version>
+        </dependency>
+
+        <!-- Push support -->
+        <dependency>
+            <groupId>com.vaadin</groupId>
+            <artifactId>vaadin-push</artifactId>
+            <version>${vaadin.version}</version>
+        </dependency>
+
+        <!--
+            Use the appropriate javax.servlet version for your
+            version of Jetty and other considerations.
+
+            Jetty 6 - Servlet API 2.4
+
+            <dependency>
+                <groupId>javax.servlet</groupId>
+                <artifactId>servlet-api</artifactId>
+                <version>2.4</version>
+                <scope>provided</scope>
+            </dependency>
+
+            Jetty 7 - Servlet API 2.5 / Standard Location
+
+            <dependency>
+                <groupId>javax.servlet</groupId>
+                <artifactId>servlet-api</artifactId>
+                <version>2.5</version>
+                <scope>provided</scope>
+            </dependency>
+
+            Jetty 7 - Servlet API 2.5 / OSGi bundle ready
+
+            <dependency>
+                <groupId>org.eclipse.jetty.orbit</groupId>
+                <artifactId>javax.servlet</artifactId>
+                <version>2.5.0.v201103041518</version>
+                <scope>provided</scope>
+            </dependency>
+
+            Jetty 8 - Servlet API 3.0 / Standard Location / OSGi bundle ready
+
+            <dependency>
+                <groupId>javax.servlet</groupId>
+                <artifactId>javax.servlet-api</artifactId>
+                <version>3.0.1</version>
+                <scope>provided</scope>
+            </dependency>
+
+            Jetty 9 - Servlet API 3.1 / Standard Location / OSGi bundle ready
+
+            <dependency>
+                <groupId>javax.servlet</groupId>
+                <artifactId>javax.servlet-api</artifactId>
+                <version>3.1.0</version>
+                <scope>provided</scope>
+            </dependency>
+        -->
+
+        <!-- Jetty 8 - Servlet API 3.0 / Standard Location / OSGi bundle ready -->
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+            <version>3.0.1</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <!-- Precompiled DefaultWidgetSet -->
+        <dependency>
+            <groupId>com.vaadin</groupId>
+            <artifactId>vaadin-client-compiled</artifactId>
+            <version>${vaadin.version}</version>
+        </dependency>
+
+        <!-- Vaadin client side, needed for widget set compilation -->
+        <dependency>
+            <groupId>com.vaadin</groupId>
+            <artifactId>vaadin-client</artifactId>
+            <scope>provided</scope>
+            <version>${vaadin.version}</version>
+        </dependency>
+
+        <!-- Compiler for custom widget sets. Should not be deployed -->
+        <dependency>
+            <groupId>com.vaadin</groupId>
+            <artifactId>vaadin-client-compiler</artifactId>
+            <scope>provided</scope>
+            <version>${vaadin.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.vaadin.addon</groupId>
+            <artifactId>jpacontainer</artifactId>
+            <version>3.1.1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.vaadin.addon</groupId>
+            <artifactId>confirmdialog</artifactId>
+            <version>2.0.5</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.openaz</groupId>
+            <artifactId>openaz-xacml</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.openaz</groupId>
+            <artifactId>openaz-xacml-rest</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+            <version>1.2.17</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-logging</groupId>
+            <artifactId>commons-logging</artifactId>
+            <version>1.1.3</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>javax.servlet</groupId>
+                    <artifactId>servlet-api</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-continuation</artifactId>
+            <version>9.0.0.v20130308</version>
+        </dependency>
+        <dependency>
+            <groupId>log4j</groupId>
+            <artifactId>apache-log4j-extras</artifactId>
+            <version>1.2.17</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>2.4</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-compress</artifactId>
+            <version>1.8</version>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+            <version>2.3.0-rc1</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+            <version>14.0.1</version>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jgit</groupId>
+            <artifactId>org.eclipse.jgit</artifactId>
+            <version>3.2.0.201312181205-r</version>
+        </dependency>
+        <dependency>
+            <groupId>com.h2database</groupId>
+            <artifactId>h2</artifactId>
+            <version>1.3.174</version>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <version>5.1.30</version>
+        </dependency>
+        <dependency>
+            <groupId>postgresql</groupId>
+            <artifactId>postgresql</artifactId>
+            <version>9.1-901.jdbc4</version>
+        </dependency>
+        <dependency>
+            <groupId>org.hsqldb</groupId>
+            <artifactId>hsqldb</artifactId>
+            <version>2.3.2</version>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.11</version>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.persistence</groupId>
+            <artifactId>eclipselink</artifactId>
+            <version>2.5.2</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <pluginManagement>
+            <plugins>
+                <plugin>            
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-war-plugin</artifactId>
+                    <configuration>
+                        <webXml>src\main\webapp\WEB-INF\web.xml</webXml>        
+                        <resource>
+                            <directory>src/META-INF</directory>
+                            <targetPath>META-INF</targetPath>
+                            <includes>
+                                <include>persistence.xml</include>
+                                <include>data.sql</include>
+                                <include>drop.sql</include>
+                                <include>empty.sql</include>
+                                <include>views.sql</include>
+                            </includes>
+                        </resource>
+                    </configuration>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+    </build>
+
+
+
+
 </project>
diff --git a/openaz-xacml-pap-admin/src/META-INF/data.sql b/openaz-xacml-pap-admin/src/META-INF/data.sql
new file mode 100644
index 0000000..a679b4d
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/META-INF/data.sql
@@ -0,0 +1,723 @@
+INSERT INTO ConstraintType (id, constraint_type, description) VALUES (1,'Range','Set a range of min and/or max integer/double values the attribute can be set to during policy creation.');
+INSERT INTO ConstraintType (id, constraint_type, description) VALUES (2,'Regular Expression','Define a regular expression the attribute must match against during policy creation.');
+INSERT INTO ConstraintType (id, constraint_type, description) VALUES (3,'Enumeration','Enumerate a set of values that the attribute may be set to during policy creation.');
+
+INSERT INTO Category (id, grouping, is_standard, xacml_id, short_name) VALUES (4,'subject','S','urn:oasis:names:tc:xacml:1.0:subject-category:intermediary-subject','intermediary-subject');
+INSERT INTO Category (id, grouping, is_standard, xacml_id, short_name) VALUES (5,'resource','S','urn:oasis:names:tc:xacml:3.0:attribute-category:resource','resource');
+INSERT INTO Category (id, grouping, is_standard, xacml_id, short_name) VALUES (6,'subject','S','urn:oasis:names:tc:xacml:1.0:subject-category:codebase','codebase');
+INSERT INTO Category (id, grouping, is_standard, xacml_id, short_name) VALUES (7,'action','S','urn:oasis:names:tc:xacml:3.0:attribute-category:action','action');
+INSERT INTO Category (id, grouping, is_standard, xacml_id, short_name) VALUES (8,'subject','S','urn:oasis:names:tc:xacml:1.0:subject-category:access-subject','access-subject');
+INSERT INTO Category (id, grouping, is_standard, xacml_id, short_name) VALUES (9,'environment','S','urn:oasis:names:tc:xacml:3.0:attribute-category:environment','environment');
+INSERT INTO Category (id, grouping, is_standard, xacml_id, short_name) VALUES (10,'subject','S','urn:oasis:names:tc:xacml:1.0:subject-category:requesting-machine','requesting-machine');
+INSERT INTO Category (id, grouping, is_standard, xacml_id, short_name) VALUES (11,'subject','S','urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject','recipient-subject');
+
+INSERT INTO Datatype (id, is_standard, short_name, xacml_id) VALUES (12,'S','integer','http://www.w3.org/2001/XMLSchema#integer');
+INSERT INTO Datatype (id, is_standard, short_name, xacml_id) VALUES (13,'S','base64Binary','http://www.w3.org/2001/XMLSchema#base64Binary');
+INSERT INTO Datatype (id, is_standard, short_name, xacml_id) VALUES (14,'S','x500Name','urn:oasis:names:tc:xacml:1.0:data-type:x500Name');
+INSERT INTO Datatype (id, is_standard, short_name, xacml_id) VALUES (15,'S','dayTimeDuration','http://www.w3.org/2001/XMLSchema#dayTimeDuration');
+INSERT INTO Datatype (id, is_standard, short_name, xacml_id) VALUES (16,'S','time','http://www.w3.org/2001/XMLSchema#time');
+INSERT INTO Datatype (id, is_standard, short_name, xacml_id) VALUES (17,'S','dnsName','urn:oasis:names:tc:xacml:2.0:data-type:dnsName');
+INSERT INTO Datatype (id, is_standard, short_name, xacml_id) VALUES (18,'S','boolean','http://www.w3.org/2001/XMLSchema#boolean');
+INSERT INTO Datatype (id, is_standard, short_name, xacml_id) VALUES (19,'S','dateTime','http://www.w3.org/2001/XMLSchema#dateTime');
+INSERT INTO Datatype (id, is_standard, short_name, xacml_id) VALUES (20,'S','rfc822Name','urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name');
+INSERT INTO Datatype (id, is_standard, short_name, xacml_id) VALUES (21,'S','date','http://www.w3.org/2001/XMLSchema#date');
+INSERT INTO Datatype (id, is_standard, short_name, xacml_id) VALUES (22,'S','ipAddress','urn:oasis:names:tc:xacml:2.0:data-type:ipAddress');
+INSERT INTO Datatype (id, is_standard, short_name, xacml_id) VALUES (23,'S','yearMonthDuration','http://www.w3.org/2001/XMLSchema#yearMonthDuration');
+INSERT INTO Datatype (id, is_standard, short_name, xacml_id) VALUES (24,'S','hexBinary','http://www.w3.org/2001/XMLSchema#hexBinary');
+INSERT INTO Datatype (id, is_standard, short_name, xacml_id) VALUES (25,'S','double','http://www.w3.org/2001/XMLSchema#double');
+INSERT INTO Datatype (id, is_standard, short_name, xacml_id) VALUES (26,'S','string','http://www.w3.org/2001/XMLSchema#string');
+INSERT INTO Datatype (id, is_standard, short_name, xacml_id) VALUES (27,'S','anyURI','http://www.w3.org/2001/XMLSchema#anyURI');
+INSERT INTO Datatype (id, is_standard, short_name, xacml_id) VALUES (28,'S','xpathExpression','urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression');
+
+INSERT INTO PolicyAlgorithms (id, is_standard, short_name, xacml_id) VALUES (29,'S','ordered-deny-overrides','urn:oasis:names:tc:xacml:3.0:policy-combining-algorithm:ordered-deny-overrides');
+INSERT INTO PolicyAlgorithms (id, is_standard, short_name, xacml_id) VALUES (30,'S','on-permit-apply-second','urn:oasis:names:tc:xacml:3.0:policy-combining-algorithm:on-permit-apply-second');
+INSERT INTO PolicyAlgorithms (id, is_standard, short_name, xacml_id) VALUES (31,'S','deny-overrides','urn:oasis:names:tc:xacml:3.0:policy-combining-algorithm:deny-overrides');
+INSERT INTO PolicyAlgorithms (id, is_standard, short_name, xacml_id) VALUES (32,'S','permit-unless-deny','urn:oasis:names:tc:xacml:3.0:policy-combining-algorithm:permit-unless-deny');
+INSERT INTO PolicyAlgorithms (id, is_standard, short_name, xacml_id) VALUES (33,'S','deny-unless-permit','urn:oasis:names:tc:xacml:3.0:policy-combining-algorithm:deny-unless-permit');
+INSERT INTO PolicyAlgorithms (id, is_standard, short_name, xacml_id) VALUES (34,'S','permit-overrides','urn:oasis:names:tc:xacml:3.0:policy-combining-algorithm:permit-overrides');
+INSERT INTO PolicyAlgorithms (id, is_standard, short_name, xacml_id) VALUES (35,'S','only-one-applicable','urn:oasis:names:tc:xacml:1.0:policy-combining-algorithm:only-one-applicable');
+INSERT INTO PolicyAlgorithms (id, is_standard, short_name, xacml_id) VALUES (36,'S','first-applicable','urn:oasis:names:tc:xacml:1.0:policy-combining-algorithm:first-applicable');
+INSERT INTO PolicyAlgorithms (id, is_standard, short_name, xacml_id) VALUES (37,'S','ordered-permit-overrides','urn:oasis:names:tc:xacml:3.0:policy-combining-algorithm:ordered-permit-overrides');
+
+INSERT INTO RuleAlgorithms (id, is_standard, short_name, xacml_id) VALUES (38,'S','permit-unless-deny','urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:permit-unless-deny');
+INSERT INTO RuleAlgorithms (id, is_standard, short_name, xacml_id) VALUES (39,'S','permit-overrides','urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:permit-overrides');
+INSERT INTO RuleAlgorithms (id, is_standard, short_name, xacml_id) VALUES (40,'S','deny-overrides','urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-overrides');
+INSERT INTO RuleAlgorithms (id, is_standard, short_name, xacml_id) VALUES (41,'S','ordered-permit-overrides','urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:ordered-permit-overrides');
+INSERT INTO RuleAlgorithms (id, is_standard, short_name, xacml_id) VALUES (42,'S','deny-unless-permit','urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-unless-permit');
+INSERT INTO RuleAlgorithms (id, is_standard, short_name, xacml_id) VALUES (43,'S','ordered-deny-overrides','urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:ordered-deny-overrides');
+INSERT INTO RuleAlgorithms (id, is_standard, short_name, xacml_id) VALUES (44,'S','only-one-applicable','urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:only-one-applicable');
+INSERT INTO RuleAlgorithms (id, is_standard, short_name, xacml_id) VALUES (45,'S','first-applicable','urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable');
+
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (1,'integer-greater-than-or-equal','urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (2,'integer-subtract','urn:oasis:names:tc:xacml:1.0:function:integer-subtract',12,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (3,'double-to-integer','urn:oasis:names:tc:xacml:1.0:function:double-to-integer',12,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (4,'integer-one-and-only','urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only',12,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (5,'double-one-and-only','urn:oasis:names:tc:xacml:1.0:function:double-one-and-only',25,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (6,'string-equal','urn:oasis:names:tc:xacml:1.0:function:string-equal',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (7,'string-equal-ignore-case','urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (8,'string-starts-with','urn:oasis:names:tc:xacml:3.0:function:string-starts-with',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (9,'string-ends-with','urn:oasis:names:tc:xacml:3.0:function: string-ends-with',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (10,'string-concatenate','urn:oasis:names:tc:xacml:2.0:function:string-concatenate',26,0,0,2,-1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (11,'boolean-from-string','urn:oasis:names:tc:xacml:3.0:function:boolean-from-string',18,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (12,'string-from-boolean','urn:oasis:names:tc:xacml:3.0:function:string-from-boolean',26,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (13,'integer-from-string','urn:oasis:names:tc:xacml:3.0:function:integer-from-string',12,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (14,'string-from-integer','urn:oasis:names:tc:xacml:3.0:function:string-from-integer',26,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (15,'double-from-string','urn:oasis:names:tc:xacml:3.0:function:double-from-string',25,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (16,'string-from-double','urn:oasis:names:tc:xacml:3.0:function:string-from-double',26,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (17,'time-from-string','urn:oasis:names:tc:xacml:3.0:function:time-from-string',16,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (18,'string-from-time','urn:oasis:names:tc:xacml:3.0:function:string-from-time',26,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (19,'date-from-string','urn:oasis:names:tc:xacml:3.0:function:date-from-string',21,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (20,'string-from-date','urn:oasis:names:tc:xacml:3.0:function:string-from-date',26,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (21,'dateTime-from-string','urn:oasis:names:tc:xacml:3.0:function:dateTime-from-string',19,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (22,'string-from-dateTime','urn:oasis:names:tc:xacml:3.0:function:string-from-dateTime',26,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (23,'anyURI-from-string','urn:oasis:names:tc:xacml:3.0:function:anyURI-from-string',27,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (24,'string-from-anyURI','urn:oasis:names:tc:xacml:3.0:function:string-from-anyURI',26,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (25,'dayTimeDuration-from-string','urn:oasis:names:tc:xacml:3.0:function:dayTimeDuration-from-string',15,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (26,'string-from-dayTimeDuration','urn:oasis:names:tc:xacml:3.0:function:string-from-dayTimeDuration',26,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (27,'yearMonthDuration-from-string','urn:oasis:names:tc:xacml:3.0:function:yearMonthDuration-from-string',23,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (28,'string-from-yearMonthDuration','urn:oasis:names:tc:xacml:3.0:function:string-from-yearMonthDuration',26,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (29,'x500Name-from-string','urn:oasis:names:tc:xacml:3.0:function:x500Name-from-string',14,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (30,'string-from-x500Name','urn:oasis:names:tc:xacml:3.0:function:string-from-x500Name',26,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (31,'rfc822Name-from-string','urn:oasis:names:tc:xacml:3.0:function:rfc822Name-from-string',20,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (32,'string-from-rfc822Name','urn:oasis:names:tc:xacml:3.0:function:string-from-rfc822Name',26,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (33,'ipAddress-from-string','urn:oasis:names:tc:xacml:3.0:function:ipAddress-from-string',22,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (34,'string-from-ipAddress','urn:oasis:names:tc:xacml:3.0:function:string-from-ipAddress',26,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (35,'dnsName-from-string','urn:oasis:names:tc:xacml:3.0:function:dnsName-from-string',17,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (36,'string-from-dnsName','urn:oasis:names:tc:xacml:3.0:function:string-from-dnsName',26,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (37,'anyURI-starts-with','urn:oasis:names:tc:xacml:3.0:function:anyURI-starts-with',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (38,'anyURI-ends-with','urn:oasis:names:tc:xacml:3.0:function:anyURI-ends-with',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (39,'string-contains','urn:oasis:names:tc:xacml:3.0:function:string-contains',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (40,'anyURI-contains','urn:oasis:names:tc:xacml:3.0:function:anyURI-contains',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (41,'string-substring','urn:oasis:names:tc:xacml:3.0:function:string-substring',26,0,0,3,3,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (42,'anyURI-substring','urn:oasis:names:tc:xacml:3.0:function:anyURI-substring',26,0,0,3,3,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (43,'boolean-equal','urn:oasis:names:tc:xacml:1.0:function:boolean-equal',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (44,'integer-equal','urn:oasis:names:tc:xacml:1.0:function:integer-equal',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (45,'double-equal','urn:oasis:names:tc:xacml:1.0:function:double-equal',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (46,'date-equal','urn:oasis:names:tc:xacml:1.0:function:date-equal',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (47,'time-equal','urn:oasis:names:tc:xacml:1.0:function:time-equal',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (48,'dateTime-equal','urn:oasis:names:tc:xacml:1.0:function:dateTime-equal',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (49,'dayTimeDuration-equal','urn:oasis:names:tc:xacml:3.0:function:dayTimeDuration-equal',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (50,'yearMonthDuration-equal','urn:oasis:names:tc:xacml:3.0:function:yearMonthDuration-equal',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (51,'anyURI-equal','urn:oasis:names:tc:xacml:1.0:function:anyURI-equal',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (52,'x500Name-equal','urn:oasis:names:tc:xacml:1.0:function:x500Name-equal',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (53,'rfc822Name-equal','urn:oasis:names:tc:xacml:1.0:function:rfc822Name-equal',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (54,'hexBinary-equal','urn:oasis:names:tc:xacml:1.0:function:hexBinary-equal',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (55,'base64Binary-equal','urn:oasis:names:tc:xacml:1.0:function:base64Binary-equal',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (56,'integer-add','urn:oasis:names:tc:xacml:1.0:function:integer-add',12,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (57,'double-add','urn:oasis:names:tc:xacml:1.0:function:double-add',25,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (58,'double-subtract','urn:oasis:names:tc:xacml:1.0:function:double-subtract',25,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (59,'integer-multiply','urn:oasis:names:tc:xacml:1.0:function:integer-multiply',12,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (60,'double-multiply','urn:oasis:names:tc:xacml:1.0:function:double-multiply',25,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (61,'integer-divide','urn:oasis:names:tc:xacml:1.0:function:integer-divide',12,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (62,'double-divide','urn:oasis:names:tc:xacml:1.0:function:double-divide',25,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (63,'integer-mod','urn:oasis:names:tc:xacml:1.0:function:integer-mod',12,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (64,'integer-abs','urn:oasis:names:tc:xacml:1.0:function:integer-abs',12,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (65,'double-abs','urn:oasis:names:tc:xacml:1.0:function:double-abs',25,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (66,'round','urn:oasis:names:tc:xacml:1.0:function:round',25,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (67,'floor','urn:oasis:names:tc:xacml:1.0:function:floor',25,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (68,'string-normalize-space','urn:oasis:names:tc:xacml:1.0:function:string-normalize-space',26,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (69,'string-normalize-to-lower-case','urn:oasis:names:tc:xacml:1.0:function:string-normalize-to-lower-case',26,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (70,'integer-to-double','urn:oasis:names:tc:xacml:1.0:function:integer-to-double',25,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (71,'integer-greater-than','urn:oasis:names:tc:xacml:1.0:function:integer-greater-than',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (72,'integer-less-than','urn:oasis:names:tc:xacml:1.0:function:integer-less-than',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (73,'integer-less-than-or-equal','urn:oasis:names:tc:xacml:1.0:function:integer-less-than-or-equal',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (74,'double-greater-than','urn:oasis:names:tc:xacml:1.0:function:double-greater-than',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (75,'double-greater-than-or-equal','urn:oasis:names:tc:xacml:1.0:function:double-greater-than-or-equal',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (76,'double-less-than','urn:oasis:names:tc:xacml:1.0:function:double-less-than',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (77,'double-less-than-or-equal','urn:oasis:names:tc:xacml:1.0:function:double-less-than-or-equal',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (78,'dateTime-add-dayTimeDuration','urn:oasis:names:tc:xacml:3.0:function:dateTime-add-dayTimeDuration',19,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (79,'dateTime-add-yearMonthDuration','urn:oasis:names:tc:xacml:3.0:function:dateTime-add-yearMonthDuration',19,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (80,'dateTime-subtract-dayTimeDuration','urn:oasis:names:tc:xacml:3.0:function:dateTime-subtract-dayTimeDuration',19,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (81,'dateTime-subtract-yearMonthDuration','urn:oasis:names:tc:xacml:3.0:function:dateTime-subtract-yearMonthDuration',19,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (82,'date-add-yearMonthDuration','urn:oasis:names:tc:xacml:3.0:function:date-add-yearMonthDuration',21,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (83,'date-subtract-yearMonthDuration','urn:oasis:names:tc:xacml:3.0:function:date-subtract-yearMonthDuration',21,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (84,'string-greater-than','urn:oasis:names:tc:xacml:1.0:function:string-greater-than',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (85,'string-greater-than-or-equal','urn:oasis:names:tc:xacml:1.0:function:string-greater-than-or-equal',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (86,'string-less-than','urn:oasis:names:tc:xacml:1.0:function:string-less-than',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (87,'string-less-than-or-equal','urn:oasis:names:tc:xacml:1.0:function:string-less-than-or-equal',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (88,'time-greater-than','urn:oasis:names:tc:xacml:1.0:function:time-greater-than',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (89,'time-greater-than-or-equal','urn:oasis:names:tc:xacml:1.0:function:time-greater-than-or-equal',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (90,'time-less-than','urn:oasis:names:tc:xacml:1.0:function:time-less-than',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (91,'time-less-than-or-equal','urn:oasis:names:tc:xacml:1.0:function:time-less-than-or-equal',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (92,'time-in-range','urn:oasis:names:tc:xacml:2.0:function:time-in-range',18,0,0,3,3,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (93,'dateTime-greater-than','urn:oasis:names:tc:xacml:1.0:function:dateTime-greater-than',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (94,'dateTime-greater-than-or-equal','urn:oasis:names:tc:xacml:1.0:function:dateTime-greater-than-or-equal',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (95,'dateTime-less-than','urn:oasis:names:tc:xacml:1.0:function:dateTime-less-than',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (96,'dateTime-less-than-or-equal','urn:oasis:names:tc:xacml:1.0:function:dateTime-less-than-or-equal',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (97,'date-greater-than','urn:oasis:names:tc:xacml:1.0:function:date-greater-than',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (98,'date-greater-than-or-equal','urn:oasis:names:tc:xacml:1.0:function:date-greater-than-or-equal',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (99,'date-less-than','urn:oasis:names:tc:xacml:1.0:function:date-less-than',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (100,'date-less-than-or-equal','urn:oasis:names:tc:xacml:1.0:function:date-less-than-or-equal',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (101,'string-one-and-only','urn:oasis:names:tc:xacml:1.0:function:string-one-and-only',26,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (102,'string-bag-size','urn:oasis:names:tc:xacml:1.0:function:string-bag-size',12,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (103,'string-is-in','urn:oasis:names:tc:xacml:1.0:function:string-is-in',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (104,'string-bag','urn:oasis:names:tc:xacml:1.0:function:string-bag',26,1,0,1,-1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (105,'integer-bag-size','urn:oasis:names:tc:xacml:1.0:function:integer-bag-size',12,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (106,'integer-is-in','urn:oasis:names:tc:xacml:1.0:function:integer-is-in',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (107,'integer-bag','urn:oasis:names:tc:xacml:1.0:function:integer-bag',12,1,0,1,-1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (108,'double-bag-size','urn:oasis:names:tc:xacml:1.0:function:double-bag-size',12,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (109,'double-is-in','urn:oasis:names:tc:xacml:1.0:function:double-is-in',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (110,'double-bag','urn:oasis:names:tc:xacml:1.0:function:double-bag',25,1,0,1,-1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (111,'boolean-one-and-only','urn:oasis:names:tc:xacml:1.0:function:boolean-one-and-only',18,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (112,'boolean-bag-size','urn:oasis:names:tc:xacml:1.0:function:boolean-bag-size',12,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (113,'boolean-is-in','urn:oasis:names:tc:xacml:1.0:function:boolean-is-in',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (114,'boolean-bag','urn:oasis:names:tc:xacml:1.0:function:boolean-bag',18,1,0,1,-1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (115,'time-one-and-only','urn:oasis:names:tc:xacml:1.0:function:time-one-and-only',16,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (116,'time-bag-size','urn:oasis:names:tc:xacml:1.0:function:time-bag-size',12,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (117,'time-is-in','urn:oasis:names:tc:xacml:1.0:function:time-is-in',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (118,'time-bag','urn:oasis:names:tc:xacml:1.0:function:time-bag',16,1,0,1,-1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (119,'date-one-and-only','urn:oasis:names:tc:xacml:1.0:function:date-one-and-only',21,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (120,'date-bag-size','urn:oasis:names:tc:xacml:1.0:function:date-bag-size',12,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (121,'date-is-in','urn:oasis:names:tc:xacml:1.0:function:date-is-in',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (122,'date-bag','urn:oasis:names:tc:xacml:1.0:function:date-bag',21,1,0,1,-1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (123,'dateTime-one-and-only','urn:oasis:names:tc:xacml:1.0:function:dateTime-one-and-only',19,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (124,'dateTime-bag-size','urn:oasis:names:tc:xacml:1.0:function:dateTime-bag-size',12,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (125,'dateTime-is-in','urn:oasis:names:tc:xacml:1.0:function:dateTime-is-in',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (126,'dateTime-bag','urn:oasis:names:tc:xacml:1.0:function:dateTime-bag',19,1,0,1,-1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (127,'anyURI-one-and-only','urn:oasis:names:tc:xacml:1.0:function:anyURI-one-and-only',27,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (128,'anyURI-bag-size','urn:oasis:names:tc:xacml:1.0:function:anyURI-bag-size',12,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (129,'anyURI-is-in','urn:oasis:names:tc:xacml:1.0:function:anyURI-is-in',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (130,'anyURI-bag','urn:oasis:names:tc:xacml:1.0:function:anyURI-bag',27,1,0,1,-1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (131,'hexBinary-one-and-only','urn:oasis:names:tc:xacml:1.0:function:hexBinary-one-and-only',24,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (132,'hexBinary-bag-size','urn:oasis:names:tc:xacml:1.0:function:hexBinary-bag-size',12,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (133,'hexBinary-is-in','urn:oasis:names:tc:xacml:1.0:function:hexBinary-is-in',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (134,'hexBinary-bag','urn:oasis:names:tc:xacml:1.0:function:hexBinary-bag',24,1,0,1,-1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (135,'base64Binary-one-and-only','urn:oasis:names:tc:xacml:1.0:function:base64Binary-one-and-only',13,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (136,'base64Binary-bag-size','urn:oasis:names:tc:xacml:1.0:function:base64Binary-bag-size',12,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (137,'base64Binary-is-in','urn:oasis:names:tc:xacml:1.0:function:base64Binary-is-in',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (138,'base64Binary-bag','urn:oasis:names:tc:xacml:1.0:function:base64Binary-bag',13,1,0,1,-1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (139,'dayTimeDuration-one-and-only','urn:oasis:names:tc:xacml:3.0:function:dayTimeDuration-one-and-only',15,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (140,'dayTimeDuration-bag-size','urn:oasis:names:tc:xacml:3.0:function:dayTimeDuration-bag-size',12,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (141,'dayTimeDuration-is-in','urn:oasis:names:tc:xacml:3.0:function:dayTimeDuration-is-in',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (142,'dayTimeDuration-bag','urn:oasis:names:tc:xacml:3.0:function:dayTimeDuration-bag',15,1,0,1,-1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (143,'yearMonthDuration-one-and-only','urn:oasis:names:tc:xacml:3.0:function:yearMonthDuration-one-and-only',23,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (144,'yearMonthDuration-bag-size','urn:oasis:names:tc:xacml:3.0:function:yearMonthDuration-bag-size',12,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (145,'yearMonthDuration-is-in','urn:oasis:names:tc:xacml:3.0:function:yearMonthDuration-is-in',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (146,'yearMonthDuration-bag','urn:oasis:names:tc:xacml:3.0:function:yearMonthDuration-bag',23,1,0,1,-1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (147,'x500Name-one-and-only','urn:oasis:names:tc:xacml:1.0:function:x500Name-one-and-only',14,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (148,'x500Name-bag-size','urn:oasis:names:tc:xacml:1.0:function:x500Name-bag-size',12,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (149,'x500Name-is-in','urn:oasis:names:tc:xacml:1.0:function:x500Name-is-in',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (150,'x500Name-bag','urn:oasis:names:tc:xacml:1.0:function:x500Name-bag',14,1,0,1,-1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (151,'rfc822Name-one-and-only','urn:oasis:names:tc:xacml:1.0:function:rfc822Name-one-and-only',20,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (152,'rfc822Name-bag-size','urn:oasis:names:tc:xacml:1.0:function:rfc822Name-bag-size',12,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (153,'rfc822Name-is-in','urn:oasis:names:tc:xacml:1.0:function:rfc822Name-is-in',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (154,'rfc822Name-bag','urn:oasis:names:tc:xacml:1.0:function:rfc822Name-bag',20,1,0,1,-1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (155,'ipAddress-one-and-only','urn:oasis:names:tc:xacml:2.0:function:ipAddress-one-and-only',22,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (156,'ipAddress-bag-size','urn:oasis:names:tc:xacml:2.0:function:ipAddress-bag-size',12,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (157,'ipAddress-is-in','urn:oasis:names:tc:xacml:2.0:function:ipAddress-is-in',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (158,'ipAddress-bag','urn:oasis:names:tc:xacml:2.0:function:ipAddress-bag',22,1,0,1,-1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (159,'dnsName-one-and-only','urn:oasis:names:tc:xacml:2.0:function:dnsName-one-and-only',17,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (160,'dnsName-bag-size','urn:oasis:names:tc:xacml:2.0:function:dnsName-bag-size',12,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (161,'dnsName-is-in','urn:oasis:names:tc:xacml:2.0:function:dnsName-is-in',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (162,'dnsName-bag','urn:oasis:names:tc:xacml:2.0:function:dnsName-bag',17,1,0,1,-1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (163,'string-regexp-match','urn:oasis:names:tc:xacml:1.0:function:string-regexp-match',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (164,'anyURI-regexp-match','urn:oasis:names:tc:xacml:2.0:function:anyURI-regexp-match',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (165,'ipAddress-regexp-match','urn:oasis:names:tc:xacml:2.0:function:ipAddress-regexp-match',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (166,'dnsName-regexp-match','urn:oasis:names:tc:xacml:2.0:function:dnsName-regexp-match',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (167,'rfc822Name-regexp-match','urn:oasis:names:tc:xacml:2.0:function:rfc822Name-regexp-match',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (168,'x500Name-regexp-match','urn:oasis:names:tc:xacml:2.0:function:x500Name-regexp-match',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (169,'string-intersection','urn:oasis:names:tc:xacml:1.0:function:string-intersection',26,1,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (170,'string-at-least-one-member-of','urn:oasis:names:tc:xacml:1.0:function:string-at-least-one-member-of',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (171,'string-union','urn:oasis:names:tc:xacml:1.0:function:string-union',26,1,0,2,-1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (172,'string-subset','urn:oasis:names:tc:xacml:1.0:function:string-subset',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (173,'string-set-equals','urn:oasis:names:tc:xacml:1.0:function:string-set-equals',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (174,'integer-at-least-one-member-of','urn:oasis:names:tc:xacml:1.0:function:integer-at-least-one-member-of',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (175,'integer-union','urn:oasis:names:tc:xacml:1.0:function:integer-union',12,1,0,2,-1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (176,'integer-subset','urn:oasis:names:tc:xacml:1.0:function:integer-subset',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (177,'integer-set-equals','urn:oasis:names:tc:xacml:1.0:function:integer-set-equals',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (178,'double-at-least-one-member-of','urn:oasis:names:tc:xacml:1.0:function:double-at-least-one-member-of',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (179,'double-union','urn:oasis:names:tc:xacml:1.0:function:double-union',25,1,0,2,-1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (180,'double-subset','urn:oasis:names:tc:xacml:1.0:function:double-subset',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (181,'double-set-equals','urn:oasis:names:tc:xacml:1.0:function:double-set-equals',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (182,'boolean-intersection','urn:oasis:names:tc:xacml:1.0:function:boolean-intersection',18,1,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (183,'boolean-at-least-one-member-of','urn:oasis:names:tc:xacml:1.0:function:boolean-at-least-one-member-of',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (184,'boolean-union','urn:oasis:names:tc:xacml:1.0:function:boolean-union',18,1,0,2,-1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (185,'boolean-subset','urn:oasis:names:tc:xacml:1.0:function:boolean-subset',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (186,'boolean-set-equals','urn:oasis:names:tc:xacml:1.0:function:boolean-set-equals',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (187,'time-intersection','urn:oasis:names:tc:xacml:1.0:function:time-intersection',16,1,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (188,'time-at-least-one-member-of','urn:oasis:names:tc:xacml:1.0:function:time-at-least-one-member-of',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (189,'time-union','urn:oasis:names:tc:xacml:1.0:function:time-union',16,1,0,2,-1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (190,'time-subset','urn:oasis:names:tc:xacml:1.0:function:time-subset',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (191,'time-set-equals','urn:oasis:names:tc:xacml:1.0:function:time-set-equals',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (192,'date-intersection','urn:oasis:names:tc:xacml:1.0:function:date-intersection',21,1,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (193,'date-at-least-one-member-of','urn:oasis:names:tc:xacml:1.0:function:date-at-least-one-member-of',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (194,'date-union','urn:oasis:names:tc:xacml:1.0:function:date-union',21,1,0,2,-1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (195,'date-subset','urn:oasis:names:tc:xacml:1.0:function:date-subset',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (196,'date-set-equals','urn:oasis:names:tc:xacml:1.0:function:date-set-equals',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (197,'dateTime-intersection','urn:oasis:names:tc:xacml:1.0:function:dateTime-intersection',19,1,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (198,'dateTime-at-least-one-member-of','urn:oasis:names:tc:xacml:1.0:function:dateTime-at-least-one-member-of',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (199,'dateTime-union','urn:oasis:names:tc:xacml:1.0:function:dateTime-union',19,1,0,2,-1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (200,'dateTime-subset','urn:oasis:names:tc:xacml:1.0:function:dateTime-subset',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (201,'dateTime-set-equals','urn:oasis:names:tc:xacml:1.0:function:dateTime-set-equals',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (202,'anyURI-intersection','urn:oasis:names:tc:xacml:1.0:function:anyURI-intersection',27,1,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (203,'anyURI-at-least-one-member-of','urn:oasis:names:tc:xacml:1.0:function:anyURI-at-least-one-member-of',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (204,'anyURI-union','urn:oasis:names:tc:xacml:1.0:function:anyURI-union',27,1,0,2,-1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (205,'anyURI-subset','urn:oasis:names:tc:xacml:1.0:function:anyURI-subset',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (206,'anyURI-set-equals','urn:oasis:names:tc:xacml:1.0:function:anyURI-set-equals',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (207,'hexBinary-intersection','urn:oasis:names:tc:xacml:1.0:function:hexBinary-intersection',24,1,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (208,'hexBinary-at-least-one-member-of','urn:oasis:names:tc:xacml:1.0:function:hexBinary-at-least-one-member-of',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (209,'hexBinary-union','urn:oasis:names:tc:xacml:1.0:function:hexBinary-union',24,1,0,2,-1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (210,'hexBinary-subset','urn:oasis:names:tc:xacml:1.0:function:hexBinary-subset',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (211,'hexBinary-set-equals','urn:oasis:names:tc:xacml:1.0:function:hexBinary-set-equals',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (212,'base64Binary-intersection','urn:oasis:names:tc:xacml:1.0:function:base64Binary-intersection',13,1,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (213,'base64Binary-at-least-one-member-of','urn:oasis:names:tc:xacml:1.0:function:base64Binary-at-least-one-member-of',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (214,'base64Binary-union','urn:oasis:names:tc:xacml:1.0:function:base64Binary-union',13,1,0,2,-1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (215,'base64Binary-subset','urn:oasis:names:tc:xacml:1.0:function:base64Binary-subset',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (216,'base64Binary-set-equals','urn:oasis:names:tc:xacml:1.0:function:base64Binary-set-equals',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (217,'dayTimeDuration-intersection','urn:oasis:names:tc:xacml:3.0:function:dayTimeDuration-intersection',15,1,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (218,'dayTimeDuration-at-least-one-member-of','urn:oasis:names:tc:xacml:3.0:function:dayTimeDuration-at-least-one-member-of',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (219,'dayTimeDuration-union','urn:oasis:names:tc:xacml:3.0:function:dayTimeDuration-union',15,1,0,2,-1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (220,'dayTimeDuration-subset','urn:oasis:names:tc:xacml:3.0:function:dayTimeDuration-subset',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (221,'dayTimeDuration-set-equals','urn:oasis:names:tc:xacml:3.0:function:dayTimeDuration-set-equals',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (222,'yearMonthDuration-intersection','urn:oasis:names:tc:xacml:3.0:function:yearMonthDuration-intersection',23,1,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (223,'yearMonthDuration-at-least-one-member-of','urn:oasis:names:tc:xacml:3.0:function:yearMonthDuration-at-least-one-member-of',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (224,'yearMonthDuration-union','urn:oasis:names:tc:xacml:3.0:function:yearMonthDuration-union',23,1,0,2,-1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (225,'yearMonthDuration-subset','urn:oasis:names:tc:xacml:3.0:function:yearMonthDuration-subset',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (226,'yearMonthDuration-set-equals','urn:oasis:names:tc:xacml:3.0:function:yearMonthDuration-set-equals',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (227,'x500Name-intersection','urn:oasis:names:tc:xacml:1.0:function:x500Name-intersection',14,1,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (228,'x500Name-at-least-one-member-of','urn:oasis:names:tc:xacml:1.0:function:x500Name-at-least-one-member-of',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (229,'x500Name-union','urn:oasis:names:tc:xacml:1.0:function:x500Name-union',14,1,0,2,-1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (230,'x500Name-subset','urn:oasis:names:tc:xacml:1.0:function:x500Name-subset',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (231,'x500Name-set-equals','urn:oasis:names:tc:xacml:1.0:function:x500Name-set-equals',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (232,'rfc822Name-intersection','urn:oasis:names:tc:xacml:1.0:function:rfc822Name-intersection',20,1,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (233,'rfc822Name-at-least-one-member-of','urn:oasis:names:tc:xacml:1.0:function:rfc822Name-at-least-one-member-of',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (234,'rfc822Name-union','urn:oasis:names:tc:xacml:1.0:function:rfc822Name-union',20,1,0,2,-1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (235,'rfc822Name-subset','urn:oasis:names:tc:xacml:1.0:function:rfc822Name-subset',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (236,'rfc822Name-set-equals','urn:oasis:names:tc:xacml:1.0:function:rfc822Name-set-equals',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (237,'x500Name-match','urn:oasis:names:tc:xacml:1.0:function:x500Name-match',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (238,'rfc822Name-match','urn:oasis:names:tc:xacml:1.0:function:rfc822Name-match',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (239,'integer-intersection','urn:oasis:names:tc:xacml:1.0:function:integer-intersection',12,1,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (240,'double-intersection','urn:oasis:names:tc:xacml:1.0:function:double-intersection',25,1,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (241,'or','urn:oasis:names:tc:xacml:1.0:function:or',18,0,0,0,-1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (242,'and','urn:oasis:names:tc:xacml:1.0:function:and',18,0,0,0,-1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (243,'n-of','urn:oasis:names:tc:xacml:1.0:function:n-of',18,0,0,2,-1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (244,'not','urn:oasis:names:tc:xacml:1.0:function:not',18,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (245,'any-of','urn:oasis:names:tc:xacml:3.0:function:any-of',18,0,1,2,-1,1,-1,1);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (246,'all-of','urn:oasis:names:tc:xacml:3.0:function:all-of',18,0,1,2,-1,1,-1,1);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (247,'any-of-any','urn:oasis:names:tc:xacml:3.0:function:any-of-any',18,0,1,2,-1,1,-1,0);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (248,'all-of-any','urn:oasis:names:tc:xacml:1.0:function:all-of-any',18,0,1,3,3,2,2,1);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (249,'any-of-all','urn:oasis:names:tc:xacml:1.0:function:any-of-all',18,0,1,3,3,2,2,1);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (250,'all-of-all','urn:oasis:names:tc:xacml:1.0:function:all-of-all',18,0,1,3,3,2,2,1);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (251,'map','urn:oasis:names:tc:xacml:3.0:function:map',NULL,1,1,2,-1,1,-1,1);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (252,'xpath-node-count','urn:oasis:names:tc:xacml:3.0:function:xpath-node-count',12,0,0,1,1,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (253,'xpath-node-equal','urn:oasis:names:tc:xacml:3.0:function:xpath-node-equal',18,0,0,2,2,NULL,NULL,NULL);
+INSERT INTO FunctionDefinition (id, short_name, xacml_id, return_datatype, is_bag_return, is_higher_order, arg_lb, arg_ub, ho_arg_lb, ho_arg_ub, ho_primitive) VALUES (254,'xpath-node-match','urn:oasis:names:tc:xacml:3.0:function:xpath-node-match',18,0,0,2,2,NULL,NULL,NULL);
+
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (1,0,1,1,12);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (2,0,1,2,12);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (3,0,2,1,12);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (4,0,2,2,12);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (5,0,3,1,25);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (6,1,4,1,12);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (7,1,5,1,25);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (8,0,6,1,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (9,0,6,2,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (10,0,7,1,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (11,0,7,2,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (12,0,8,1,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (13,0,8,2,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (14,0,9,1,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (15,0,9,2,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (16,0,10,1,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (17,0,11,1,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (18,0,12,1,18);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (19,0,13,1,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (20,0,14,1,12);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (21,0,15,1,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (22,0,16,1,25);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (23,0,17,1,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (24,0,18,1,16);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (25,0,19,1,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (26,0,20,1,21);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (27,0,21,1,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (28,0,22,1,19);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (29,0,23,1,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (30,0,24,1,27);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (31,0,25,1,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (32,0,26,1,15);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (33,0,27,1,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (34,0,28,1,23);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (35,0,29,1,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (36,0,30,1,14);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (37,0,31,1,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (38,0,32,1,20);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (39,0,33,1,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (40,0,34,1,22);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (41,0,35,1,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (42,0,36,1,17);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (43,0,37,2,27);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (44,0,37,1,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (45,0,38,1,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (46,0,38,2,27);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (47,0,39,1,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (48,0,39,2,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (49,0,40,1,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (50,0,40,2,27);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (51,0,41,1,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (52,0,41,2,12);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (53,0,41,3,12);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (54,0,42,1,27);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (55,0,42,2,12);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (56,0,42,3,12);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (57,0,43,1,18);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (58,0,43,2,18);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (59,0,44,1,12);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (60,0,44,2,12);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (61,0,45,1,25);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (62,0,45,2,25);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (63,0,46,1,21);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (64,0,46,2,21);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (65,0,47,1,16);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (66,0,47,2,16);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (67,0,48,1,19);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (68,0,48,2,19);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (69,0,49,1,15);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (70,0,49,2,15);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (71,0,50,1,23);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (72,0,50,2,23);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (73,0,51,1,27);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (74,0,51,2,27);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (75,0,52,1,14);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (76,0,52,2,14);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (77,0,53,1,20);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (78,0,53,2,20);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (79,0,54,1,24);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (80,0,54,2,24);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (81,0,55,1,13);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (82,0,55,2,13);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (83,0,56,1,12);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (84,0,56,2,12);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (85,0,57,1,25);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (86,0,57,2,25);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (89,0,58,1,25);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (90,0,58,2,25);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (91,0,59,1,12);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (92,0,59,2,12);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (93,0,60,1,25);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (94,0,60,2,25);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (95,0,61,1,12);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (96,0,61,2,12);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (97,0,62,1,25);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (98,0,62,2,25);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (99,0,63,1,12);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (100,0,63,2,12);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (101,0,64,1,12);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (102,0,65,1,25);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (103,0,66,1,25);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (104,0,67,1,25);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (125,0,68,1,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (126,0,69,1,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (128,0,70,1,12);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (129,0,71,1,12);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (130,0,71,2,12);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (131,0,72,1,12);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (132,0,72,2,12);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (133,0,73,1,12);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (134,0,73,2,12);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (135,0,74,1,25);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (136,0,74,2,25);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (137,0,75,1,25);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (138,0,75,2,25);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (139,0,76,1,25);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (140,0,76,2,25);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (141,0,77,1,25);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (142,0,77,2,25);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (143,0,78,1,19);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (144,0,78,2,15);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (145,0,79,1,19);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (146,0,79,2,23);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (147,0,80,1,19);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (148,0,80,2,15);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (149,0,81,1,19);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (150,0,81,2,23);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (151,0,82,1,21);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (152,0,82,2,23);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (153,0,83,1,21);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (154,0,83,2,23);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (155,0,84,1,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (156,0,84,2,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (157,0,85,1,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (158,0,85,2,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (159,0,86,1,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (160,0,86,2,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (161,0,87,1,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (162,0,87,2,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (163,0,88,1,16);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (164,0,88,2,16);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (165,0,89,1,16);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (166,0,89,2,16);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (167,0,90,1,16);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (168,0,90,2,16);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (169,0,91,1,16);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (170,0,91,2,16);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (171,0,92,1,16);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (172,0,92,2,16);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (173,0,93,1,19);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (174,0,93,2,19);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (175,0,94,1,19);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (176,0,94,2,19);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (177,0,95,1,19);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (178,0,95,2,19);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (179,0,96,1,19);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (180,0,96,2,19);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (181,0,97,1,21);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (182,0,97,2,21);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (183,0,98,1,21);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (184,0,98,2,21);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (185,0,99,2,21);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (186,0,99,1,21);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (187,0,100,2,21);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (188,0,100,1,21);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (189,1,101,1,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (190,1,102,1,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (191,0,103,1,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (192,1,103,2,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (193,0,104,1,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (194,1,105,1,12);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (195,0,106,1,12);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (196,1,106,2,12);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (197,0,107,1,12);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (198,1,108,1,25);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (199,0,109,1,25);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (200,1,109,2,25);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (201,0,110,1,25);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (202,1,111,1,18);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (203,1,112,1,18);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (204,0,113,1,18);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (205,1,113,2,18);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (206,0,114,1,18);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (207,1,115,1,16);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (208,1,116,1,16);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (209,0,117,1,16);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (210,1,117,2,16);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (211,0,118,1,16);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (212,1,119,1,21);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (213,1,120,1,21);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (214,0,121,1,21);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (215,1,121,2,21);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (216,0,122,1,21);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (217,1,123,1,19);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (218,1,124,1,19);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (219,0,125,1,19);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (220,1,125,2,19);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (221,0,126,1,19);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (222,1,127,1,27);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (223,1,128,1,27);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (224,0,129,1,27);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (225,1,129,2,27);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (226,0,130,1,27);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (227,1,131,1,24);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (228,1,132,1,24);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (229,0,133,1,24);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (230,1,133,2,24);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (231,0,134,1,24);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (232,1,135,1,13);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (233,1,136,1,13);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (234,0,137,1,13);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (235,1,137,2,13);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (236,0,138,1,13);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (237,1,139,1,15);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (238,1,140,1,15);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (239,0,141,1,15);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (240,1,141,2,15);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (241,0,142,1,15);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (242,1,143,1,23);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (243,1,144,1,23);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (244,1,145,2,23);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (245,0,145,1,23);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (246,0,146,1,23);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (247,1,147,1,14);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (248,1,148,1,14);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (249,0,149,1,14);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (250,1,149,2,14);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (251,0,150,1,14);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (252,1,151,1,20);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (253,1,152,1,20);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (254,0,153,1,20);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (255,1,153,2,20);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (256,0,154,1,20);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (257,1,155,1,22);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (258,1,156,1,22);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (259,0,157,1,22);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (260,1,157,2,22);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (261,0,158,1,22);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (262,1,159,1,17);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (263,1,160,1,17);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (264,0,161,1,17);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (265,1,161,2,17);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (266,0,162,1,17);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (267,0,163,1,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (268,0,163,2,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (269,0,164,1,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (270,0,164,2,27);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (271,0,165,1,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (272,0,165,2,22);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (273,0,166,1,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (274,0,166,2,17);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (275,0,167,1,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (276,0,167,2,20);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (277,0,168,1,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (278,0,168,2,14);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (279,1,169,1,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (280,1,169,2,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (281,1,170,1,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (282,1,170,2,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (283,1,171,1,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (284,1,172,1,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (285,1,172,2,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (286,1,173,1,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (287,1,173,2,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (288,1,174,2,12);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (289,1,174,1,12);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (290,1,175,1,12);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (292,1,176,2,12);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (293,1,176,1,12);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (294,1,177,2,12);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (295,1,177,1,12);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (296,1,178,1,25);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (297,1,178,2,25);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (298,1,179,1,25);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (299,1,180,1,25);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (300,1,180,2,25);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (301,1,181,1,25);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (302,1,181,2,25);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (303,1,182,1,18);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (304,1,182,2,18);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (305,1,183,1,18);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (306,1,183,2,18);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (307,1,184,1,18);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (308,1,185,1,18);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (309,1,185,2,18);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (310,1,186,1,18);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (311,1,186,2,18);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (312,1,187,2,16);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (313,1,187,1,16);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (314,1,188,1,16);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (315,1,188,2,16);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (316,1,189,1,16);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (317,1,190,1,16);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (318,1,190,2,16);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (319,1,191,1,16);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (320,1,191,2,16);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (321,1,192,1,21);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (322,1,192,2,21);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (323,1,193,1,21);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (324,1,193,2,21);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (325,1,194,1,21);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (326,1,195,1,21);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (327,1,195,2,21);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (328,1,196,1,21);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (329,1,196,2,21);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (330,1,197,1,19);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (331,1,197,2,19);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (332,1,198,1,19);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (333,1,198,2,19);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (334,1,199,1,19);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (335,1,200,1,19);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (336,1,200,2,19);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (337,1,201,1,19);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (338,1,201,2,19);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (339,1,202,1,27);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (340,1,202,2,27);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (341,1,203,1,27);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (342,1,203,2,27);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (343,1,204,1,27);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (344,1,205,1,27);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (345,1,205,2,27);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (346,1,206,1,27);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (347,1,206,2,27);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (348,1,207,1,24);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (349,1,207,2,24);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (350,1,208,1,24);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (351,1,208,2,24);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (352,1,209,1,24);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (353,1,210,1,24);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (354,1,210,2,24);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (355,1,211,1,24);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (356,1,211,2,24);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (357,1,212,1,13);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (358,1,212,2,13);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (359,1,213,1,13);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (360,1,213,2,13);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (361,1,214,1,13);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (362,1,215,1,13);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (363,1,215,2,13);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (364,1,216,1,13);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (365,1,216,2,13);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (366,1,217,1,15);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (367,1,217,2,15);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (368,1,218,1,15);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (369,1,218,2,15);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (370,1,219,1,15);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (371,1,220,1,15);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (372,1,220,2,15);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (373,1,221,1,15);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (374,1,221,2,15);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (375,1,222,1,23);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (376,1,222,2,23);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (377,1,223,1,23);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (378,1,223,2,23);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (380,1,224,1,23);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (381,1,225,1,23);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (382,1,225,2,23);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (383,1,226,2,23);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (384,1,226,1,23);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (385,1,227,1,14);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (386,1,227,2,14);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (387,1,228,1,14);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (388,1,228,2,14);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (389,1,229,1,14);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (390,1,230,1,14);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (391,1,230,2,14);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (392,1,231,1,14);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (393,1,231,2,14);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (394,1,232,1,20);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (395,1,232,2,20);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (396,1,233,1,20);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (397,1,233,2,20);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (398,1,234,1,20);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (399,1,235,1,20);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (400,1,235,2,20);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (401,1,236,1,20);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (402,1,236,2,20);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (403,0,237,1,14);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (404,0,237,2,14);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (405,0,238,1,26);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (406,0,238,2,20);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (407,1,239,1,12);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (408,1,239,2,12);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (409,1,240,1,25);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (410,1,240,2,25);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (411,0,241,1,18);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (412,0,242,1,18);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (413,0,243,1,12);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (414,0,243,2,18);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (415,0,244,1,18);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (416,0,245,1,18);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (417,0,245,2,NULL);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (418,1,245,3,NULL);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (419,0,246,1,18);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (420,0,246,2,NULL);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (421,1,246,3,NULL);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (422,0,247,1,18);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (423,1,247,2,NULL);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (424,1,247,3,NULL);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (433,0,248,1,18);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (434,1,248,2,NULL);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (435,1,248,3,NULL);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (436,0,249,1,18);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (437,1,249,2,NULL);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (438,1,249,3,NULL);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (439,0,250,1,18);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (440,1,250,2,NULL);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (441,1,250,3,NULL);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (442,0,251,1,NULL);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (447,1,251,2,NULL);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (448,0,252,1,28);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (449,0,253,1,28);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (450,0,253,2,28);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (451,0,254,1,28);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (452,0,254,2,28);
+INSERT INTO FunctionArguments (id, is_bag, function_id, arg_index, datatype_id) VALUES (453,0,92,3,16);
+
+INSERT INTO PIPType VALUES (500,'SQL'), (501,'LDAP'), (502,'CSV'), (503,'Hyper-CSV'), (504,'Custom');
diff --git a/openaz-xacml-pap-admin/src/META-INF/drop.sql b/openaz-xacml-pap-admin/src/META-INF/drop.sql
new file mode 100644
index 0000000..8aee7ee
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/META-INF/drop.sql
@@ -0,0 +1,21 @@
+DROP TABLE IF EXISTS AttributeAssignment;
+DROP TABLE IF EXISTS ConstraintValues;
+DROP TABLE IF EXISTS ObadviceExpressions;
+DROP TABLE IF EXISTS Attribute;
+DROP TABLE IF EXISTS Category;
+DROP TABLE IF EXISTS ConstraintType;
+DROP VIEW IF EXISTS match_functions;
+DROP VIEW IF EXISTS higherorder_bag_functions;
+DROP VIEW IF EXISTS function_flattener;
+DROP TABLE IF EXISTS FunctionArguments;
+DROP TABLE IF EXISTS FunctionDefinition;
+DROP TABLE IF EXISTS Datatype;
+DROP TABLE IF EXISTS Obadvice;
+DROP TABLE IF EXISTS PIPConfigParams;
+DROP TABLE IF EXISTS PIPResolverParams;
+DROP TABLE IF EXISTS PIPResolver;
+DROP TABLE IF EXISTS PIPConfiguration;
+DROP TABLE IF EXISTS PIPType;
+DROP TABLE IF EXISTS PolicyAlgorithms;
+DROP TABLE IF EXISTS RuleAlgorithms;
+DROP TABLE IF EXISTS SEQUENCE;
\ No newline at end of file
diff --git a/openaz-xacml-pap-admin/src/META-INF/empty.sql b/openaz-xacml-pap-admin/src/META-INF/empty.sql
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/META-INF/empty.sql
diff --git a/openaz-xacml-pap-admin/src/META-INF/persistence.xml b/openaz-xacml-pap-admin/src/META-INF/persistence.xml
new file mode 100644
index 0000000..79594a9
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/META-INF/persistence.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
+	<persistence-unit name="XACML-PAP-ADMIN">
+		<class>org.apache.openaz.xacml.admin.jpa.Attribute</class>
+		<class>org.apache.openaz.xacml.admin.jpa.AttributeAssignment</class>
+		<class>org.apache.openaz.xacml.admin.jpa.Category</class>
+		<class>org.apache.openaz.xacml.admin.jpa.ConstraintType</class>
+		<class>org.apache.openaz.xacml.admin.jpa.ConstraintValue</class>
+		<class>org.apache.openaz.xacml.admin.jpa.Datatype</class>
+		<class>org.apache.openaz.xacml.admin.jpa.Obadvice</class>
+		<class>org.apache.openaz.xacml.admin.jpa.ObadviceExpression</class>
+		<class>org.apache.openaz.xacml.admin.jpa.PolicyAlgorithms</class>
+		<class>org.apache.openaz.xacml.admin.jpa.RuleAlgorithms</class>
+		<class>org.apache.openaz.xacml.admin.jpa.FunctionArgument</class>
+		<class>org.apache.openaz.xacml.admin.jpa.FunctionDefinition</class>
+		<class>org.apache.openaz.xacml.admin.jpa.PIPConfigParam</class>
+		<class>org.apache.openaz.xacml.admin.jpa.PIPConfiguration</class>
+		<class>org.apache.openaz.xacml.admin.jpa.PIPResolver</class>
+		<class>org.apache.openaz.xacml.admin.jpa.PIPResolverParam</class>
+		<class>org.apache.openaz.xacml.admin.jpa.PIPType</class>
+		<properties>
+			<!-- 
+				The properties defined below are the default settings to be used when someone initially
+				wants to start working with the XACML-PAP-ADMIN web gui. They are not intended for production
+				use.
+				
+				They are setup to drop and create the tables and then load an initial set of data into the database
+				every time the application is deployed. So if you add anything to the dictionaries or PIP
+				configuration, they will get lost upon each deployment. It uses an H2 database engine configured
+				for a local file so you don't have to setup you're own SQL database environment to start.
+				
+				Instead of modifying this file directly, please refer to the xacml.admin.properties file for
+				customizing the application settings.
+				
+			 -->
+			<property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
+			<property name="javax.persistence.schema-generation.create-source" value="metadata-then-script"/>
+			<property name="javax.persistence.schema-generation.create-script-source" value="META-INF/views.sql" />
+			<property name="javax.persistence.schema-generation.drop-source" value="script"/>
+			<property name="javax.persistence.schema-generation.drop-script-source" value="META-INF/drop.sql" />
+			<property name="javax.persistence.sql-load-script-source" value="META-INF/data.sql" />
+			
+			<!-- 
+			
+			These properties should be set in the xacml.admin.properties file, so they can be re-used by non-JPA
+			database functionality.
+			
+			<property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
+			<property name="javax.persistence.jdbc.url" value="jdbc:h2:file:sql/xacml"/>
+			<property name="javax.persistence.jdbc.user" value="sa"/>
+			<property name="javax.persistence.jdbc.password" value=""/>
+			 -->
+		</properties>
+	</persistence-unit>
+</persistence>
diff --git a/openaz-xacml-pap-admin/src/META-INF/views.sql b/openaz-xacml-pap-admin/src/META-INF/views.sql
new file mode 100644
index 0000000..7c4a820
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/META-INF/views.sql
@@ -0,0 +1,6 @@
+
+CREATE VIEW match_functions AS SELECT D.ID AS id, D.SHORT_NAME AS shortname, D.XACML_ID AS xacmlid,	D.RETURN_DATATYPE AS return_datatype, D.IS_BAG_RETURN AS is_bag_return,	D.ARG_LB AS arg_lb,	D.ARG_UB AS arg_ub,	A1.IS_BAG AS arg1_isbag, A1.DATATYPE_ID AS arg1_datatype, A2.IS_BAG AS arg2_isbag,	A2.DATATYPE_ID AS arg2_datatype FROM (FunctionDefinition D left join FunctionArguments A1 on (A1.FUNCTION_ID = D.ID and A1.ARG_INDEX = 1) left join FunctionArguments A2 on (A2.FUNCTION_ID = D.ID and A2.ARG_INDEX = 2)) where (D.ARG_LB = 2 and D.ARG_UB = 2 and D.RETURN_DATATYPE = 18 and A1.IS_BAG = 0) order by D.SHORT_NAME;
+
+CREATE VIEW function_flattener AS SELECT D.ID AS id, D.SHORT_NAME AS shortname, D.RETURN_DATATYPE AS return_datatype, D.IS_BAG_RETURN AS is_bag_return, D.IS_HIGHER_ORDER AS is_higher_order, D.ARG_LB AS arg_lb, D.ARG_UB AS arg_ub, A1.IS_BAG AS arg1_isbag, A1.DATATYPE_ID AS arg1_datatype, A2.IS_BAG AS arg2_isbag, A2.DATATYPE_ID AS arg2_datatype, A3.IS_BAG AS arg3_isbag, A3.DATATYPE_ID AS arg3_datatype FROM (FunctionDefinition D left join FunctionArguments A1 ON (A1.FUNCTION_ID = D.ID and A1.ARG_INDEX = 1) left join FunctionArguments A2 ON (A2.FUNCTION_ID = D.ID and A2.ARG_INDEX = 2) LEFT JOIN FunctionArguments A3 ON (A3.FUNCTION_ID = D.ID and A3.ARG_INDEX = 3)) ORDER BY D.ID;
+
+CREATE VIEW higherorder_bag_functions AS SELECT * FROM function_flattener WHERE is_higher_order = 1 AND is_bag_return = 1 AND return_datatype=18 AND arg_lb=2 AND arg_ub=2 AND arg1_isbag = 1 AND (arg2_isbag = 1 OR arg2_isbag IS NULL);
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/PAPNotificationBroadcaster.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/PAPNotificationBroadcaster.java
new file mode 100644
index 0000000..b2deda7
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/PAPNotificationBroadcaster.java
@@ -0,0 +1,120 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ *
+ */
+
+package org.apache.openaz.xacml.admin;
+
+import java.io.Serializable;
+import java.util.LinkedList;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Handle Notifications from the PAP that the PDP Groups have been changed.
+ * We need a Server Push Broadcaster because there may be multiple Vaadin instances (i.e. Users) that need to be told when a change occurs.
+ * 
+ * Initially we only update the entire set of PDPGroups in one shot.
+ * 
+ * (Code copied from Book of Vaadin chapter on Server Push
+ * @author glenngriffin
+ *
+ */
+public class PAPNotificationBroadcaster implements Serializable {
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = -2539940306348821754L;
+
+
+	private static Log logger	= LogFactory.getLog(PAPNotificationBroadcaster.class);
+
+	
+    static ExecutorService executorService = Executors.newSingleThreadExecutor();
+
+    /**
+     * Interface used by all classes that need to be notified when PAP sends an update message.
+     * 
+     * @author glenngriffin
+     *
+     */
+    public interface PAPNotificationBroadcastListener {
+        void updateAllGroups();
+    }
+    
+    
+    
+    /*
+     * list of registered listeners
+     */
+    private static LinkedList<PAPNotificationBroadcastListener> listeners =
+        new LinkedList<PAPNotificationBroadcastListener>();
+    
+    /**
+     * Listener registers to hear about updates.
+     * @param listener
+     */
+    public static synchronized void register(
+    		PAPNotificationBroadcastListener listener) {
+        listeners.add(listener);
+    }
+    
+    
+    /**
+     * Listener is going away.
+     * 
+     * @param listener
+     */
+    public static synchronized void unregister(
+    		PAPNotificationBroadcastListener listener) {
+        listeners.remove(listener);
+    }
+    
+    
+    
+    /**
+     * Tell all listeners about an update.
+     * 
+     * @param message
+     */
+    public static synchronized void updateAllGroups() {
+        for (final PAPNotificationBroadcastListener listener: listeners) {
+  // Original code copied from example:
+  //          executorService.execute(new Runnable() {
+  //              @Override
+  //              public void run() {
+  // The problem with this is that the execute starts a new Thread, but the thing we are calling (the listener.updateAllGroups)
+  // happens in this case to ALSO create a new thread, and it locks up because the shared threadpool queue is already locked by this method.
+  // On application shutdown that left us with a blocked thread, so the process never goes away.
+  // Since the listener.updateAllGroups does ALL of its work inside a new Runnable thread, there should be no need for this method to also create a thread.
+  
+        	/*
+        	 * IMPORTANT:
+        	 * All listeners MUST either execute with no possibility of blocking
+        	 * OR must start their own threads to handle blocking and concurrent operations.
+        	 */
+        	if (logger.isDebugEnabled()) {
+        		logger.debug("updateAllGroups");
+        	}
+            listener.updateAllGroups();
+        }
+    }
+}
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/XacmlAdminAuthorization.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/XacmlAdminAuthorization.java
new file mode 100644
index 0000000..2a065d5
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/XacmlAdminAuthorization.java
@@ -0,0 +1,178 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ *
+ */
+
+package org.apache.openaz.xacml.admin;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.openaz.xacml.std.annotations.XACMLRequest;
+import org.apache.openaz.xacml.std.annotations.RequestParser;
+import org.apache.openaz.xacml.std.annotations.XACMLSubject;
+import org.apache.openaz.xacml.std.annotations.XACMLAction;
+import org.apache.openaz.xacml.std.annotations.XACMLResource;
+import org.apache.openaz.xacml.api.DataTypeException;
+import org.apache.openaz.xacml.api.Decision;
+import org.apache.openaz.xacml.api.Request;
+import org.apache.openaz.xacml.api.Response;
+import org.apache.openaz.xacml.api.Result;
+import org.apache.openaz.xacml.api.pdp.PDPEngine;
+import org.apache.openaz.xacml.api.pdp.PDPEngineFactory;
+import org.apache.openaz.xacml.api.pdp.PDPException;
+import org.apache.openaz.xacml.util.FactoryException;
+
+public class XacmlAdminAuthorization {
+	private static Log logger	= LogFactory.getLog(XacmlAdminAuthorization.class);
+	
+	public enum AdminAction {
+		ACTION_ACCESS("access"),
+		ACTION_READ("read"),
+		ACTION_WRITE("write"),
+		ACTION_ADMIN("admin");
+		
+		String action;
+		AdminAction(String a) {
+			this.action = a;
+		}
+		public String toString() {
+			return this.action;
+		}
+	}
+	
+	public enum AdminResource {
+		RESOURCE_APPLICATION("application"),
+		RESOURCE_POLICY_WORKSPACE("workspace"),
+		RESOURCE_POLICY_EDITOR("editor"),
+		RESOURCE_DICTIONARIES("dictionaries"),
+		RESOURCE_PDP_ADMIN("pdp_admin"),
+		RESOURCE_PIP_ADMIN("pip_admin");
+		
+		String resource;
+		AdminResource(String r) {
+			this.resource = r;
+		}
+		public String toString() {
+			return this.resource;
+		}
+	}
+	
+	@XACMLRequest(ReturnPolicyIdList=true)
+	public class AuthorizationRequest {
+		
+		@XACMLSubject(includeInResults=true)
+		String	userID;
+		
+		@XACMLAction()
+		String	action;
+		
+		@XACMLResource()
+		String	resource;
+		
+		public AuthorizationRequest(String userId, String action, String resource) {
+			this.userID = userId;
+			this.action = action;
+			this.resource = resource;
+		}
+
+		public String getUserID() {
+			return userID;
+		}
+
+		public void setUserID(String userID) {
+			this.userID = userID;
+		}
+
+		public String getAction() {
+			return action;
+		}
+
+		public void setAction(String action) {
+			this.action = action;
+		}
+
+		public String getResource() {
+			return resource;
+		}
+
+		public void setResource(String resource) {
+			this.resource = resource;
+		}
+	}
+	
+	//
+	// The PDP Engine
+	//
+	protected PDPEngine pdpEngine;
+
+	public XacmlAdminAuthorization() {
+		PDPEngineFactory pdpEngineFactory	= null;
+		try {
+			pdpEngineFactory	= PDPEngineFactory.newInstance();
+			if (pdpEngineFactory == null) {
+				logger.error("Failed to create PDP Engine Factory");
+			}
+			this.pdpEngine = pdpEngineFactory.newEngine();
+		} catch (FactoryException e) {
+			logger.error("Exception create PDP Engine: " + e.getLocalizedMessage());
+		}
+	}
+	
+	public boolean	isAuthorized(String userid, AdminAction action, AdminResource resource) {
+		logger.info("authorize: " + userid + " to " + action + " with " + resource);
+		if (this.pdpEngine == null) {
+			logger.warn("no pdp engine available to authorize");
+			return false;
+		}
+		Request request;
+		try {
+			request = RequestParser.parseRequest(new AuthorizationRequest(userid, action.toString(), resource.toString()));
+		} catch (IllegalArgumentException | IllegalAccessException | DataTypeException e) {
+			logger.error("Failed to create request: " + e.getLocalizedMessage());
+			return false;
+		}
+		if (request == null) {
+			logger.error("Failed to parse request.");
+			return false;
+		}
+		logger.info("Request: " + request);
+		//
+		// Ask the engine
+		//
+		try {
+			Response response = this.pdpEngine.decide(request);
+			if (response == null) {
+				logger.error("Null response from PDP decide");
+			}
+			//
+			// Should only be one result
+			//
+			for (Result result : response.getResults()) {
+				Decision decision = result.getDecision();
+				logger.info("Decision: " + decision);
+				if (decision.equals(Decision.PERMIT)) {
+					return true;
+				}
+			}
+		} catch (PDPException e) {
+			logger.error("PDP Decide failed: " + e.getLocalizedMessage());
+		}
+		return false;
+	}
+}
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/XacmlAdminConsole.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/XacmlAdminConsole.java
new file mode 100644
index 0000000..91e831b
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/XacmlAdminConsole.java
@@ -0,0 +1,253 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ *
+ */
+
+package org.apache.openaz.xacml.admin;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.openaz.xacml.admin.components.AttributeDictionary;
+import org.apache.openaz.xacml.admin.components.ObadviceDictionary;
+import org.apache.openaz.xacml.admin.components.PDPManagement;
+import org.apache.openaz.xacml.admin.components.PIPManagement;
+import org.apache.openaz.xacml.admin.components.PolicyWorkspace;
+import com.vaadin.annotations.AutoGenerated;
+import com.vaadin.navigator.View;
+import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent;
+import com.vaadin.server.ThemeResource;
+import com.vaadin.shared.ui.label.ContentMode;
+import com.vaadin.ui.Alignment;
+import com.vaadin.ui.CustomComponent;
+import com.vaadin.ui.Embedded;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.TabSheet;
+import com.vaadin.ui.UI;
+import com.vaadin.ui.VerticalLayout;
+
+public class XacmlAdminConsole extends CustomComponent implements View {
+	private static final long serialVersionUID = 1L;
+	@AutoGenerated
+	private VerticalLayout mainLayout;
+	@AutoGenerated
+	private Label labelCopyright;
+	@AutoGenerated
+	private TabSheet tabSheet;
+	@AutoGenerated
+	private HorizontalLayout horizontalLayout_1;
+	@AutoGenerated
+	private Label labelWelcome;
+	@AutoGenerated
+	private Label caption;
+	@AutoGenerated
+	private Embedded embedded_1;
+
+	private static Log logger	= LogFactory.getLog(XacmlAdminConsole.class);
+	
+	private final PolicyWorkspace policyWorkspace;
+	private final AttributeDictionary attributeDictionary;
+	private final ObadviceDictionary obadvice;
+	private final PDPManagement pdp;
+	private final PIPManagement pip;
+//	private final UserManagement user;
+	
+	/**
+	 * The constructor should first build the main layout, set the
+	 * composition root and then do any custom initialization.
+	 *
+	 * The constructor will not be automatically regenerated by the
+	 * visual editor.
+	 */
+	public XacmlAdminConsole() {
+		buildMainLayout();
+		setCompositionRoot(mainLayout);
+		
+		if (logger.isDebugEnabled()) {
+			logger.debug("Creating tabs...");
+		}
+		
+		this.labelWelcome.setValue("Welcome " + ((XacmlAdminUI)UI.getCurrent()).getUserName());
+		this.labelCopyright.setContentMode(ContentMode.HTML);
+		
+		if (((XacmlAdminUI)UI.getCurrent()).isAuthorized( 
+				XacmlAdminAuthorization.AdminAction.ACTION_READ, 
+				XacmlAdminAuthorization.AdminResource.RESOURCE_POLICY_WORKSPACE)) {
+			this.policyWorkspace = new PolicyWorkspace();
+			this.tabSheet.addComponent(this.policyWorkspace);
+			this.tabSheet.getTab(this.policyWorkspace).setCaption("Policy Workspace");
+		} else {
+			this.policyWorkspace = null;
+		}
+		
+		if (((XacmlAdminUI)UI.getCurrent()).isAuthorized( 
+				XacmlAdminAuthorization.AdminAction.ACTION_READ, 
+				XacmlAdminAuthorization.AdminResource.RESOURCE_DICTIONARIES)) {
+			this.attributeDictionary = new AttributeDictionary();
+			this.tabSheet.addComponent(this.attributeDictionary);
+			this.tabSheet.getTab(this.attributeDictionary).setCaption("Attribute Dictionary");
+
+			this.obadvice = new ObadviceDictionary(); 
+			this.tabSheet.addComponent(this.obadvice);
+			this.tabSheet.getTab(this.obadvice).setCaption("Obligation/Advice Dictionary");
+		} else {
+			this.attributeDictionary = null;
+			this.obadvice = null;
+		}
+		if (((XacmlAdminUI)UI.getCurrent()).isAuthorized( 
+									XacmlAdminAuthorization.AdminAction.ACTION_READ, 
+									XacmlAdminAuthorization.AdminResource.RESOURCE_PDP_ADMIN)) {
+			this.pdp = new PDPManagement(((XacmlAdminUI)UI.getCurrent()).getPAPEngine());
+			this.tabSheet.addComponent(this.pdp);
+			this.tabSheet.getTab(this.pdp).setCaption("PDP Management");
+		} else {
+			this.pdp = null;
+		}
+		
+		if (((XacmlAdminUI)UI.getCurrent()).isAuthorized( 
+				XacmlAdminAuthorization.AdminAction.ACTION_READ, 
+				XacmlAdminAuthorization.AdminResource.RESOURCE_PIP_ADMIN)) {
+			this.pip = new PIPManagement();
+			this.tabSheet.addComponent(this.pip);
+			this.tabSheet.getTab(this.pip).setCaption("PIP Management");
+		} else {
+			this.pip = null;
+		}
+		/*
+		 * TODO  - figure out how to add this in
+		 *
+		if (((XacmlAdminUI)UI.getCurrent()).isAuthorized( 
+				XacmlAdminAuthorization.AdminAction.ACTION_READ, 
+				XacmlAdminAuthorization.AdminResource.RESOURCE_POLICY_WORKSPACE)) {
+			this.user = new UserManagement();
+			this.tabSheet.addComponent(this.user);
+			this.tabSheet.getTab(this.user).setCaption("User Management");
+		}
+		*/
+		
+		if (logger.isDebugEnabled()) {
+			logger.debug("Done creating tabs.");
+		}
+	}
+	
+	public void refreshAttributes() {
+		this.attributeDictionary.refreshContainer();
+	}
+	public void refreshObadvice() {
+		this.obadvice.refreshContainer();
+	}
+
+	public void refreshPIPConfiguration() {
+		this.pip.refreshContainer();
+	}
+
+	public void refreshPDPGroups() {
+		this.pdp.refreshContainer();
+	}
+
+	public TabSheet getTabSheet() { return tabSheet;}
+
+	@AutoGenerated
+	private VerticalLayout buildMainLayout() {
+		// common part: create layout
+		mainLayout = new VerticalLayout();
+		mainLayout.setImmediate(false);
+		mainLayout.setWidth("100%");
+		mainLayout.setHeight("100%");
+		mainLayout.setMargin(true);
+		
+		// top-level component properties
+		setWidth("100.0%");
+		setHeight("100.0%");
+		
+		// horizontalLayout_1
+		horizontalLayout_1 = buildHorizontalLayout_1();
+		mainLayout.addComponent(horizontalLayout_1);
+		
+		// tabSheet
+		tabSheet = new TabSheet();
+		tabSheet.setImmediate(false);
+		tabSheet.setWidth("100.0%");
+		tabSheet.setHeight("100.0%");
+		mainLayout.addComponent(tabSheet);
+		mainLayout.setExpandRatio(tabSheet, 1.0f);
+		
+		// labelCopyright
+		labelCopyright = new Label();
+		labelCopyright.setImmediate(false);
+		labelCopyright.setWidth("-1px");
+		labelCopyright.setHeight("40px");
+		labelCopyright
+				.setValue("<center>Copyright &copy; 2015 The Apache Software Foundation, Licensed under the Apache License, Version 2.0.</center>");
+		mainLayout.addComponent(labelCopyright);
+		mainLayout.setComponentAlignment(labelCopyright, new Alignment(48));
+		
+		return mainLayout;
+	}
+
+	@AutoGenerated
+	private HorizontalLayout buildHorizontalLayout_1() {
+		// common part: create layout
+		horizontalLayout_1 = new HorizontalLayout();
+		horizontalLayout_1.setImmediate(false);
+		horizontalLayout_1.setWidth("100.0%");
+		horizontalLayout_1.setHeight("40px");
+		horizontalLayout_1.setMargin(false);
+		
+		// embedded_1
+		embedded_1 = new Embedded();
+		embedded_1.setImmediate(false);
+		embedded_1.setWidth("30px");
+		embedded_1.setHeight("30px");
+		embedded_1.setSource(new ThemeResource("img/att.png"));
+		embedded_1.setType(1);
+		embedded_1.setMimeType("image/png");
+		horizontalLayout_1.addComponent(embedded_1);
+		horizontalLayout_1.setComponentAlignment(embedded_1, new Alignment(33));
+		
+		// caption
+		caption = new Label();
+		caption.setImmediate(false);
+		caption.setWidth("-1px");
+		caption.setHeight("-1px");
+		caption.setValue("Apache OpenAZ Admin Console");
+		horizontalLayout_1.addComponent(caption);
+		horizontalLayout_1.setExpandRatio(caption, 1.0f);
+		horizontalLayout_1.setComponentAlignment(caption, new Alignment(33));
+		
+		// labelWelcome
+		labelWelcome = new Label();
+		labelWelcome.setImmediate(false);
+		labelWelcome.setWidth("-1px");
+		labelWelcome.setHeight("40px");
+		labelWelcome.setValue("Label");
+		horizontalLayout_1.addComponent(labelWelcome);
+		horizontalLayout_1.setComponentAlignment(labelWelcome,
+				new Alignment(34));
+		
+		return horizontalLayout_1;
+	}
+
+	@Override
+	public void enter(ViewChangeEvent event) {
+		//
+		// This needs to be implemented
+		//
+	}
+}
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/XacmlAdminServlet.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/XacmlAdminServlet.java
new file mode 100644
index 0000000..fa48543
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/XacmlAdminServlet.java
@@ -0,0 +1,97 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ *
+ */
+
+package org.apache.openaz.xacml.admin;
+
+import java.io.IOException;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.annotation.WebInitParam;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.vaadin.annotations.Push;
+import com.vaadin.annotations.VaadinServletConfiguration;
+import com.vaadin.server.VaadinServlet;
+
+import org.apache.openaz.xacml.rest.XACMLRest;
+
+
+//
+// The Servlet underlying the Vaadin Servlet
+//
+@Push
+@WebServlet(
+		value = "/*",
+		description = "XACML Admin Console",
+		asyncSupported = true, 
+		loadOnStartup=1,
+		initParams = { 
+		@WebInitParam(name = "XACML_PROPERTIES_NAME", value = "xacml.admin.properties", description = "The location of the properties file holding configuration information.")
+})
+@VaadinServletConfiguration(productionMode = false, ui = XacmlAdminUI.class)
+public class XacmlAdminServlet extends VaadinServlet {
+	//
+	// All static declarations
+	//
+	private static Log logger	= LogFactory.getLog(XacmlAdminServlet.class); //NOPMD
+
+	@Override
+	public void init(ServletConfig servletConfig) throws ServletException {
+		super.init(servletConfig);
+		//
+		// Common initialization
+		//
+		XACMLRest.xacmlInit(servletConfig);
+
+		// Initialization
+		XacmlAdminUI.servletInit();
+	}
+	
+	@Override
+	public void destroy() {
+		XacmlAdminUI.servletDestroy();
+		super.destroy();
+	}
+	
+	/**
+	 * 
+	 * Called by:
+	 * 	- PAP to notify Vaadin GUIs that something has changed
+	 * 
+	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
+	 */
+	@Override
+	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+		// watch for notifications from the PAP
+		if (request.getMethod().equals("PUT") && request.getParameter("PAPNotification") != null) {
+			XacmlAdminUI.doPAPNotification(request, response);
+			return;
+		}
+
+		// not a PAP notification, so let Vaadin handle normally
+		super.service(request,response);
+	}
+}
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/XacmlAdminUI.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/XacmlAdminUI.java
new file mode 100644
index 0000000..e553749
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/XacmlAdminUI.java
@@ -0,0 +1,801 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ *
+ */
+
+package org.apache.openaz.xacml.admin;
+
+import java.io.IOException;
+import java.net.URI;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.sql.SQLException;
+import java.util.Properties;
+import java.util.UUID;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Persistence;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.api.errors.InvalidRemoteException;
+import org.eclipse.jgit.api.errors.TransportException;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.lib.StoredConfig;
+import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
+import org.eclipse.persistence.config.PersistenceUnitProperties;
+
+import org.apache.openaz.xacml.admin.XacmlAdminAuthorization.AdminAction;
+import org.apache.openaz.xacml.admin.XacmlAdminAuthorization.AdminResource;
+import org.apache.openaz.xacml.admin.converters.XacmlConverterFactory;
+import org.apache.openaz.xacml.admin.jpa.Attribute;
+import org.apache.openaz.xacml.admin.jpa.Category;
+import org.apache.openaz.xacml.admin.jpa.ConstraintType;
+import org.apache.openaz.xacml.admin.jpa.Datatype;
+import org.apache.openaz.xacml.admin.jpa.FunctionArgument;
+import org.apache.openaz.xacml.admin.jpa.FunctionDefinition;
+import org.apache.openaz.xacml.admin.jpa.Obadvice;
+import org.apache.openaz.xacml.admin.jpa.ObadviceExpression;
+import org.apache.openaz.xacml.admin.jpa.PIPConfiguration;
+import org.apache.openaz.xacml.admin.jpa.PIPResolver;
+import org.apache.openaz.xacml.admin.jpa.PIPType;
+import org.apache.openaz.xacml.admin.jpa.PolicyAlgorithms;
+import org.apache.openaz.xacml.admin.jpa.RuleAlgorithms;
+import org.apache.openaz.xacml.admin.model.MatchFunctionQueryDelegate;
+import org.apache.openaz.xacml.admin.util.RESTfulPAPEngine;
+import org.apache.openaz.xacml.api.XACML3;
+import org.apache.openaz.xacml.api.pap.PAPEngine;
+import org.apache.openaz.xacml.api.pap.PAPException;
+import org.apache.openaz.xacml.rest.XACMLRestProperties;
+import org.apache.openaz.xacml.util.XACMLProperties;
+import com.google.gwt.thirdparty.guava.common.base.Joiner;
+import com.google.gwt.thirdparty.guava.common.base.Splitter;
+import com.vaadin.addon.jpacontainer.JPAContainer;
+import com.vaadin.addon.jpacontainer.provider.CachingLocalEntityProvider;
+import com.vaadin.addon.jpacontainer.provider.CachingMutableLocalEntityProvider;
+import com.vaadin.annotations.Push;
+import com.vaadin.annotations.Theme;
+import com.vaadin.data.util.sqlcontainer.SQLContainer;
+import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool;
+import com.vaadin.data.util.sqlcontainer.query.FreeformQuery;
+import com.vaadin.navigator.Navigator;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.server.VaadinServletService;
+import com.vaadin.ui.UI;
+
+@Push
+@SuppressWarnings("serial")
+@Theme("xacml_pap_admin")
+public class XacmlAdminUI extends UI implements PAPNotificationBroadcaster.PAPNotificationBroadcastListener {
+	//
+	// All static declarations
+	//
+	public static final String PERSISTENCE_UNIT = "XACML-PAP-ADMIN";
+	private static Log logger	= LogFactory.getLog(XacmlAdminUI.class); //NOPMD
+	
+	/*
+	 * These objects are shared amongst sessions.
+	 */
+	private static Path repositoryPath;
+	private static Repository repository;
+	private static EntityManagerFactory emf;
+	private static JDBCConnectionPool pool;
+	
+	/*
+	 * These objects are created each session.
+	 */
+	private Path workspacePath;
+	private Path gitPath;
+	//
+	// Our Persistence Fields. For general use. NOTE: Be careful applying
+	// filters to these container objects. If one window applies a filter, then
+	// when another window uses the object, that filter will show up and cause confusion.
+	// If filters are needed within a window, then create another instance instead of
+	// using one of these pointers.
+	//
+	private EntityManager em;
+	private JPAContainer<Attribute> 			attributes;
+	private JPAContainer<ConstraintType> 		constraintTypes;
+	private JPAContainer<Obadvice> 				obadvice;
+	private JPAContainer<ObadviceExpression> 	obadviceExpressions;
+	private JPAContainer<Category> 				categories;
+	private JPAContainer<Datatype> 				datatypes;
+	private JPAContainer<PolicyAlgorithms> 		policyAlgorithms;
+	private JPAContainer<RuleAlgorithms> 		ruleAlgorithms;
+	private JPAContainer<PIPConfiguration>		pipConfigurations;
+	private JPAContainer<PIPResolver>			pipResolvers;
+	private JPAContainer<PIPType>				pipTypes;
+	private JPAContainer<FunctionDefinition>	functionDefinitions;
+	private JPAContainer<FunctionArgument>		functionArguments;
+	private SQLContainer matchFunctionContainer;
+	private SQLContainer higherorderBagContainer;
+	//
+	// Our authorization object
+	//
+	XacmlAdminAuthorization authorizer = new XacmlAdminAuthorization();
+	//
+	// The PAP Engine
+	//
+	private PAPEngine papEngine;
+	//
+	// GUI navigation
+	//
+	private Navigator navigator = null;
+	private XacmlAdminConsole console = null;
+	//
+	// Vaadin Init
+	//
+	@Override
+	protected void init(VaadinRequest request) {
+		//
+		// Set our title
+		//
+		this.getPage().setTitle("Apache OpenAZ Admin Console");
+		//
+		// Create our authorization object
+		//
+		this.authorizer = new XacmlAdminAuthorization();
+		//
+		// Is the user authorized to use the application?
+		//
+		if (this.authorizer.isAuthorized(this.getUserid(), 
+									XacmlAdminAuthorization.AdminAction.ACTION_ACCESS, 
+									XacmlAdminAuthorization.AdminResource.RESOURCE_APPLICATION) == false) {
+			logger.error("user " + this.getUserid() + " is not authorized.");
+			//
+			// Create a navigator to manage all our views
+			//
+			this.navigator = new Navigator(this, this);
+			//
+			// Redirect to an error page
+			//
+			this.navigator.addView(XacmlErrorHandler.VIEWNAME, new XacmlErrorHandler("User " + this.getUserid() + " is not authorized to access application", null));
+			this.navigator.navigateTo(XacmlErrorHandler.VIEWNAME);
+			return;
+		}
+		try {
+			//
+			// Initialize user's Git repository
+			//
+			this.workspacePath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_ADMIN_WORKSPACE), this.getUserid());
+			this.gitPath = XacmlAdminUI.initializeUserRepository(this.workspacePath, this.getUserid(), this.getUserEmail());
+		} catch (Exception e) {
+			logger.error("Git Setup failure", e);
+			//
+			// Create a navigator to manage all our views
+			//
+			this.navigator = new Navigator(this, this);
+			//
+			// Redirect to an error page
+			//
+			this.navigator.addView(XacmlErrorHandler.VIEWNAME, new XacmlErrorHandler(e.getMessage(), null));
+			this.navigator.navigateTo(XacmlErrorHandler.VIEWNAME);
+			return;
+		}
+		//
+		// Create a navigator to manage all our views
+		//
+		this.navigator = new Navigator(this, this);
+		//
+		// Set our converter factory
+		//
+		this.getSession().setConverterFactory(new XacmlConverterFactory());
+		//
+		// Initialize our data objects
+		//
+		try {
+			//
+			// Initialize JPA and SQL. Create our custom entity manager.
+			//
+			logger.info("Creating Persistence Entity Manager");
+			//
+			// Now create the entity manager. This is used throughout the application to create JPA
+			// containers of the entities located in the database.
+			//
+			this.em = XacmlAdminUI.emf.createEntityManager();
+			//
+			// Our Read-Only containers
+			//
+			logger.info("Creating JPA read-only containers");
+			this.constraintTypes = new JPAContainer<ConstraintType>(ConstraintType.class);
+			this.constraintTypes.setEntityProvider(new CachingLocalEntityProvider<ConstraintType>(ConstraintType.class, this.em));
+			
+			this.categories = new JPAContainer<Category>(Category.class);
+			this.categories.setEntityProvider(new CachingLocalEntityProvider<Category>(Category.class, this.em));
+
+			this.datatypes = new JPAContainer<Datatype>(Datatype.class);
+			this.datatypes.setEntityProvider(new CachingLocalEntityProvider<Datatype>(Datatype.class, this.em));
+			
+			this.policyAlgorithms = new JPAContainer<PolicyAlgorithms>(PolicyAlgorithms.class);
+			this.policyAlgorithms.setEntityProvider(new CachingLocalEntityProvider<PolicyAlgorithms>(PolicyAlgorithms.class, this.em));
+			
+			this.ruleAlgorithms = new JPAContainer<RuleAlgorithms>(RuleAlgorithms.class);
+			this.ruleAlgorithms.setEntityProvider(new CachingLocalEntityProvider<RuleAlgorithms>(RuleAlgorithms.class, this.em));
+			
+			this.pipTypes = new JPAContainer<PIPType>(PIPType.class);
+			this.pipTypes.setEntityProvider(new CachingLocalEntityProvider<PIPType>(PIPType.class, this.em));
+			
+			this.functionDefinitions = new JPAContainer<FunctionDefinition>(FunctionDefinition.class);
+			this.functionDefinitions.setEntityProvider(new CachingLocalEntityProvider<FunctionDefinition>(FunctionDefinition.class, this.em));
+
+			this.functionArguments = new JPAContainer<FunctionArgument>(FunctionArgument.class);
+			this.functionArguments.setEntityProvider(new CachingLocalEntityProvider<FunctionArgument>(FunctionArgument.class, this.em));
+			//
+			// Our writable containers. NOTE: The dictionaries have their own JPA instance since they can
+			// apply filters to their table views. If you update these, then refresh the dictionary containers
+			// by calling the appropriate refresh method defined in XacmlAdminUI.
+			//
+			logger.info("Creating JPA writable containers");
+			this.attributes = new JPAContainer<Attribute>(Attribute.class);
+			this.attributes.setEntityProvider(new CachingMutableLocalEntityProvider<Attribute>(Attribute.class, this.em));
+
+			this.obadvice = new JPAContainer<Obadvice>(Obadvice.class);
+			this.obadvice.setEntityProvider(new CachingMutableLocalEntityProvider<Obadvice>(Obadvice.class, this.em));
+
+			this.obadviceExpressions = new JPAContainer<ObadviceExpression>(ObadviceExpression.class);
+			this.obadviceExpressions.setEntityProvider(new CachingMutableLocalEntityProvider<ObadviceExpression>(ObadviceExpression.class, this.em));
+
+			this.pipConfigurations = new JPAContainer<PIPConfiguration>(PIPConfiguration.class);
+			this.pipConfigurations.setEntityProvider(new CachingMutableLocalEntityProvider<PIPConfiguration>(PIPConfiguration.class, this.em));
+			
+			this.pipResolvers = new JPAContainer<PIPResolver>(PIPResolver.class);
+			this.pipResolvers.setEntityProvider(new CachingMutableLocalEntityProvider<PIPResolver>(PIPResolver.class, this.em));
+			//
+			// Sort our persistence data
+			//
+			logger.info("Sorting containers");
+			this.categories.sort(new String[]{"xacmlId"}, new boolean[]{true});
+			this.datatypes.sort(new String[]{"xacmlId"}, new boolean[]{true});
+			this.policyAlgorithms.sort(new String[]{"xacmlId"}, new boolean[]{true});
+			this.ruleAlgorithms.sort(new String[]{"xacmlId"}, new boolean[]{true});
+			this.functionDefinitions.sort(new String[]{"xacmlid"}, new boolean[]{true});
+			//this.functionArguments.sort(new String[]{"datatypeBean"}, new boolean[]{true});
+			//
+			// Create our special query for MatchType functions. We need a custom
+			// QueryDelegate because these functions are accessible via a View (vs a Table).
+			// The basic FreeformQuery does not work with filters on a View (via Vaadin).
+			//
+			// TODO: Consider putting this into a couple of Map's. Doing so would speed up
+			// access. However, if we want to support custom functions, then there needs to
+			// be a way for those custom functions to get into the Map. This is why a database
+			// is being used to store ALL the functions, both standard and custom.
+			//
+			logger.info("Creating SQL Queries");
+			MatchFunctionQueryDelegate delegate = new MatchFunctionQueryDelegate();
+			FreeformQuery query = new FreeformQuery("SELECT * FROM match_functions", XacmlAdminUI.pool, new String[] {});
+			query.setDelegate(delegate);
+			this.matchFunctionContainer = new SQLContainer(query);
+			//
+			// Same for this one
+			//
+			delegate = new MatchFunctionQueryDelegate();
+			query = new FreeformQuery("SELECT * FROM higherorder_bag_functions", XacmlAdminUI.pool, new String[] {});
+			query.setDelegate(delegate);
+			this.higherorderBagContainer = new SQLContainer(query);
+			//
+			// Load our PAP engine
+			//
+			logger.info("Creating PAP engine");
+			String myRequestURL = VaadinServletService.getCurrentServletRequest().getRequestURL().toString();
+			try {
+				//
+				// Set the URL for the RESTful PAP Engine
+				//
+				papEngine = new RESTfulPAPEngine(myRequestURL);
+			} catch (PAPException e  ) {
+				logger.error("Failed to create PAP engine", e);
+			} catch (Exception e) {
+				logger.error("Failed to create PAP engine", e);
+			}
+			logger.info("done creating connections");
+		} catch(Exception e) {
+			//
+			// Redirect to an error page
+			//
+			logger.error(e);
+			e.printStackTrace();
+			this.navigator.addView("", new XacmlErrorHandler(e.getMessage(), null));
+			this.navigator.navigateTo("");
+			return;
+		}
+		logger.info("Creating main layout");
+		//
+		// Create our main component layout
+		//
+		this.console = new XacmlAdminConsole();
+		this.navigator.addView("", console);
+		this.navigator.setErrorView(new XacmlErrorHandler(null, null));
+		//
+		// Navigate to our view
+		//
+		this.navigator.navigateTo("");
+		//
+		// Register to receive PAP change notifications broadcasts
+		//
+		PAPNotificationBroadcaster.register(this);
+	}
+	
+	public static void servletInit() throws ServletException {
+		//
+		// Initialize GIT repository.
+		//
+		XacmlAdminUI.initializeGitRepository();
+		//
+		// Initialize Entity Factory
+		//
+		XacmlAdminUI.initializeEntityFactory();
+		//
+		// If we get here, then the configuration information
+		// seems ok.
+		//
+	}
+
+	public static void servletDestroy() {
+		if (XacmlAdminUI.repository != null) {
+			XacmlAdminUI.repository.close();
+		}
+	}
+	
+	/**
+	 * An Update Notification has arrived from the PAP.
+	 * Tell the Vaadin users to change their data.
+	 * 
+	 * @param request
+	 * @param response
+	 * @throws ServletException
+	 * @throws IOException
+	 */
+	public static void doPAPNotification(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+		try {
+			//
+			// Notify all user instances to update groups
+			//
+			PAPNotificationBroadcaster.updateAllGroups();
+		} catch (Exception e) {
+			logger.error("Unable to process PAP request: "+e, e);
+			response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
+		}
+		response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+	}
+
+	// Must unregister when the UI expires
+	@Override
+	public void detach() {
+		PAPNotificationBroadcaster.unregister(this);
+		super.detach();
+	}
+	
+	/**
+	 * This will initialize the JPA Entity Manager Factory. This will determine if
+	 * the database connection settings are correct.
+	 * 
+	 * @throws ServletException
+	 */
+	private static void initializeEntityFactory() throws ServletException {
+		logger.info("intializing Persistence Entity Factory");
+		//
+		// Pull custom persistence settings
+		//
+		Properties properties;
+		try {
+			properties = XACMLProperties.getProperties();
+		} catch (IOException e) {
+			throw new ServletException(e.getMessage(), e.getCause());
+		}
+		//
+		// Create the factory
+		//
+		emf = Persistence.createEntityManagerFactory(XacmlAdminUI.PERSISTENCE_UNIT, properties);
+		//
+		// Did it get created?
+		//
+		if (emf == null) {
+			throw new ServletException("Unable to create Entity Manager Factory");
+		}
+		//
+		// Create our JDBC connection pool
+		//
+		try {
+			logger.info("intializing JDBC Connection Pool");
+			XacmlAdminUI.pool = new XacmlJDBCConnectionPool(
+					properties.getProperty(PersistenceUnitProperties.JDBC_DRIVER),
+					properties.getProperty(PersistenceUnitProperties.JDBC_URL),
+					properties.getProperty(PersistenceUnitProperties.JDBC_USER),
+					properties.getProperty(PersistenceUnitProperties.JDBC_PASSWORD));
+		} catch (SQLException e) {
+			throw new ServletException(e.getMessage(), e.getCause());
+		}
+	}
+
+	private static void initializeGitRepository() throws ServletException {
+		XacmlAdminUI.repositoryPath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_ADMIN_REPOSITORY));
+		FileRepositoryBuilder builder = new FileRepositoryBuilder();
+		try {
+			XacmlAdminUI.repository = builder.setGitDir(XacmlAdminUI.repositoryPath.toFile()).readEnvironment().findGitDir().setBare().build();
+			if (Files.notExists(XacmlAdminUI.repositoryPath) || Files.notExists(Paths.get(XacmlAdminUI.repositoryPath.toString(), "HEAD"))) {
+				//
+				// Create it if it doesn't exist. As a bare repository
+				//
+				logger.info("Creating bare git repository: " + XacmlAdminUI.repositoryPath.toString());
+				XacmlAdminUI.repository.create();
+				//
+				// Add the magic file so remote works.
+				//
+				Path daemon = Paths.get(XacmlAdminUI.repositoryPath.toString(), "git-daemon-export-ok");
+				Files.createFile(daemon);					
+			}
+		} catch (IOException e) {
+			logger.error("Failed to build repository: " + repository, e);
+			throw new ServletException(e.getMessage(), e.getCause());
+		}
+		//
+		// Make sure the workspace directory is created
+		//
+		Path workspace = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_ADMIN_WORKSPACE));
+		workspace = workspace.toAbsolutePath();
+		if (Files.notExists(workspace)) {
+			try {
+				Files.createDirectory(workspace);
+			} catch (IOException e) {
+				logger.error("Failed to build workspace: " + workspace, e);
+				throw new ServletException(e.getMessage(), e.getCause());
+			}
+		}
+		//
+		// Create the user workspace directory
+		//
+		workspace = Paths.get(workspace.toString(), "pe");
+		if (Files.notExists(workspace)) {
+			try {
+				Files.createDirectory(workspace);
+			} catch (IOException e) {
+				logger.error("Failed to create directory: " + workspace, e);
+				throw new ServletException(e.getMessage(), e.getCause());
+			}
+		}
+		//
+		// Get the path to where the repository is going to be
+		//
+		Path gitPath = Paths.get(workspace.toString(), XacmlAdminUI.repositoryPath.getFileName().toString());
+		if (Files.notExists(gitPath)) {
+			try {
+				Files.createDirectory(gitPath);
+			} catch (IOException e) {
+				logger.error("Failed to create directory: " + gitPath, e);
+				throw new ServletException(e.getMessage(), e.getCause());
+			}
+		}
+		//
+		// Initialize the domain structure
+		//
+		String base = null;
+		String domain = XacmlAdminUI.getDomain();
+		if (domain != null) {
+			for (String part : Splitter.on(':').trimResults().split(domain)) {
+				if (base == null) {
+					base = part;
+				}
+				Path subdir = Paths.get(gitPath.toString(), part);
+				if (Files.notExists(subdir)) {
+					try {
+						Files.createDirectory(subdir);
+						Files.createFile(Paths.get(subdir.toString(), ".svnignore"));
+					} catch (IOException e) {
+						logger.error("Failed to create: " + subdir, e);
+						throw new ServletException(e.getMessage(), e.getCause());
+					}
+				}
+			}
+		} else {
+			try {
+				Files.createFile(Paths.get(workspace.toString(), ".svnignore"));
+				base = ".svnignore";
+			} catch (IOException e) {
+				logger.error("Failed to create file", e);
+				throw new ServletException(e.getMessage(), e.getCause());
+			}
+		}
+		try {
+			//
+			// These are the sequence of commands that must be done initially to
+			// finish setting up the remote bare repository.
+			//
+			Git git = Git.init().setDirectory(gitPath.toFile()).setBare(false).call();
+			git.add().addFilepattern(base).call();
+			git.commit().setMessage("Initialize Bare Repository").call();
+			StoredConfig config = git.getRepository().getConfig();
+			config.setString("remote", "origin", "url", XacmlAdminUI.repositoryPath.toAbsolutePath().toString());
+			config.setString("remote", "origin", "fetch", "+refs/heads/*:refs/remotes/origin/*");
+			config.save();
+			git.push().setRemote("origin").add("master").call();
+			/*
+			 * This will not work unless git.push().setRemote("origin").add("master").call();
+			 * is called first. Otherwise it throws an exception. However, if the push() is
+			 * called then calling this function seems to add nothing.
+			 * 
+			git.branchCreate().setName("master")
+				.setUpstreamMode(SetupUpstreamMode.SET_UPSTREAM)
+				.setStartPoint("origin/master").setForce(true).call();
+			*/
+		} catch (GitAPIException | IOException e) {
+			logger.error(e);
+			throw new ServletException(e.getMessage(), e.getCause());
+		}
+	}
+
+	/**
+	 * Initializes a user's git repository.
+	 * 
+	 * 
+	 * @param workspacePath
+	 * @param userId
+	 * @param email
+	 * @return
+	 * @throws IOException
+	 * @throws InvalidRemoteException
+	 * @throws TransportException
+	 * @throws GitAPIException
+	 */
+	private static Path initializeUserRepository(Path workspacePath, String userId, URI email) throws IOException, InvalidRemoteException, TransportException, GitAPIException {
+		Path gitPath = null;
+		//
+		// Initialize the User's Git repository
+		//
+		if (Files.notExists(workspacePath)) {
+			logger.info("Creating user workspace: " + workspacePath.toAbsolutePath().toString());
+			//
+			// Create our user's directory
+			//
+			Files.createDirectory(workspacePath);
+		}
+		gitPath = Paths.get(workspacePath.toString(), XacmlAdminUI.repositoryPath.getFileName().toString());
+		if (Files.notExists(gitPath)) {
+			//
+			// It doesn't exist yet, so Clone it and check it out
+			//
+			logger.info("Cloning user git directory: " + gitPath.toAbsolutePath().toString());
+			Git.cloneRepository().setURI(XacmlAdminUI.repositoryPath.toUri().toString())
+							.setDirectory(gitPath.toFile())
+							.setNoCheckout(false)
+							.call();
+			//
+			// Set userid
+			//
+			Git git = Git.open(gitPath.toFile());
+			StoredConfig config = git.getRepository().getConfig();
+			config.setString("user", null, "name", userId);
+			if (email != null && email.getPath() != null) {
+				config.setString("user", null, "email", email.toString());
+			}
+			config.save();
+		}
+		return gitPath;
+	}
+
+
+	public static String	getDomain() {
+		return XACMLProperties.getProperty(XACMLRestProperties.PROP_ADMIN_DOMAIN, "urn");
+	}
+	
+	public static JDBCConnectionPool	getConnectionPool() {
+		return pool;
+	}
+	
+	public SQLContainer	getMatchFunctionContainer() {
+		return this.matchFunctionContainer;
+	}
+	
+	public SQLContainer getHigherOrderBagContainer() {
+		return this.higherorderBagContainer;
+	}
+	
+	public EntityManager getEntityManager() {
+		return this.em;
+	}
+	
+	public JPAContainer<Attribute>	getAttributes() {
+		return this.attributes;
+	}
+	
+	public void refreshAttributes() {
+		this.attributes.refresh();
+		this.console.refreshAttributes();
+	}
+
+	public JPAContainer<ConstraintType>	getConstraintTypes() {
+		return this.constraintTypes;
+	}
+	
+	public JPAContainer<Category>	getCategories() {
+		return this.categories;
+	}
+	
+	public JPAContainer<Datatype>	getDatatypes() {
+		return this.datatypes;
+	}
+
+	public JPAContainer<PolicyAlgorithms> getPolicyAlgorithms() {
+		return this.policyAlgorithms;
+	}
+	
+	public JPAContainer<RuleAlgorithms> getRuleAlgorithms() {
+		return this.ruleAlgorithms;
+	}
+
+	public JPAContainer<Obadvice> getObadvice() {
+		return this.obadvice;
+	}
+
+	public JPAContainer<ObadviceExpression> getObadviceExpressions() {
+		return this.obadviceExpressions;
+	}
+	
+	public void refreshObadvice() {
+		this.obadvice.refresh();
+		this.obadviceExpressions.refresh();
+		this.console.refreshObadvice();
+	}
+
+	public JPAContainer<FunctionDefinition>	getFunctionDefinitions() {
+		return this.functionDefinitions;
+	}
+	
+	public JPAContainer<FunctionArgument> getFunctionArguments() {
+		return this.functionArguments;
+	}
+	
+	public JPAContainer<PIPConfiguration> getPIPConfigurations() {
+		return this.pipConfigurations;
+	}
+	
+	public JPAContainer<PIPResolver>	getPIPResolvers() {
+		return this.pipResolvers;
+	}
+	
+	public JPAContainer<PIPType>	getPIPTypes() {
+		return this.pipTypes;
+	}
+
+	public void refreshPIPConfiguration() {
+		this.pipConfigurations.refresh();
+		this.console.refreshPIPConfiguration();
+	}
+	
+	public Category	getDefaultCategory() throws Exception {
+		for (Object id : categories.getItemIds()) {
+			Category cat = categories.getItem(id).getEntity();
+			if (cat.getIdentifer().equals(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT)) {
+				return cat;
+			}
+		}
+		throw new Exception("There is no default category.");
+	}
+	
+	public Datatype getDefaultDatatype() throws Exception {
+		for (Object id: this.datatypes.getItemIds()) {
+			Datatype dt = this.datatypes.getItem(id).getEntity();
+			if (dt.getIdentifer().equals(XACML3.ID_DATATYPE_STRING)) {
+				return dt;
+			}
+		}
+		throw new Exception("There is no default datatype.");
+	}
+	
+	public XacmlAdminAuthorization getAuthorizer() {
+		return this.authorizer;
+	}
+	
+	public boolean	isAuthorized(AdminAction action, AdminResource resource) {
+		return this.authorizer.isAuthorized(this.getUserid(), action, resource);
+	}
+	
+	public String	getUserid() {
+		Object id = this.getSession().getSession().getAttribute("xacml.rest.admin.user.id");
+		if (id == null) {
+			return XACMLProperties.getProperty("xacml.rest.admin.user.id", "guest");
+		}
+		String str = id.toString();
+		if (str == null || str.isEmpty()) {
+			return "guest";
+		}
+		return str;
+	}
+	
+	public String 	getUserName() {
+		Object id = this.getSession().getSession().getAttribute("xacml.rest.admin.user.name");
+		if (id == null) {
+			return XACMLProperties.getProperty("xacml.rest.admin.user.name", "guest");
+		}
+		String str = id.toString();
+		if (str == null || str.isEmpty()) {
+			return "guest";
+		}
+		return str;
+	}
+	
+	public URI		getUserEmail() {
+		Object id = this.getSession().getSession().getAttribute("xacml.rest.admin.user.email");
+		if (id == null) {
+			return URI.create(XACMLProperties.getProperty("xacml.rest.admin.user.email", "guest"));
+		}
+		String str = id.toString();
+		if (str == null || str.isEmpty()) {
+			return null;
+		}
+		return URI.create(str);
+	}
+	
+	public Path		getUserWorkspace() {
+		return this.workspacePath;
+	}
+	
+	public Path		getUserGitPath() {
+		return this.gitPath;
+	}
+	
+	public PAPEngine	getPAPEngine() {
+		return this.papEngine;
+	}
+	
+	public String	newPolicyID() {
+		return Joiner.on(':').skipNulls().join((XacmlAdminUI.getDomain().startsWith("urn") ? null : "urn"),
+												XacmlAdminUI.getDomain().replaceAll("[/\\\\.]", ":"), 
+												"xacml", "policy", "id", UUID.randomUUID());
+	}
+
+	public String	newRuleID() {
+		return Joiner.on(':').skipNulls().join((XacmlAdminUI.getDomain().startsWith("urn") ? null : "urn"),
+												XacmlAdminUI.getDomain().replaceAll("[/\\\\.]", ":"), 
+												"xacml", "rule", "id", UUID.randomUUID());
+	}
+	//
+	// PAPNotificationBroadcaster Interface implementation
+	//
+	/**
+	 * Got a notification that the PAP has changed the PDP data,
+	 * so update ALL PDPGroups.
+	 * This is called once for each Vaadin instance for each PAP change Notification.
+	 */
+	public void updateAllGroups() {
+		access(new Runnable() {
+			@Override
+			public void run() {
+				//
+				// locking is needed to avoid race conditions.
+				// Shows up as Exception: "A connector should not be marked as dirty while a response is being written."
+				//
+				getUI().getSession().lock();
+				try {
+					//
+					// Tell the console to refresh its PDP group information
+					//
+					console.refreshPDPGroups();
+				} finally {
+					getUI().getSession().unlock();
+				}
+			}
+		});
+	}
+}
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/XacmlErrorHandler.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/XacmlErrorHandler.java
new file mode 100644
index 0000000..dd014dd
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/XacmlErrorHandler.java
@@ -0,0 +1,106 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ *
+ */
+
+package org.apache.openaz.xacml.admin;
+
+import com.vaadin.annotations.AutoGenerated;
+import com.vaadin.navigator.View;
+import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent;
+import com.vaadin.ui.Alignment;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.CustomComponent;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.VerticalLayout;
+
+public class XacmlErrorHandler extends CustomComponent implements View {
+	
+	@AutoGenerated
+	private VerticalLayout mainLayout;
+
+	@AutoGenerated
+	private Button buttonGo;
+
+	@AutoGenerated
+	private Label labelError;
+
+	public static String VIEWNAME="ErrorHandler.View";
+
+	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */
+
+	private static final long serialVersionUID = 1L;
+	/**
+	 * The constructor should first build the main layout, set the
+	 * composition root and then do any custom initialization.
+	 *
+	 * The constructor will not be automatically regenerated by the
+	 * visual editor.
+	 */
+	public XacmlErrorHandler(String message, String button) {
+		buildMainLayout();
+		setCompositionRoot(mainLayout);
+		this.labelError.setValue(message);
+		if (button != null) {
+			this.buttonGo.setCaption(button);
+		} else {
+			this.buttonGo.setVisible(false);
+		}
+	}
+
+	@Override
+	public void enter(ViewChangeEvent event) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	@AutoGenerated
+	private VerticalLayout buildMainLayout() {
+		// common part: create layout
+		mainLayout = new VerticalLayout();
+		mainLayout.setImmediate(false);
+		mainLayout.setWidth("100%");
+		mainLayout.setHeight("-1px");
+		mainLayout.setMargin(true);
+		mainLayout.setSpacing(true);
+		
+		// top-level component properties
+		setWidth("100.0%");
+		setHeight("-1px");
+		
+		// labelError
+		labelError = new Label();
+		labelError.setImmediate(false);
+		labelError.setWidth("100.0%");
+		labelError.setHeight("80px");
+		labelError.setValue("This holds error messages.");
+		mainLayout.addComponent(labelError);
+		
+		// buttonGo
+		buttonGo = new Button();
+		buttonGo.setCaption("Ok");
+		buttonGo.setImmediate(true);
+		buttonGo.setWidth("-1px");
+		buttonGo.setHeight("-1px");
+		mainLayout.addComponent(buttonGo);
+		mainLayout.setComponentAlignment(buttonGo, new Alignment(48));
+		
+		return mainLayout;
+	}
+
+}
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/XacmlJDBCConnectionPool.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/XacmlJDBCConnectionPool.java
new file mode 100644
index 0000000..a11707d
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/XacmlJDBCConnectionPool.java
@@ -0,0 +1,239 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ *
+ */
+
+package org.apache.openaz.xacml.admin;
+
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool;
+
+public class XacmlJDBCConnectionPool implements JDBCConnectionPool {
+	private static final long serialVersionUID = 1L;
+	private static Log logger	= LogFactory.getLog(XacmlJDBCConnectionPool.class);
+
+    private int initialConnections = 5;
+    private int maxConnections = 300;
+
+    private String driverName;
+    private String connectionUri;
+    private String userName;
+    private String password;
+
+    private transient Set<Connection> availableConnections;
+    private transient Set<Connection> reservedConnections;
+
+    private boolean initialized;
+
+    public XacmlJDBCConnectionPool(String driverName, String connectionUri, String userName, String password) throws SQLException {
+        if (driverName == null) {
+            throw new IllegalArgumentException(
+                    "JDBC driver class name must be given.");
+        }
+        if (connectionUri == null) {
+            throw new IllegalArgumentException(
+                    "Database connection URI must be given.");
+        }
+        if (userName == null) {
+            throw new IllegalArgumentException(
+                    "Database username must be given.");
+        }
+        if (password == null) {
+            throw new IllegalArgumentException(
+                    "Database password must be given.");
+        }
+        this.driverName = driverName;
+        this.connectionUri = connectionUri;
+        this.userName = userName;
+        this.password = password;
+
+        /* Initialize JDBC driver */
+        try {
+            Class.forName(driverName).newInstance();
+        } catch (Exception ex) {
+            throw new RuntimeException("Specified JDBC Driver: " + driverName
+                    + " - initialization failed.", ex);
+        }
+    }
+
+    public XacmlJDBCConnectionPool(String driverName, String connectionUri,
+            String userName, String password, int initialConnections,
+            int maxConnections) throws SQLException {
+        this(driverName, connectionUri, userName, password);
+        this.initialConnections = initialConnections;
+        this.maxConnections = maxConnections;
+    }
+
+    private void initializeConnections() throws SQLException {
+        availableConnections = new HashSet<Connection>(initialConnections);
+        reservedConnections = new HashSet<Connection>(initialConnections);
+        for (int i = 0; i < initialConnections; i++) {
+            availableConnections.add(createConnection());
+        }
+        initialized = true;
+    }
+
+    @Override
+    public synchronized Connection reserveConnection() throws SQLException {
+        if (!initialized) {
+            initializeConnections();
+        }
+        Connection c = null;
+        do {
+	        if (availableConnections.isEmpty()) {
+	            if (reservedConnections.size() < maxConnections) {
+	            	logger.info("creating new connection");
+	                availableConnections.add(createConnection());
+	            } else {
+	                throw new SQLException("Connection limit has been reached.");
+	            }
+	        }
+	        //
+	        // Get first available
+	        //
+	        c = availableConnections.iterator().next();
+	        //
+	        // It is still valid?
+	        //
+	        if (!this.isValid(c)) {
+	        	try {
+	        		logger.warn("Removing invalid connection.");
+		        	//
+		        	// No close it
+		        	//
+	        		c.close();
+	        		//
+	        		// Remove from our list
+	        		//
+	        		this.availableConnections.remove(c);
+	        		//
+	        		// Try again
+	        		//
+	        		c = null;
+	        	} catch (SQLException e) { // NOPMD
+	        		// If removing the connection fails, ignore
+	        	}
+	        } else {
+	        	//
+	        	// Yes
+	        	//
+		        availableConnections.remove(c);
+	        	break;
+	        }
+        } while (c == null);
+        //
+        // Add it to our reserved list
+        //
+        reservedConnections.add(c);
+        return c;
+    }
+
+    @Override
+    public synchronized void releaseConnection(Connection conn) {
+        if (conn == null || !initialized) {
+            return;
+        }
+        /* Try to roll back if necessary */
+        try {
+            if (!conn.getAutoCommit()) {
+                conn.rollback();
+            }
+        } catch (SQLException e) {
+            /* Roll back failed, close and discard connection */
+            try {
+                conn.close();
+            } catch (SQLException e1) { // NOPMD
+                /* Nothing needs to be done */
+            }
+            reservedConnections.remove(conn);
+            return;
+        }
+        reservedConnections.remove(conn);
+        availableConnections.add(conn);
+    }
+
+    private Connection createConnection() throws SQLException {
+        Connection c = DriverManager.getConnection(connectionUri, userName,
+                password);
+        c.setAutoCommit(false);
+        if (driverName.toLowerCase().contains("mysql")) {
+            try {
+                Statement s = c.createStatement();
+                s.execute("SET SESSION sql_mode = 'ANSI'");
+                s.close();
+            } catch (Exception e) { // NOPMD
+                // Failed to set ansi mode; continue
+            }
+        }
+        return c;
+    }
+
+    @Override
+    public void destroy() {
+        for (Connection c : availableConnections) {
+            try {
+                c.close();
+            } catch (SQLException e) { // NOPMD
+                // No need to do anything
+            }
+        }
+        for (Connection c : reservedConnections) {
+            try {
+                c.close();
+            } catch (SQLException e) { // NOPMD
+                // No need to do anything
+            }
+        }
+
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws IOException {
+        initialized = false;
+        out.defaultWriteObject();
+    }
+
+	private final boolean isValid(final Connection con) throws SQLException {
+		final String bogusQuery = "SELECT 1";
+		
+		try (Statement st = con.createStatement(); ResultSet res = st.executeQuery(bogusQuery)) {
+			return true;
+		} catch (final SQLException sqlx) {
+			return false;
+		}
+	}
+
+	@Override
+	public String toString() {
+		return "XacmlJDBCConnectionPool [initialConnections="
+				+ initialConnections + ", maxConnections=" + maxConnections
+				+ ", driverName=" + driverName + ", connectionUri="
+				+ connectionUri + ", userName=" + userName + ", password="
+				+ password + ", initialized=" + initialized + "]";
+	}
+}
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/components/AttributeDictionary.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/components/AttributeDictionary.java
new file mode 100644
index 0000000..f0069a7
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/components/AttributeDictionary.java
@@ -0,0 +1,503 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ *
+ */
+
+package org.apache.openaz.xacml.admin.components;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.openaz.xacml.admin.XacmlAdminAuthorization;
+import org.apache.openaz.xacml.admin.XacmlAdminUI;
+import org.apache.openaz.xacml.admin.jpa.Attribute;
+import org.apache.openaz.xacml.admin.jpa.Category;
+import org.apache.openaz.xacml.admin.jpa.Datatype;
+import org.apache.openaz.xacml.admin.view.windows.AttributeEditorWindow;
+import com.vaadin.addon.jpacontainer.EntityItem;
+import com.vaadin.addon.jpacontainer.JPAContainer;
+import com.vaadin.addon.jpacontainer.provider.CachingLocalEntityProvider;
+import com.vaadin.addon.jpacontainer.provider.CachingMutableLocalEntityProvider;
+import com.vaadin.annotations.AutoGenerated;
+import com.vaadin.data.Container.Filter;
+import com.vaadin.data.Item;
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.data.Property.ValueChangeListener;
+import com.vaadin.data.util.filter.Compare;
+import com.vaadin.event.ItemClickEvent;
+import com.vaadin.event.ItemClickEvent.ItemClickListener;
+import com.vaadin.ui.Alignment;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.AbstractSelect.ItemCaptionMode;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Button.ClickListener;
+import com.vaadin.ui.ComboBox;
+import com.vaadin.ui.CustomComponent;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.Table;
+import com.vaadin.ui.UI;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.Window.CloseEvent;
+import com.vaadin.ui.Window.CloseListener;
+
+public class AttributeDictionary extends CustomComponent {
+	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */
+
+	@AutoGenerated
+	private VerticalLayout mainLayout;
+	@AutoGenerated
+	private Table table;
+	@AutoGenerated
+	private HorizontalLayout horizontalLayoutToolbar;
+	@AutoGenerated
+	private ComboBox comboBoxFilterDatatype;
+	@AutoGenerated
+	private ComboBox comboBoxFilterCategory;
+	@AutoGenerated
+	private Button buttonClone;
+	@AutoGenerated
+	private Button buttonRemove;
+	@AutoGenerated
+	private Button buttonNew;
+	private static final long serialVersionUID = 4553719412188869190L;
+	private static final Log logger	= LogFactory.getLog(AttributeDictionary.class);
+	private static final Object[] visibleColumns = new Object[] { "xacmlId", "description", "categoryBean", "datatypeBean", "constraintType", "modifiedBy", "modifiedDate", "createdBy", "createdDate"};
+	private static final String[] columnHeaders = new String[] { "Attribute ID", "Description", "Category", "DataType", "Constraint", "Modified By", "Modified Date", "Created By", "Created Date"};
+	
+	private AttributeDictionary self = this;
+
+	private final JPAContainer<Attribute> attributes = new JPAContainer<Attribute>(Attribute.class);
+	private final JPAContainer<Category> categories = new JPAContainer<Category>(Category.class);
+	private final JPAContainer<Datatype> datatypes = new JPAContainer<Datatype>(Datatype.class);
+	
+	/**
+	 * The constructor should first build the main layout, set the
+	 * composition root and then do any custom initialization.
+	 *
+	 * The constructor will not be automatically regenerated by the
+	 * visual editor.
+	 */
+	public AttributeDictionary() {
+		buildMainLayout();
+		setCompositionRoot(mainLayout);
+		//
+		// Finish initializing the container
+		//
+		boolean isReadOnly;
+		if (((XacmlAdminUI)UI.getCurrent()).isAuthorized( 
+				XacmlAdminAuthorization.AdminAction.ACTION_WRITE, 
+				XacmlAdminAuthorization.AdminResource.RESOURCE_DICTIONARIES)) {
+			if (logger.isDebugEnabled()) {
+				logger.debug("write access");
+			}
+			//
+			// Make it mutable
+			//
+			isReadOnly = false;
+			this.attributes.setEntityProvider(new CachingMutableLocalEntityProvider<Attribute>(Attribute.class, ((XacmlAdminUI)UI.getCurrent()).getEntityManager()));
+		} else {
+			if (logger.isDebugEnabled()) {
+				logger.debug("read access");
+			}
+			//
+			// Make it read-only
+			//
+			isReadOnly = true;
+			this.attributes.setEntityProvider(new CachingLocalEntityProvider<Attribute>(Attribute.class, ((XacmlAdminUI)UI.getCurrent()).getEntityManager()));
+		}
+		this.categories.setEntityProvider(new CachingLocalEntityProvider<Category>(Category.class, ((XacmlAdminUI)UI.getCurrent()).getEntityManager()));
+		this.categories.sort(new String[]{"xacmlId"}, new boolean[]{true});
+		this.datatypes.setEntityProvider(new CachingLocalEntityProvider<Datatype>(Datatype.class, ((XacmlAdminUI)UI.getCurrent()).getEntityManager()));
+		this.datatypes.sort(new String[]{"xacmlId"}, new boolean[]{true});
+		//
+		// Initialize
+		//
+		this.initializeTable(isReadOnly);
+		this.initializeButtons(isReadOnly);
+		this.initializeCategoryComboFilter();
+		this.initializeDatatypeComboFilter();
+	}
+	
+	protected void initializeTable(boolean isReadOnly) {
+		//
+		// This is the data source
+		//
+		this.table.setContainerDataSource(this.attributes);
+		//
+		// Setup table
+		//
+		this.table.setVisibleColumns(visibleColumns);
+		this.table.setColumnHeaders(columnHeaders);
+		this.table.setImmediate(true);
+		this.table.setColumnCollapsingAllowed(true);
+		//
+		// Read only?
+		//
+		if (isReadOnly) {
+			if (logger.isDebugEnabled()) {
+				logger.debug("read only table");
+			}
+			return;
+		}
+		this.table.setSelectable(true);
+		//
+		// Respond to clicks
+		//
+		this.table.addItemClickListener(new ItemClickListener() {
+			private static final long serialVersionUID = 1L;
+			@Override
+			public void itemClick(ItemClickEvent event) {
+				if (event.isDoubleClick()) {
+					//
+					// Create our editor window
+					//
+					final AttributeEditorWindow attributeEditor = new AttributeEditorWindow(self.attributes.getItem(event.getItemId()));
+					attributeEditor.setCaption("Edit Attribute");
+					attributeEditor.setModal(true);
+					attributeEditor.center();
+					UI.getCurrent().addWindow(attributeEditor);
+				}
+			}
+		});
+		//
+		// Respond to selections
+		//
+		this.table.addValueChangeListener(new ValueChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void valueChange(ValueChangeEvent event) {
+				Object value = self.table.getValue();
+				if (value == null) {
+					self.buttonRemove.setEnabled(false);
+					self.buttonClone.setEnabled(false);
+				} else {
+					self.buttonRemove.setEnabled(true);
+					self.buttonClone.setEnabled(true);
+				}
+			}
+		});
+	}
+	
+	protected void initializeButtons(boolean isReadOnly) {
+		if (isReadOnly) {
+			this.buttonNew.setVisible(false);
+			this.buttonRemove.setVisible(false);
+			this.buttonClone.setVisible(false);
+			return;
+		}
+		this.buttonNew.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				AttributeDictionary.createNewAttributeWindow();
+			}
+			
+		});
+		
+		this.buttonRemove.setEnabled(false);
+		this.buttonRemove.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				//
+				// Get the selected item
+				//
+				Object id = self.table.getValue();
+				//
+				// Sanity check
+				//
+				if (id == null) {
+					return;
+				}
+				//
+				// Remove the attribute
+				//
+				self.attributes.removeItem(id);
+				//
+				// Unfortunately, removing the item does NOT result
+				// in a ValueChange event being generated. So we must
+				// trigger it ourselves.
+				//
+				self.table.select(self.table.getNullSelectionItemId());
+			}	
+		});
+		
+		this.buttonClone.setEnabled(false);
+		this.buttonClone.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				Object id = self.table.getValue();
+				if (id == null) {
+					return;
+				}
+				Item item = self.table.getItem(id);
+				if (item instanceof EntityItem) {
+					@SuppressWarnings("unchecked")
+					//
+					// Get the entity
+					//
+					EntityItem<Attribute> entityItem = (EntityItem<Attribute>) item;
+					//
+					// Clone it
+					//
+					Attribute newAttribute = new Attribute(entityItem.getEntity(), ((XacmlAdminUI)UI.getCurrent()).getUserid());
+					//
+					// Add it to the database
+					//
+					id = self.attributes.addEntity(newAttribute);
+					//
+					// Now select it
+					//
+					self.table.select(id);
+					//
+					// Refresh it to get the latest modified date
+					//
+					self.attributes.refreshItem(id);
+				}
+			}
+		});
+	}
+
+	protected void initializeCategoryComboFilter() {
+		//
+		// Set data source
+		//
+		this.comboBoxFilterCategory.setContainerDataSource(self.categories);
+		this.comboBoxFilterCategory.setItemCaptionMode(ItemCaptionMode.PROPERTY);
+		this.comboBoxFilterCategory.setItemCaptionPropertyId("xacmlId");
+		//
+		// Initialize GUI properties
+		//
+		this.comboBoxFilterCategory.setNullSelectionAllowed(true);
+		this.comboBoxFilterCategory.setImmediate(true);
+		//
+		// Respond to value changes
+		//
+		this.comboBoxFilterCategory.addValueChangeListener(new ValueChangeListener() {
+			private static final long serialVersionUID = 1L;
+			Filter currentFilter = null;
+
+			@Override
+			public void valueChange(ValueChangeEvent event) {
+				//
+				// Remove filter
+				//
+				if (currentFilter != null) {
+					self.attributes.removeContainerFilter(this.currentFilter);
+					this.currentFilter = null;
+				}
+				//
+				// Set the new one
+				//
+				Object id = self.comboBoxFilterCategory.getValue();
+				if (id == null) {
+					return;
+				}
+				Category cat = self.categories.getItem(id).getEntity();
+				this.currentFilter = new Compare.Equal("categoryBean", cat);
+				self.attributes.addContainerFilter(this.currentFilter);
+			}
+		});
+	}
+	
+	protected void initializeDatatypeComboFilter() {
+		//
+		// Set data source
+		//
+		this.comboBoxFilterDatatype.setContainerDataSource(self.datatypes);
+		this.comboBoxFilterDatatype.setItemCaptionMode(ItemCaptionMode.PROPERTY);
+		this.comboBoxFilterDatatype.setItemCaptionPropertyId("xacmlId");
+		//
+		// Initialize GUI properties
+		//
+		this.comboBoxFilterDatatype.setNullSelectionAllowed(true);
+		this.comboBoxFilterDatatype.setImmediate(true);
+		//
+		// Respond to value changes
+		//
+		this.comboBoxFilterDatatype.addValueChangeListener(new ValueChangeListener() {
+			private static final long serialVersionUID = 1L;
+			Filter currentFilter = null;
+
+			@Override
+			public void valueChange(ValueChangeEvent event) {
+				//
+				// Remove filter
+				//
+				if (currentFilter != null) {
+					self.attributes.removeContainerFilter(this.currentFilter);
+					this.currentFilter = null;
+				}
+				//
+				// Set the new one
+				//
+				Object id = self.comboBoxFilterDatatype.getValue();
+				if (id == null) {
+					return;
+				}
+				Datatype cat = self.datatypes.getItem(id).getEntity();
+				this.currentFilter = new Compare.Equal("datatypeBean", cat);
+				self.attributes.addContainerFilter(this.currentFilter);
+			}
+		});
+	}
+	
+	public void refreshContainer() {
+		this.attributes.refresh();
+		this.categories.refresh();
+		this.datatypes.refresh();
+	}
+	
+	public static void createNewAttributeWindow() {
+		//
+		// Create our new attribute
+		//
+		String domain = XacmlAdminUI.getDomain();
+		String userid = ((XacmlAdminUI)UI.getCurrent()).getUserid();
+		final Attribute newAttribute = new Attribute(domain, userid);
+		try {
+			newAttribute.setCategoryBean(((XacmlAdminUI)UI.getCurrent()).getDefaultCategory());
+			newAttribute.setDatatypeBean(((XacmlAdminUI)UI.getCurrent()).getDefaultDatatype());
+		} catch (Exception e) {
+			logger.error(e);
+			return;
+		}
+		//
+		// Create our editor window
+		//
+		final AttributeEditorWindow attributeEditor = new AttributeEditorWindow(((XacmlAdminUI)UI.getCurrent()).getAttributes().createEntityItem(newAttribute));
+		attributeEditor.setCaption("Add New Attribute");
+		attributeEditor.setModal(true);
+		attributeEditor.addCloseListener(new CloseListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void windowClose(CloseEvent e) {
+				//
+				// Did the user hit save?
+				//
+				if (attributeEditor.isSaved()) {
+					//
+					// Add the new attribute
+					//
+					((XacmlAdminUI)UI.getCurrent()).getAttributes().addEntity(newAttribute);
+					((XacmlAdminUI)UI.getCurrent()).refreshAttributes();
+				}
+			}
+			
+		});
+		attributeEditor.center();
+		UI.getCurrent().addWindow(attributeEditor);
+	}
+
+	@AutoGenerated
+	private VerticalLayout buildMainLayout() {
+		// common part: create layout
+		mainLayout = new VerticalLayout();
+		mainLayout.setImmediate(false);
+		mainLayout.setWidth("-1px");
+		mainLayout.setHeight("-1px");
+		mainLayout.setMargin(true);
+		mainLayout.setSpacing(true);
+		
+		// top-level component properties
+		setWidth("-1px");
+		setHeight("-1px");
+		
+		// horizontalLayoutToolbar
+		horizontalLayoutToolbar = buildHorizontalLayoutToolbar();
+		mainLayout.addComponent(horizontalLayoutToolbar);
+		
+		// table
+		table = new Table();
+		table.setImmediate(false);
+		table.setWidth("100.0%");
+		table.setHeight("-1px");
+		mainLayout.addComponent(table);
+		
+		return mainLayout;
+	}
+
+	@AutoGenerated
+	private HorizontalLayout buildHorizontalLayoutToolbar() {
+		// common part: create layout
+		horizontalLayoutToolbar = new HorizontalLayout();
+		horizontalLayoutToolbar.setImmediate(false);
+		horizontalLayoutToolbar.setWidth("-1px");
+		horizontalLayoutToolbar.setHeight("-1px");
+		horizontalLayoutToolbar.setMargin(false);
+		horizontalLayoutToolbar.setSpacing(true);
+		
+		// buttonNew
+		buttonNew = new Button();
+		buttonNew.setCaption("New");
+		buttonNew.setImmediate(true);
+		buttonNew.setDescription("Create a new attribute");
+		buttonNew.setWidth("70px");
+		buttonNew.setHeight("-1px");
+		horizontalLayoutToolbar.addComponent(buttonNew);
+		horizontalLayoutToolbar.setComponentAlignment(buttonNew, new Alignment(
+				9));
+		
+		// buttonRemove
+		buttonRemove = new Button();
+		buttonRemove.setCaption("Remove");
+		buttonRemove.setImmediate(true);
+		buttonRemove.setDescription("Remove the selected attribute(s)");
+		buttonRemove.setWidth("-1px");
+		buttonRemove.setHeight("-1px");
+		horizontalLayoutToolbar.addComponent(buttonRemove);
+		horizontalLayoutToolbar.setComponentAlignment(buttonRemove,
+				new Alignment(9));
+		
+		// buttonClone
+		buttonClone = new Button();
+		buttonClone.setCaption("Clone");
+		buttonClone.setImmediate(true);
+		buttonClone.setDescription("Clone an attribute.");
+		buttonClone.setWidth("-1px");
+		buttonClone.setHeight("-1px");
+		horizontalLayoutToolbar.addComponent(buttonClone);
+		horizontalLayoutToolbar.setComponentAlignment(buttonClone,
+				new Alignment(9));
+		
+		// comboBoxFilterCategory
+		comboBoxFilterCategory = new ComboBox();
+		comboBoxFilterCategory.setCaption("Filter By Category");
+		comboBoxFilterCategory.setImmediate(false);
+		comboBoxFilterCategory.setWidth("-1px");
+		comboBoxFilterCategory.setHeight("-1px");
+		horizontalLayoutToolbar.addComponent(comboBoxFilterCategory);
+		
+		// comboBoxFilterDatatype
+		comboBoxFilterDatatype = new ComboBox();
+		comboBoxFilterDatatype.setCaption("Filter By Data Type");
+		comboBoxFilterDatatype.setImmediate(false);
+		comboBoxFilterDatatype.setWidth("-1px");
+		comboBoxFilterDatatype.setHeight("-1px");
+		horizontalLayoutToolbar.addComponent(comboBoxFilterDatatype);
+		
+		return horizontalLayoutToolbar;
+	}
+
+}
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/components/ObadviceDictionary.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/components/ObadviceDictionary.java
new file mode 100644
index 0000000..1b1edd4
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/components/ObadviceDictionary.java
@@ -0,0 +1,347 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ *
+ */
+
+package org.apache.openaz.xacml.admin.components;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.openaz.xacml.admin.XacmlAdminAuthorization;
+import org.apache.openaz.xacml.admin.XacmlAdminUI;
+import org.apache.openaz.xacml.admin.jpa.Obadvice;
+import org.apache.openaz.xacml.admin.view.windows.ObadviceEditorWindow;
+import com.vaadin.addon.jpacontainer.EntityItem;
+import com.vaadin.addon.jpacontainer.JPAContainer;
+import com.vaadin.addon.jpacontainer.provider.CachingLocalEntityProvider;
+import com.vaadin.addon.jpacontainer.provider.CachingMutableLocalEntityProvider;
+import com.vaadin.annotations.AutoGenerated;
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.data.Property.ValueChangeListener;
+import com.vaadin.data.util.filter.Compare;
+import com.vaadin.event.ShortcutAction.KeyCode;
+import com.vaadin.ui.Alignment;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Button.ClickListener;
+import com.vaadin.ui.ComboBox;
+import com.vaadin.ui.CustomComponent;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.Table;
+import com.vaadin.ui.UI;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.Window.CloseEvent;
+import com.vaadin.ui.Window.CloseListener;
+
+public class ObadviceDictionary extends CustomComponent {
+	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */
+
+	@AutoGenerated
+	private VerticalLayout mainLayout;
+	@AutoGenerated
+	private Table table;
+	@AutoGenerated
+	private HorizontalLayout horizontalLayoutToolbar;
+	@AutoGenerated
+	private ComboBox comboBoxFilter;
+	@AutoGenerated
+	private Button buttonClone;
+	@AutoGenerated
+	private Button buttonRemove;
+	@AutoGenerated
+	private Button buttonNew;
+	private static final long serialVersionUID = 1L;
+	private static final Log logger	= LogFactory.getLog(ObadviceDictionary.class);
+	private final ObadviceDictionary self = this;
+	
+	private static final Object[] visibleColumns = new Object[] { "type", "xacmlId", "description", "fulfillOn", "modifiedBy", "modifiedDate", "createdBy", "createdDate"};
+	private static final String[] columnHeaders = new String[] { "Type", "Attribute ID", "Description", "FulFill/Apply", "Modified By", "Modified Date", "Created By", "Created Date"};
+	
+	private final JPAContainer<Obadvice>	obadvice  = new JPAContainer<Obadvice>(Obadvice.class);
+
+	/**
+	 * The constructor should first build the main layout, set the
+	 * composition root and then do any custom initialization.
+	 *
+	 * The constructor will not be automatically regenerated by the
+	 * visual editor.
+	 * @param jpaContainer 
+	 */
+	public ObadviceDictionary() {
+		buildMainLayout();
+		setCompositionRoot(mainLayout);
+		//
+		// Setup container
+		//
+		boolean isReadOnly;
+		if (((XacmlAdminUI)UI.getCurrent()).isAuthorized( 
+				XacmlAdminAuthorization.AdminAction.ACTION_WRITE, 
+				XacmlAdminAuthorization.AdminResource.RESOURCE_DICTIONARIES)) {
+			if (logger.isDebugEnabled()) {
+				logger.debug("write access");
+			}
+			isReadOnly = false;
+			this.obadvice.setEntityProvider(new CachingMutableLocalEntityProvider<Obadvice>(Obadvice.class, ((XacmlAdminUI)UI.getCurrent()).getEntityManager()));
+		} else {
+			if (logger.isDebugEnabled()) {
+				logger.debug("read only access");
+			}
+			isReadOnly = true;
+			this.obadvice.setEntityProvider(new CachingLocalEntityProvider<Obadvice>(Obadvice.class, ((XacmlAdminUI)UI.getCurrent()).getEntityManager()));
+		}
+		//
+		// initialize
+		//
+		this.initializeTable(isReadOnly);
+		this.initializeButtons(isReadOnly);
+		this.initializeCombo();
+	}
+	
+	protected void initializeTable(boolean isReadOnly) {
+		//
+		// Set our container
+		//
+		this.table.setContainerDataSource(this.obadvice);
+		//
+		// Initialize GUI properties
+		//
+		this.table.setVisibleColumns(visibleColumns);
+		this.table.setColumnHeaders(columnHeaders);
+		this.table.setImmediate(true);
+		this.table.setColumnCollapsingAllowed(true);
+		//
+		// Is read only
+		//
+		if (isReadOnly) {
+			return;
+		}
+		this.table.setSelectable(true);
+		//
+		// Respond to selections
+		//
+		this.table.addValueChangeListener(new ValueChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void valueChange(ValueChangeEvent event) {
+				self.buttonRemove.setEnabled(self.table.getValue() != null);
+				self.buttonClone.setEnabled(self.table.getValue() != null);
+			}			
+		});
+	}
+	
+	protected void initializeButtons(boolean isReadOnly) {
+		if (isReadOnly) {
+			this.buttonNew.setVisible(false);
+			this.buttonRemove.setVisible(false);
+			this.buttonClone.setVisible(false);
+			return;
+		}
+		//
+		// NEW button
+		//
+		this.buttonNew.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				//
+				// Create window
+				//
+				String domain = XacmlAdminUI.getDomain();
+				String userid = ((XacmlAdminUI)UI.getCurrent()).getUserid();
+				final Obadvice oa = new Obadvice(domain, userid);
+				final EntityItem<Obadvice> entity = self.obadvice.createEntityItem(oa);
+				final ObadviceEditorWindow editor = new ObadviceEditorWindow(entity);
+				editor.setCaption("Add New Obligation/Advice");
+				editor.setCloseShortcut(KeyCode.ESCAPE);
+				editor.setModal(true);
+				editor.addCloseListener(new CloseListener() {
+					private static final long serialVersionUID = 1L;
+
+					@Override
+					public void windowClose(CloseEvent e) {
+						if (editor.isSaved()) {
+							self.obadvice.addEntity(oa);
+							logger.info("Added new obligation/advice: " + oa);
+						}
+					}
+				});
+				editor.center();
+				UI.getCurrent().addWindow(editor);
+			}
+		});
+		//
+		// Disable remove/clone buttons to start
+		//
+		this.buttonRemove.setEnabled(false);
+		this.buttonClone.setEnabled(false);
+		//
+		// REMOVE button
+		//
+		this.buttonRemove.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				self.obadvice.removeItem(self.table.getValue());
+			}
+		});
+		//
+		// CLONE button
+		//
+		this.buttonClone.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				// TODO
+			}
+		});
+	}
+	
+	protected void initializeCombo() {
+		//
+		// Add filter values
+		//
+		this.comboBoxFilter.addItem(Obadvice.OBLIGATION);
+		this.comboBoxFilter.addItem(Obadvice.ADVICE);
+		//
+		// Initialize GUI properties
+		//
+		this.comboBoxFilter.setImmediate(true);
+		this.comboBoxFilter.setNullSelectionAllowed(true);
+		//
+		//
+		this.comboBoxFilter.addValueChangeListener(new ValueChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void valueChange(ValueChangeEvent event) {
+				//
+				// Remove filters
+				//
+				self.obadvice.removeAllContainerFilters();
+				//
+				// What was selected?
+				//
+				Object id = self.comboBoxFilter.getValue();
+				if (id != null) {
+					//
+					// Add filter
+					//
+					if (id.equals(Obadvice.OBLIGATION)) {
+						self.obadvice.addContainerFilter(new Compare.Equal("type", Obadvice.OBLIGATION));
+					} else if (id.equals(Obadvice.ADVICE)) {
+						self.obadvice.addContainerFilter(new Compare.Equal("type", Obadvice.ADVICE));
+					}
+				}
+			}
+		});
+	}
+
+	public void refreshContainer() {
+		this.obadvice.refresh();
+	}
+
+	@AutoGenerated
+	private VerticalLayout buildMainLayout() {
+		// common part: create layout
+		mainLayout = new VerticalLayout();
+		mainLayout.setImmediate(false);
+		mainLayout.setWidth("100%");
+		mainLayout.setHeight("-1px");
+		mainLayout.setMargin(true);
+		mainLayout.setSpacing(true);
+		
+		// top-level component properties
+		setWidth("100.0%");
+		setHeight("-1px");
+		
+		// horizontalLayoutToolbar
+		horizontalLayoutToolbar = buildHorizontalLayoutToolbar();
+		mainLayout.addComponent(horizontalLayoutToolbar);
+		
+		// table
+		table = new Table();
+		table.setImmediate(true);
+		table.setWidth("-1px");
+		table.setHeight("-1px");
+		mainLayout.addComponent(table);
+		
+		return mainLayout;
+	}
+
+	@AutoGenerated
+	private HorizontalLayout buildHorizontalLayoutToolbar() {
+		// common part: create layout
+		horizontalLayoutToolbar = new HorizontalLayout();
+		horizontalLayoutToolbar.setImmediate(false);
+		horizontalLayoutToolbar.setWidth("-1px");
+		horizontalLayoutToolbar.setHeight("-1px");
+		horizontalLayoutToolbar.setMargin(false);
+		horizontalLayoutToolbar.setSpacing(true);
+		
+		// buttonNew
+		buttonNew = new Button();
+		buttonNew.setCaption("New");
+		buttonNew.setImmediate(true);
+		buttonNew
+				.setDescription("Add a new advice or obligation to the dictionary.");
+		buttonNew.setWidth("-1px");
+		buttonNew.setHeight("-1px");
+		horizontalLayoutToolbar.addComponent(buttonNew);
+		horizontalLayoutToolbar.setComponentAlignment(buttonNew, new Alignment(
+				24));
+		
+		// buttonRemove
+		buttonRemove = new Button();
+		buttonRemove.setCaption("Remove");
+		buttonRemove.setImmediate(true);
+		buttonRemove
+				.setDescription("Remove the selected advice or obligation from the dictionary.");
+		buttonRemove.setWidth("-1px");
+		buttonRemove.setHeight("-1px");
+		horizontalLayoutToolbar.addComponent(buttonRemove);
+		horizontalLayoutToolbar.setComponentAlignment(buttonRemove,
+				new Alignment(24));
+		
+		// buttonClone
+		buttonClone = new Button();
+		buttonClone.setCaption("Clone");
+		buttonClone.setImmediate(true);
+		buttonClone.setDescription("Clone the selected obligation/advice.");
+		buttonClone.setWidth("-1px");
+		buttonClone.setHeight("-1px");
+		horizontalLayoutToolbar.addComponent(buttonClone);
+		horizontalLayoutToolbar.setComponentAlignment(buttonClone,
+				new Alignment(24));
+		
+		// comboBoxFilter
+		comboBoxFilter = new ComboBox();
+		comboBoxFilter.setCaption("Filter By Type");
+		comboBoxFilter.setImmediate(false);
+		comboBoxFilter.setWidth("-1px");
+		comboBoxFilter.setHeight("-1px");
+		horizontalLayoutToolbar.addComponent(comboBoxFilter);
+		
+		return horizontalLayoutToolbar;
+	}
+
+}
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/components/PDPManagement.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/components/PDPManagement.java
new file mode 100644
index 0000000..56fd9cd
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/components/PDPManagement.java
@@ -0,0 +1,862 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ *
+ */
+
+package org.apache.openaz.xacml.admin.components;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.vaadin.dialogs.ConfirmDialog;
+import org.vaadin.dialogs.ConfirmDialog.ContentMode;
+
+import org.apache.openaz.xacml.admin.XacmlAdminAuthorization;
+import org.apache.openaz.xacml.admin.XacmlAdminUI;
+import org.apache.openaz.xacml.admin.model.PDPContainer;
+import org.apache.openaz.xacml.admin.model.PDPGroupContainer;
+import org.apache.openaz.xacml.admin.model.PDPPIPContainer;
+import org.apache.openaz.xacml.admin.model.PDPPolicyContainer;
+import org.apache.openaz.xacml.admin.util.AdminNotification;
+import org.apache.openaz.xacml.admin.view.windows.EditPDPGroupWindow;
+import org.apache.openaz.xacml.admin.view.windows.EditPDPWindow;
+import org.apache.openaz.xacml.admin.view.windows.PDPStatusWindow;
+import org.apache.openaz.xacml.admin.view.windows.SelectPDPGroupWindow;
+import org.apache.openaz.xacml.api.pap.PAPEngine;
+import org.apache.openaz.xacml.api.pap.PAPException;
+import org.apache.openaz.xacml.api.pap.PDP;
+import org.apache.openaz.xacml.api.pap.PDPGroup;
+import org.apache.openaz.xacml.api.pap.PDPGroupStatus;
+import org.apache.openaz.xacml.api.pap.PDPStatus;
+import org.apache.openaz.xacml.std.pap.StdPDPGroup;
+import com.vaadin.annotations.AutoGenerated;
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.data.Property.ValueChangeListener;
+import com.vaadin.event.Action;
+import com.vaadin.event.Action.Handler;
+import com.vaadin.event.ItemClickEvent;
+import com.vaadin.event.ItemClickEvent.ItemClickListener;
+import com.vaadin.event.ShortcutAction.KeyCode;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Button.ClickListener;
+import com.vaadin.ui.CustomComponent;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.Table;
+import com.vaadin.ui.Table.ColumnGenerator;
+import com.vaadin.ui.TextArea;
+import com.vaadin.ui.UI;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.Window.CloseEvent;
+import com.vaadin.ui.Window.CloseListener;
+
+
+public class PDPManagement extends CustomComponent {
+
+	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */
+
+	@AutoGenerated
+	private VerticalLayout mainLayout;
+
+	@AutoGenerated
+	private Table table;
+
+	@AutoGenerated
+	private HorizontalLayout horizontalLayoutToolbar;
+
+	@AutoGenerated
+	private Button buttonRemove;
+
+	@AutoGenerated
+	private Button buttonCreate;
+
+	private static final long serialVersionUID = 1L;
+	private final PDPManagement self = this;
+	private static final Log logger	= LogFactory.getLog(PDPManagement.class);
+	
+	private PDPGroupContainer container;
+	
+	private static final Action CREATE_GROUP = 	new Action ("Create Group");
+	private static final Action REPAIR_GROUP = 	new Action ("Repair Group");
+	private static final Action EDIT_GROUP = 	new Action ("Edit Group");
+	private static final Action DELETE_GROUP = 	new Action ("Delete Group");
+	private static final Action SYNCHRONIZE = 	new Action ("Synchronize");
+	private static final Action MAKE_DEFAULT = 	new Action ("Make Default");
+	private static final Action CREATE_PDP = 	new Action ("Create PDP");
+	private static final Action EDIT_PDP = 		new Action ("Edit PDP");
+	private static final Action DELETE_PDP = 	new Action ("Delete PDP");
+	private static final Action MOVE_PDP = 		new Action ("Move PDP");
+	private static final Action GET_PDP_STATUS = new Action ("View Status");
+	
+	private PAPEngine papEngine;
+
+	/**
+	 * The constructor should first build the main layout, set the
+	 * composition root and then do any custom initialization.
+	 *
+	 * The constructor will not be automatically regenerated by the
+	 * visual editor.
+	 */
+	public PDPManagement(PAPEngine engine) {
+		buildMainLayout();
+		setCompositionRoot(mainLayout);
+		//
+		// Initialize
+		//
+		this.papEngine = engine;
+		//
+		// Initialize
+		//
+		this.initialize();
+		//
+		// setup the buttons
+		//
+		this.setupButtons();
+	}
+	
+	protected void initialize() {
+		//
+		// Don't create a container if the engine doesn't exist
+		//
+		if (this.papEngine == null) {
+			//
+			// remove all the components
+			//
+			this.mainLayout.removeAllComponents();
+			//
+			// Add a label
+			//
+			this.mainLayout.addComponent(new Label("PDP Management unavailable - PAP servlet unavailable."));
+			//
+			// done
+			//
+			return;
+		}
+		//
+		// Create our container
+		//
+		this.container = new PDPGroupContainer(this.papEngine);
+		//
+		// Determine authorization level
+		//
+		boolean isAdmin = ((XacmlAdminUI)UI.getCurrent()).isAuthorized( 
+				XacmlAdminAuthorization.AdminAction.ACTION_ADMIN, 
+				XacmlAdminAuthorization.AdminResource.RESOURCE_PDP_ADMIN);
+		try {
+			this.initializeTree(isAdmin);
+			this.initializeButtons(isAdmin);
+		} catch (Exception e) {
+			logger.error("UNABLE TO START PDPManagement: " + e, e);
+			// check if PAP servlet is up
+			try {
+				Set<PDPGroup> groups = this.papEngine.getPDPGroups();
+				if (groups == null) {
+					throw new PAPException("PAP not running");
+				}
+			} catch (PAPException | NullPointerException e1) {
+				setCompositionRoot(new Label("Cannot use PDP Management because the PAP servlet was not running when Admin Console Servlet first initialized."));
+				return;
+			}
+			setCompositionRoot(new Label("Cannot use PDP Management because of error during initialization: " + e.getMessage()));
+		}
+	}
+	
+	protected void initializeTree(final boolean isAdmin) {
+		//
+		// Set the data source
+		//
+		this.table.setContainerDataSource(this.container);
+		//
+		// Setup the GUI properties
+		//
+		this.table.setVisibleColumns("Name", "Description", "Status", "Default", "PDPs", "Policies", "PIP Configurations");
+		this.table.setColumnHeaders("Name", "Description", "Status", "Default", "PDP's", "Policies", "PIP Configurations");
+		//
+		// The description should be a text area
+		//
+		this.table.addGeneratedColumn("Description", new ColumnGenerator() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public Object generateCell(Table source, Object itemId, Object columnId) {
+				TextArea area = new TextArea();
+				area.setValue(((PDPGroup) itemId).getDescription());
+				area.setReadOnly(true);
+				return area;
+			}
+			
+		});
+		//
+		// Generate a GUI element for the PDP's
+		//
+		this.table.addGeneratedColumn("PDPs", new ColumnGenerator() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public Object generateCell(Table source, Object itemId, Object columnId) {
+	        	final Table table = new Table();
+	        	final PDPContainer container = new PDPContainer((PDPGroup) itemId);
+	        	//
+	        	// Setup the container data
+	        	//
+	        	table.setContainerDataSource(container);
+	        	//
+	        	// Save the group for easy access
+	        	//
+	        	table.setData(itemId);
+	        	//
+	        	// GUI properties
+	        	//
+	        	table.setPageLength(table.getContainerDataSource().size() + 2);
+	        	table.setVisibleColumns("Name", "Status", "Description");
+				table.setColumnCollapsingAllowed(true);
+				table.setColumnCollapsed("Description", true);
+				table.setWidth("100%");
+				//
+				// If an admin, then it is editable
+				//
+				if (isAdmin) {
+					//
+					// Set it as selectable
+					//
+					table.setSelectable(true);
+					//
+					// Add actions
+					//
+					table.addActionHandler(new Handler() {
+						private static final long serialVersionUID = 1L;
+
+						@Override
+						public Action[] getActions(Object target, Object sender) {
+							if (target == null) {
+								return new Action[] {CREATE_PDP};
+							}
+							if (target instanceof PDP) {
+								if (self.container.size() > 1) {
+									return new Action[] {EDIT_PDP, GET_PDP_STATUS, MOVE_PDP, DELETE_PDP};
+								} else {
+									return new Action[] {EDIT_PDP, GET_PDP_STATUS, DELETE_PDP};
+								}
+							}
+							return null;
+						}
+
+						@Override
+						public void handleAction(Action action, Object sender, Object target) {
+							if (action == CREATE_PDP) {
+								self.editPDP(null, (PDPGroup) table.getData());
+								return;
+							}
+							if (action == EDIT_PDP) {
+								assert target instanceof PDP;
+								self.editPDP((PDP) target, (PDPGroup) table.getData());
+								return;
+							}
+							if (action == MOVE_PDP) {
+								assert target instanceof PDP;
+								self.movePDP((PDP) target, (PDPGroup) table.getData());
+								return;
+							}
+							if (action == DELETE_PDP) {
+								assert target instanceof PDP;
+								self.deletePDP((PDP) target, (PDPGroup) table.getData());
+								return;
+							}
+							if (action == GET_PDP_STATUS) {
+								assert target instanceof PDP;
+								self.getPDPStatus((PDP) target, (PDPGroup) table.getData());
+							}
+						}
+					});
+					//
+					// Respond to events
+					//
+					table.addItemClickListener(new ItemClickListener() {
+						private static final long serialVersionUID = 1L;
+
+						@Override
+						public void itemClick(ItemClickEvent event) {
+							if (event.isDoubleClick()) {
+								self.editPDP((PDP) event.getItemId(), (PDPGroup) table.getData());
+							}
+						}
+					});
+				}
+	        	return table;
+			}
+		});
+		//
+		// Generate a GUI element for the policies
+		//
+		this.table.addGeneratedColumn("Policies", new ColumnGenerator() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public Object generateCell(Table source, Object itemId, Object columnId) {
+	        	Table table = new Table();
+	        	table.setContainerDataSource(new PDPPolicyContainer((PDPGroup) itemId));
+	        	table.setPageLength(table.getContainerDataSource().size() + 2);
+
+	        	table.setVisibleColumns("Root", "Name", "Version", "Description");
+				table.setColumnCollapsingAllowed(true);
+				table.setColumnCollapsed("Description", true);
+
+				table.setWidth("100%");
+
+	        	return table;
+			}
+		});
+		//
+		// Generate a GUI element for the PIP configurations
+		//
+		this.table.addGeneratedColumn("PIP Configurations", new ColumnGenerator() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public Object generateCell(Table source, Object itemId, Object columnId) {
+	        	Table table = new Table();
+				if (itemId instanceof PDPGroup) {
+		        	table.setContainerDataSource(new PDPPIPContainer((PDPGroup) itemId));
+		        	table.setPageLength(table.getContainerDataSource().size() + 2);
+				}
+				if (itemId instanceof PDP) {
+		        	table.setContainerDataSource(new PDPPIPContainer((PDP) itemId));
+		        	table.setVisible(false);
+		        	table.setPageLength(0);
+				}
+				table.setVisibleColumns("Name", "Description");
+				table.setColumnCollapsingAllowed(true);
+				table.setColumnCollapsed("Description", true);
+				
+				table.setWidth("100%");
+
+	        	return table;
+			}
+		});
+		//
+		// Check the user's authorization level
+		//
+		if (((XacmlAdminUI)UI.getCurrent()).isAuthorized( 
+				XacmlAdminAuthorization.AdminAction.ACTION_ADMIN, 
+				XacmlAdminAuthorization.AdminResource.RESOURCE_PDP_ADMIN)) {
+			this.table.setSelectable(true);
+		} else {
+			if (logger.isDebugEnabled()) {
+				logger.debug("No admin access to pdp management");
+			}
+			return;
+		}
+		//
+		// Setup Action Handlers
+		//
+		this.table.addActionHandler(new Handler() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public Action[] getActions(Object target, Object sender) {
+				if (target == null) {
+					//
+					// Nothing is selected, they right-clicked empty space.
+					// Only one action.
+					//
+					return new Action[] {CREATE_GROUP};
+				}
+				if (target instanceof PDPGroup) {
+					List<Action> actions = new ArrayList<Action>();
+					PDPGroupStatus.Status status = ((PDPGroup)target).getStatus().getStatus();
+					if (status == PDPGroupStatus.Status.LOAD_ERRORS) {
+						actions.add(REPAIR_GROUP);
+					}
+					if (((PDPGroup)target).isDefaultGroup() == false) {
+						actions.add(MAKE_DEFAULT);
+					}
+					actions.add(EDIT_GROUP);
+					if (status == PDPGroupStatus.Status.OUT_OF_SYNCH) {
+						actions.add(SYNCHRONIZE);
+					}
+					if (((PDPGroup)target).isDefaultGroup() == false) {
+						actions.add(DELETE_GROUP);
+					}
+					actions.add(CREATE_PDP);
+					// Throws a class cast exception
+//					return (Action[]) actions.toArray();
+					Action[] actions2 = new Action[actions.size()];
+					int index = 0;
+					for (Action a : actions) {
+						actions2[index++] = a;
+					}
+					return actions2;
+				}
+				return null;
+			}
+
+			@Override
+			public void handleAction(Action action, Object sender, Object target) {
+				if (action == CREATE_GROUP) {
+					self.editPDPGroup(null);
+					return;
+				}
+				if (action == EDIT_GROUP) {
+					assert target instanceof PDPGroup;
+					self.editPDPGroup((PDPGroup) target);
+					return;
+				}
+				if (action == DELETE_GROUP) {
+					self.deleteGroup((PDPGroup) target);
+					return;
+				}
+				if (action == REPAIR_GROUP) {
+					if (target instanceof PDPGroup) {
+						((PDPGroup) target).repair();
+					} else {
+						String message = "Action '" + REPAIR_GROUP.getCaption() + "' called on non-group target '" + target + "'";
+						logger.error(message);
+						AdminNotification.error(message);
+					}
+					return;
+				}
+				if (action == MAKE_DEFAULT) {
+					if (target instanceof PDPGroup) {
+						try {
+							self.container.makeDefault((PDPGroup) target);
+						} catch (Exception e) {
+							AdminNotification.error("Make Default failed. Reason:\n" + e.getMessage());
+						}
+					} else {
+						String message = "Action '" + MAKE_DEFAULT.getCaption() + "' called on non-group target '" + target + "'";
+						logger.error(message);
+						AdminNotification.error(message);
+					}
+					return;
+				}
+				if (action == SYNCHRONIZE) {
+					if (target instanceof PDPGroup) {
+logger.error("SYNCHRONIZE NOT YET IMPLMENTED");
+AdminNotification.error("Synchronize not yet implemented");
+					} else {
+						String message = "Action '" + SYNCHRONIZE.getCaption() + "' called on non-group target '" + target + "'";
+						logger.error(message);
+						AdminNotification.error(message);
+					}
+					return;
+				}
+				if (action == CREATE_PDP) {
+					if (target instanceof PDPGroup) {
+						self.editPDP(null, ((PDPGroup)target));
+					} else {
+						String message = "Action '" + CREATE_PDP.getCaption() + "' called on non-group target '" + target + "'";
+						logger.error(message);
+						AdminNotification.error(message);
+					}
+					return;
+				}
+			}
+		});
+		//
+		// Listen for item change notifications
+		//
+		this.table.addItemClickListener(new ItemClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void itemClick(ItemClickEvent event) {
+				if (event.isDoubleClick()) {
+					assert event.getItemId() instanceof PDPGroup;
+					self.editPDPGroup((PDPGroup) event.getItemId());
+				}
+			}
+		});
+		//
+		// Respond to selection events
+		//
+		this.table.addValueChangeListener(new ValueChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void valueChange(ValueChangeEvent event) {
+				Object id = self.table.getValue();
+				if (id == null) {
+					self.buttonRemove.setEnabled(false);
+				} else {
+					//
+					// Make sure its not the default group
+					//
+					if (((PDPGroup) id).isDefaultGroup()) {
+						self.buttonRemove.setEnabled(false);
+					} else {
+						self.buttonRemove.setEnabled(true);
+					}
+				}
+			}
+		});
+		//
+		// Maximize the table
+		//
+		this.table.setSizeFull();
+	}
+	
+	protected void initializeButtons(final boolean isAdmin) {
+		if (isAdmin == false) {
+			return;
+		}
+		this.buttonCreate.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				self.editPDPGroup(null);
+			}
+		});
+		this.buttonRemove.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				Object id = self.table.getValue();
+				assert id != null;
+				assert id instanceof PDPGroup;
+				self.deleteGroup((PDPGroup) id);
+				self.table.select(self.table.getNullSelectionItemId());
+			}
+		});
+	}
+	
+	protected void setupButtons() {
+		if (this.table.getValue() == null) {
+			this.buttonRemove.setEnabled(false);
+		} else {
+			this.buttonRemove.setEnabled(true);
+		}		
+	}
+		
+	protected void editPDP(final PDP pdp, final PDPGroup group) {
+		final EditPDPWindow editor = new EditPDPWindow(pdp, this.container.getGroups());
+		if (pdp == null) {
+			editor.setCaption("Create New PDP");
+		} else {
+			editor.setCaption("Edit PDP " + pdp.getId());
+		}
+		editor.setModal(true);
+		editor.addCloseListener(new CloseListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void windowClose(CloseEvent event) {
+				if (editor.isSaved() == false) {
+					return;
+				}
+				try {
+					//
+					// Adding a new PDP?
+					//
+					if (pdp == null) {
+						//
+						// Yes tell the container to add it
+						//
+						self.container.addNewPDP(editor.getPDPId(), group, editor.getPDPName(), editor.getPDPDescription());
+					} else {
+						//
+						// No tell the container to update it
+						//
+						pdp.setName(editor.getPDPName());
+						pdp.setDescription(editor.getPDPDescription());
+						self.container.updatePDP(pdp);
+					}
+				} catch (Exception e) {
+					String message = "Unable to create PDP.  Reason:\n" + e.getMessage();
+					logger.error(message);
+					AdminNotification.error(message);
+				}
+			}
+		});
+		editor.center();
+		UI.getCurrent().addWindow(editor);
+	}
+	
+	protected void editPDPGroup(final PDPGroup group) {
+		//
+		// copy the group
+		//
+		final StdPDPGroup copyGroup = (group == null ? null : new StdPDPGroup(group));
+		//
+		//
+		//
+		final EditPDPGroupWindow editor = new EditPDPGroupWindow(copyGroup, this.container.getGroups(), papEngine);
+		if (group == null) {
+			editor.setCaption("Create PDP Group");
+		} else {
+			editor.setCaption("Edit PDP Group " + ((PDPGroup) group).getName());
+		}
+		editor.setModal(true);
+		editor.addCloseListener(new CloseListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void windowClose(CloseEvent event) {
+				if (editor.isSaved() == false) {
+					return;
+				}
+				if (group == null) {
+					//
+					// Creating a new group
+					//
+					try {
+						self.container.addNewGroup(editor.getGroupName(), editor.getGroupDescription());
+					} catch (Exception e) {
+						String message = "Unable to create Group.  Reason:\n" + e.getMessage();
+						logger.error(message);
+						AdminNotification.error(message);
+					}
+				} else {
+					//
+					// Update group
+					//
+					self.container.updateGroup(editor.getUpdatedObject());
+				}
+			}
+		});
+		editor.center();
+		UI.getCurrent().addWindow(editor);
+	}
+	
+	protected void deletePDP(final PDP pdp, final PDPGroup pdpGroup) {
+		String message = "Are you sure you want to delete <B>" + (pdp.getName() == null ? "" : pdp.getName()) + "</B> group?";
+		ConfirmDialog dialog = ConfirmDialog.getFactory().create("Confirm PDP Deletion", message, "Delete", "Cancel");
+		dialog.setContentMode(ContentMode.HTML);
+		dialog.show(getUI(), new ConfirmDialog.Listener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void onClose(ConfirmDialog dialog) {
+				if (dialog.isConfirmed()) {
+					try {
+						self.container.removePDP(pdp, pdpGroup);
+					} catch (PAPException e) {
+						logger.warn("Failed to remove pdp");
+						AdminNotification.warn("Failed to remove PDP");
+					}
+				}
+			}
+		}, true);
+	}
+	
+	protected void movePDP(final PDP pdp, final PDPGroup currentGroup) {
+		List<PDPGroup> currentGroups = this.container.getGroups();
+		Set<PDPGroup> otherGroups = new HashSet<PDPGroup>(currentGroups);
+		if (otherGroups.remove(currentGroup) == false) {
+			logger.warn("Group list inconsistency - failed to move pdp to selected group");
+			return;
+		}
+		final SelectPDPGroupWindow editor = new SelectPDPGroupWindow(otherGroups, "What was this?");
+		editor.setCaption("Move PDP to group");
+		editor.setModal(true);
+		editor.addCloseListener(new CloseListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void windowClose(CloseEvent event) {
+				if (editor.isSaved()) {
+					self.container.movePDP((PDP) pdp, editor.selectedGroup());
+				}
+			}
+		});
+		editor.center();
+		UI.getCurrent().addWindow(editor);
+	}
+	
+	protected void getPDPStatus(final PDP pdp, final PDPGroup group) {
+		PDPStatus status;
+		try {
+			status = papEngine.getStatus(pdp);
+		} catch (Exception e) {
+			AdminNotification.error("Unable to get details for pdp '" + pdp.getId() + "' with summary status: " + pdp.getStatus().getStatus());
+			return;
+		}
+		logger.info(status);
+		PDPStatusWindow window = new PDPStatusWindow(status);
+		window.setCaption("Status for PDP " + pdp.getName());
+		window.setModal(true);
+		window.center();
+		UI.getCurrent().addWindow(window);
+	}
+	
+	private void deleteGroup(final PDPGroup group) {
+		//
+		// Cannot be the default group
+		//
+		if (group.isDefaultGroup()) {
+			logger.error("Cannot delete the Default group");
+			return;
+		}
+		//
+		// Any PDPs in the group?
+		//
+		Set<PDP> pdps = group.getPdps();
+		if (pdps.isEmpty()) {
+			//
+			// There are no PDP's, so just prompt to remove it
+			//
+			String message = "Are you sure you want to delete <B>" + (group.getName() == null ? "" : group.getName()) + "</B> group?";
+			ConfirmDialog dialog = ConfirmDialog.getFactory().create("Confirm Group Deletion", message, "Delete", "Cancel");
+			dialog.setContentMode(ContentMode.HTML);
+			dialog.show(getUI(), new ConfirmDialog.Listener() {
+				private static final long serialVersionUID = 1L;
+
+				@Override
+				public void onClose(ConfirmDialog dialog) {
+					if (dialog.isConfirmed()) {
+						try {
+							self.container.removeGroup(group, null);
+						} catch (Exception e1) {
+							logger.warn("Container failed to remove group");
+							AdminNotification.error("Unable to delete group '" + group.getId() + "'.  Reason:\n" + e1.getMessage());
+						}
+						return;
+					}
+				}
+			}, true);
+			return;
+		}
+		//
+		// Get our set of groups
+		//
+		List<PDPGroup> currentGroups = this.container.getGroups();
+		Set<PDPGroup> otherGroups = new HashSet<PDPGroup>(currentGroups);
+		if (otherGroups.remove(group) == false) {
+			logger.warn("Group list inconsistency - failed to remove group we are attempting to delete");
+			return;
+		}
+		//
+		// We should have at least one group
+		//
+		if (otherGroups.isEmpty()) {
+			logger.error("Group list inconsistency - no other groups to choose from.");
+			return;
+		}
+		//
+		// If there is only one group, it SHOULD be the default group
+		//
+		if (otherGroups.size() == 1) {
+			PDPGroup loneGroup = otherGroups.iterator().next();
+			if (loneGroup.isDefaultGroup() == false) {
+				logger.error("Group list inconsistency - lone group is NOT default.");
+				return;
+			}
+		}
+		//
+		// Create our confirmation window
+		//
+		final SelectPDPGroupWindow window = new SelectPDPGroupWindow(otherGroups, "Select New Group for PDPs");
+		window.setCaption("Confirm Group " + group.getName() + " Deletion");
+		window.setCloseShortcut(KeyCode.ESCAPE);
+		window.setModal(true);
+		window.addCloseListener(new CloseListener() {
+			private static final long serialVersionUID = 1L;
+
+
+			@Override
+			public void windowClose(CloseEvent e) {
+				if (window.isSaved()) {
+					PDPGroup newGroup = window.selectedGroup();
+					if (newGroup == null) {
+						logger.warn("No group selected for moving PDPs into");
+						AdminNotification.warn("No group selected for moving PDPs into.  Group '" + group.getId() + "' not deleted");
+						return;
+					}
+					try {
+						self.container.removeGroup(group, newGroup);
+					} catch (Exception e1) {
+						logger.warn("Container failed to remove group: " + e1, e1);
+						AdminNotification.error("Unable to delete group '" + group.getId() + "'.  Reason:\n" + e1.getMessage());
+					}
+				}
+			}
+			
+		});
+		getUI().addWindow(window);
+	}
+
+	public void refreshContainer() {
+		if (this.container != null) {
+			this.container.refreshGroups();
+		}
+	}
+
+	@AutoGenerated
+	private VerticalLayout buildMainLayout() {
+		// common part: create layout
+		mainLayout = new VerticalLayout();
+		mainLayout.setImmediate(false);
+		mainLayout.setWidth("100%");
+		mainLayout.setHeight("100%");
+		mainLayout.setMargin(false);
+		
+		// top-level component properties
+		setWidth("100.0%");
+		setHeight("100.0%");
+		
+		// horizontalLayoutToolbar
+		horizontalLayoutToolbar = buildHorizontalLayoutToolbar();
+		mainLayout.addComponent(horizontalLayoutToolbar);
+		
+		// tree
+		table = new Table();
+		table.setImmediate(false);
+		table.setWidth("-1px");
+		table.setHeight("-1px");
+		mainLayout.addComponent(table);
+		mainLayout.setExpandRatio(table, 1.0f);
+		
+		return mainLayout;
+	}
+
+	@AutoGenerated
+	private HorizontalLayout buildHorizontalLayoutToolbar() {
+		// common part: create layout
+		horizontalLayoutToolbar = new HorizontalLayout();
+		horizontalLayoutToolbar.setImmediate(false);
+		horizontalLayoutToolbar.setWidth("-1px");
+		horizontalLayoutToolbar.setHeight("-1px");
+		horizontalLayoutToolbar.setMargin(true);
+		horizontalLayoutToolbar.setSpacing(true);
+		
+		// buttonCreate
+		buttonCreate = new Button();
+		buttonCreate.setCaption("Create Group");
+		buttonCreate.setImmediate(false);
+		buttonCreate.setWidth("-1px");
+		buttonCreate.setHeight("-1px");
+		horizontalLayoutToolbar.addComponent(buttonCreate);
+		
+		// buttonRemove
+		buttonRemove = new Button();
+		buttonRemove.setCaption("Remove Group");
+		buttonRemove.setImmediate(false);
+		buttonRemove.setWidth("-1px");
+		buttonRemove.setHeight("-1px");
+		horizontalLayoutToolbar.addComponent(buttonRemove);
+		
+		return horizontalLayoutToolbar;
+	}
+
+}
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/components/PIPManagement.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/components/PIPManagement.java
new file mode 100644
index 0000000..c25f018
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/components/PIPManagement.java
@@ -0,0 +1,538 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ *
+ */
+
+package org.apache.openaz.xacml.admin.components;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Properties;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.vaadin.dialogs.ConfirmDialog;
+import org.vaadin.dialogs.ConfirmDialog.ContentMode;
+
+import org.apache.openaz.xacml.admin.XacmlAdminAuthorization;
+import org.apache.openaz.xacml.admin.XacmlAdminUI;
+import org.apache.openaz.xacml.admin.jpa.PIPConfiguration;
+import org.apache.openaz.xacml.admin.util.AdminNotification;
+import org.apache.openaz.xacml.admin.view.components.PIPResolverComponent;
+import org.apache.openaz.xacml.admin.view.windows.PIPConfigurationEditorWindow;
+import org.apache.openaz.xacml.admin.view.windows.PIPImportWindow;
+import com.vaadin.addon.jpacontainer.EntityItem;
+import com.vaadin.addon.jpacontainer.JPAContainer;
+import com.vaadin.addon.jpacontainer.provider.CachingLocalEntityProvider;
+import com.vaadin.addon.jpacontainer.provider.CachingMutableLocalEntityProvider;
+import com.vaadin.annotations.AutoGenerated;
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.data.Property.ValueChangeListener;
+import com.vaadin.event.Action;
+import com.vaadin.event.Action.Handler;
+import com.vaadin.event.ItemClickEvent;
+import com.vaadin.event.ItemClickEvent.ItemClickListener;
+import com.vaadin.ui.AbstractSelect.ItemCaptionMode;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Button.ClickListener;
+import com.vaadin.ui.CustomComponent;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.Table;
+import com.vaadin.ui.Table.ColumnGenerator;
+import com.vaadin.ui.TextArea;
+import com.vaadin.ui.UI;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.Window.CloseEvent;
+import com.vaadin.ui.Window.CloseListener;
+
+public class PIPManagement extends CustomComponent {
+
+	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */
+
+	@AutoGenerated
+	private VerticalLayout mainLayout;
+	@AutoGenerated
+	private Table tablePIP;
+	@AutoGenerated
+	private HorizontalLayout horizontalLayoutToolbar;
+	@AutoGenerated
+	private Button buttonImport;
+	@AutoGenerated
+	private Button buttonRemove;
+	@AutoGenerated
+	private Button buttonClone;
+	@AutoGenerated
+	private Button buttonAdd;
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+	private static final Log logger	= LogFactory.getLog(PIPManagement.class);
+	private static final Object[] visibleColumns = new Object[] { "name", "description", "piptype", "issuer"};
+	private static final String[] columnHeaders = new String[] { "Name", "Description", "Type", "Issuer"};
+	
+	private final Action ADD_CONFIGURATION = new Action("Add Configuration");
+	private final Action EDIT_CONFIGURATION = new Action("Edit Configuration");
+	private final Action CLONE_CONFIGURATION = new Action("Clone Configuration");
+	private final Action REMOVE_CONFIGURATION = new Action("Remove Configuration");
+	private final Action ADD_RESOLVER = new Action("Add Resolver");
+	private final Action PUBLISH_CONFIGURATION = new Action("Publish Configuration");
+
+	private final PIPManagement self = this;
+	private final JPAContainer<PIPConfiguration>	container = new JPAContainer<PIPConfiguration>(PIPConfiguration.class);
+	/**
+	 * The constructor should first build the main layout, set the
+	 * composition root and then do any custom initialization.
+	 *
+	 * The constructor will not be automatically regenerated by the
+	 * visual editor.
+	 */
+	public PIPManagement() {
+		buildMainLayout();
+		setCompositionRoot(mainLayout);
+		//
+		// Setup containers
+		//
+		boolean isReadOnly;
+		if (((XacmlAdminUI)UI.getCurrent()).isAuthorized( 
+				XacmlAdminAuthorization.AdminAction.ACTION_WRITE, 
+				XacmlAdminAuthorization.AdminResource.RESOURCE_PIP_ADMIN)) {
+			//
+			// Writable container
+			//
+			container.setEntityProvider(new CachingMutableLocalEntityProvider<PIPConfiguration>(PIPConfiguration.class, ((XacmlAdminUI)UI.getCurrent()).getEntityManager()));
+			isReadOnly = false;
+		} else {
+			//
+			// Read only container
+			//
+			container.setEntityProvider(new CachingLocalEntityProvider<PIPConfiguration>(PIPConfiguration.class, ((XacmlAdminUI)UI.getCurrent()).getEntityManager()));
+			isReadOnly = true;
+		}
+		//
+		// Finish initialization
+		//
+		this.initializeTree(isReadOnly);
+		this.initializeButtons(isReadOnly);
+		//
+		// Setup
+		//
+		this.setupButtons();
+	}
+	
+	protected void initializeTree(boolean isReadOnly) {
+		//
+		// Initialize GUI properties
+		//
+		this.tablePIP.setImmediate(true);
+		this.tablePIP.setContainerDataSource(this.container);
+		this.tablePIP.setItemCaptionMode(ItemCaptionMode.PROPERTY);
+		this.tablePIP.setItemCaptionPropertyId("name");
+		this.tablePIP.setVisibleColumns(visibleColumns);
+		this.tablePIP.setColumnHeaders(columnHeaders);
+		this.tablePIP.setSizeFull();
+		//
+		// Access?
+		//
+		if (isReadOnly) {
+			if (logger.isDebugEnabled()) {
+				logger.debug("read only pip access");
+			}
+			return;
+		}
+		this.tablePIP.setSelectable(true);
+		//
+		// Setup click handler
+		//
+		this.tablePIP.addItemClickListener(new ItemClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void itemClick(ItemClickEvent event) {
+				if (event.isDoubleClick()) {
+					PIPManagement.editConfiguration(self.container.getItem(event.getItemId()));
+				}				
+			}
+		});
+		//
+		// Setup action handler
+		//
+		this.tablePIP.addActionHandler(new Handler() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public Action[] getActions(Object target, Object sender) {
+				if (target == null) {
+					return new Action[] {ADD_CONFIGURATION};
+				}
+				//
+				// Target is an Object ID
+				//
+				EntityItem<PIPConfiguration> config = self.container.getItem(target);
+				if (config != null && config.getEntity().isReadOnly() == false) {
+					if (config.getEntity().requiresResolvers()) {
+						return new Action[] {EDIT_CONFIGURATION, CLONE_CONFIGURATION, REMOVE_CONFIGURATION, PUBLISH_CONFIGURATION, ADD_RESOLVER};
+					} else {
+						return new Action[] {EDIT_CONFIGURATION, CLONE_CONFIGURATION, REMOVE_CONFIGURATION, PUBLISH_CONFIGURATION};							
+					}
+				}
+				if (logger.isDebugEnabled()) {
+					logger.debug("Could not find item: " + target);
+				}
+				return null;
+			}
+
+			@Override
+			public void handleAction(Action action, Object sender, Object target) {
+				EntityItem<PIPConfiguration> config = self.container.getItem(target);
+				if (config == null) {
+					if (logger.isDebugEnabled()) {
+						logger.debug("Could not find item: " + target);
+					}
+					return;
+				}
+				if (action == ADD_CONFIGURATION) {
+					PIPManagement.editConfiguration(self.container.createEntityItem(new PIPConfiguration()));
+					return;
+				}
+				if (action == EDIT_CONFIGURATION) {
+					PIPManagement.editConfiguration(config);
+					return;
+				}
+				if (action == CLONE_CONFIGURATION) {
+					self.cloneConfiguration(config);
+					return;
+				}
+				if (action == REMOVE_CONFIGURATION) {
+					self.removeConfiguration(config);
+					return;
+				}
+				if (action == ADD_RESOLVER) {
+					PIPResolverComponent.addResolver(config.getEntity(), null);
+					return;
+				}
+				if (action == PUBLISH_CONFIGURATION) {
+					PIPResolverComponent.publishConfiguration(config);
+					return;
+				}
+			}
+		});
+		//
+		// When a selection changes listener
+		//
+		this.tablePIP.addValueChangeListener(new ValueChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void valueChange(ValueChangeEvent event) {
+				self.setupButtons();
+			}			
+		});
+		this.tablePIP.addGeneratedColumn("description", new ColumnGenerator() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public Object generateCell(Table source, Object itemId, Object columnId) {
+				EntityItem<PIPConfiguration> entity = self.container.getItem(itemId);
+				if (entity != null && entity.getEntity() != null) {
+					TextArea area = new TextArea();
+					area.setValue(entity.getEntity().getDescription());
+					area.setNullRepresentation("");
+					area.setSizeFull();
+					area.setReadOnly(true);
+					return area;
+				}
+				return null;
+			}
+		});
+		this.tablePIP.addGeneratedColumn("piptype", new ColumnGenerator() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public Object generateCell(Table source, Object itemId, Object columnId) {
+				EntityItem<PIPConfiguration> entity = self.container.getItem(itemId);
+				if (entity != null && entity.getEntity() != null) {
+					return entity.getEntity().getPiptype().getType();
+				}
+				return null;
+			}
+		});
+		//
+		// Customize the resolver column
+		//
+		this.tablePIP.addGeneratedColumn("Resolvers", new ColumnGenerator() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public Object generateCell(Table source, Object itemId, Object columnId) {
+				EntityItem<PIPConfiguration> entity = self.container.getItem(itemId);
+				if (entity != null && entity.getEntity() != null && entity.getEntity().requiresResolvers()) {
+					PIPResolverComponent component = new PIPResolverComponent(entity.getEntity());
+					return component;
+				}
+				return null;
+			}			
+		});
+	}
+	
+	protected void initializeButtons(boolean isReadOnly) {
+		if (isReadOnly) {
+			this.buttonAdd.setVisible(false);
+			this.buttonRemove.setVisible(false);
+			this.buttonClone.setVisible(false);
+			return;
+		}
+		this.buttonAdd.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				PIPManagement.editConfiguration(self.container.createEntityItem(new PIPConfiguration()));
+			}
+			
+		});
+		this.buttonRemove.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				self.removeConfiguration(self.container.getItem(self.tablePIP.getValue()));
+			}
+			
+		});
+		this.buttonClone.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				self.cloneConfiguration(self.container.getItem(self.tablePIP.getValue()));
+			}
+		});
+		this.buttonImport.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				final PIPImportWindow window = new PIPImportWindow();
+				window.setCaption("Import PIP Configuration");
+				window.setModal(true);
+				window.center();
+				window.addCloseListener(new CloseListener() {
+					private static final long serialVersionUID = 1L;
+
+					@Override
+					public void windowClose(CloseEvent e) {
+						String file = window.getUploadedFile();
+						if (file == null) {
+							return;
+						}
+						self.importConfiguration(file);
+					}
+				});
+				UI.getCurrent().addWindow(window);
+			}
+		});
+	}
+	
+	protected void importConfiguration(String file) {
+		Properties properties = new Properties();
+		try {
+			properties.load(new FileInputStream(file));
+			Collection<PIPConfiguration> configs = PIPConfiguration.importPIPConfigurations(properties);
+			if (configs == null || configs.isEmpty()) {
+				AdminNotification.warn("There were no PIP Engine configurations found.");
+			} else {
+				for (PIPConfiguration config : configs) {
+					this.container.addEntity(config);
+				}
+			}
+		} catch (IOException e) {
+			String message = "Failed to load properties: " + e.getLocalizedMessage();
+			logger.error(message);
+			AdminNotification.error(message);
+		}
+	}
+
+	public static void editConfiguration(final EntityItem<PIPConfiguration> entity) {
+		final PIPConfigurationEditorWindow editor = new PIPConfigurationEditorWindow(entity);
+		if (entity.isPersistent()) {
+			editor.setCaption("Edit PIP Configuration " + entity.getEntity().getName());
+		} else {
+			editor.setCaption("Create New PIP Configuration");
+		}
+		editor.setModal(true);
+		editor.addCloseListener(new CloseListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void windowClose(CloseEvent event) {
+				if (editor.isSaved()) {
+					if (entity.isPersistent() == false) {
+						((XacmlAdminUI)UI.getCurrent()).getPIPConfigurations().addEntity(entity.getEntity());
+					}
+					((XacmlAdminUI)UI.getCurrent()).refreshPIPConfiguration();
+				}
+			}					
+		});
+		editor.center();
+		UI.getCurrent().addWindow(editor);
+	}
+	
+	protected void removeConfiguration(final EntityItem<PIPConfiguration> entity) {
+		//
+		// Sanity checks
+		//
+		if (entity == null || entity.getEntity() == null) {
+			logger.error("Removing a null entity");
+			return;
+		}
+		String message = "Are you sure you want to remove the " + entity.getEntity().getName() + " configuration?";
+		ConfirmDialog dialog = ConfirmDialog.getFactory().create("Confirm PIP Configuration Deletion", message, "Remove", "Cancel");
+		dialog.setContentMode(ContentMode.HTML);
+		dialog.show(getUI(), new ConfirmDialog.Listener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void onClose(ConfirmDialog dialog) {
+				if (dialog.isConfirmed()) {
+					if (self.container.removeItem(entity.getItemId()) == false) {
+						logger.warn("Failed to remove PIP configuration");
+						AdminNotification.warn("Failed to remove PIP configuration.");
+					} else {
+						self.setupButtons();
+					}
+				}
+			}
+		}, true);
+	}
+	
+	protected void cloneConfiguration(final EntityItem<PIPConfiguration> entity) {
+		//
+		// Sanity checks
+		//
+		if (entity == null || entity.getEntity() == null) {
+			logger.warn("Cloning a null entity, the buttons were not reset. Resetting them.");
+			this.setupButtons();
+			return;
+		}
+		//
+		// Clone it
+		//
+		PIPManagement.editConfiguration(this.container.createEntityItem(new PIPConfiguration(entity.getEntity(), ((XacmlAdminUI)UI.getCurrent()).getUserid())));
+	}
+	
+	protected void setupButtons() {
+		if (this.tablePIP.getValue() != null) {
+			Object id = this.tablePIP.getValue();
+			EntityItem<PIPConfiguration> entity = this.container.getItem(id);
+			if (entity == null || entity.getEntity().isReadOnly()) {
+				this.buttonRemove.setEnabled(false);
+				this.buttonClone.setEnabled(false);
+			} else {
+				this.buttonRemove.setEnabled(true);
+				this.buttonClone.setEnabled(true);
+			}
+		} else {
+			this.buttonRemove.setEnabled(false);
+			this.buttonClone.setEnabled(false);
+		}
+	}
+
+	public void refreshContainer() {
+		this.container.refresh();
+	}
+
+	@AutoGenerated
+	private VerticalLayout buildMainLayout() {
+		// common part: create layout
+		mainLayout = new VerticalLayout();
+		mainLayout.setImmediate(false);
+		mainLayout.setWidth("100%");
+		mainLayout.setHeight("-1px");
+		mainLayout.setMargin(true);
+		mainLayout.setSpacing(true);
+		
+		// top-level component properties
+		setWidth("100.0%");
+		setHeight("-1px");
+		
+		// horizontalLayoutToolbar
+		horizontalLayoutToolbar = buildHorizontalLayoutToolbar();
+		mainLayout.addComponent(horizontalLayoutToolbar);
+		
+		// tablePIP
+		tablePIP = new Table();
+		tablePIP.setCaption("PIP Configurations");
+		tablePIP.setImmediate(false);
+		tablePIP.setWidth("100.0%");
+		tablePIP.setHeight("-1px");
+		mainLayout.addComponent(tablePIP);
+		
+		return mainLayout;
+	}
+
+	@AutoGenerated
+	private HorizontalLayout buildHorizontalLayoutToolbar() {
+		// common part: create layout
+		horizontalLayoutToolbar = new HorizontalLayout();
+		horizontalLayoutToolbar.setImmediate(false);
+		horizontalLayoutToolbar.setWidth("-1px");
+		horizontalLayoutToolbar.setHeight("-1px");
+		horizontalLayoutToolbar.setMargin(false);
+		horizontalLayoutToolbar.setSpacing(true);
+		
+		// buttonAdd
+		buttonAdd = new Button();
+		buttonAdd.setCaption("Add Configuration");
+		buttonAdd.setImmediate(true);
+		buttonAdd.setWidth("-1px");
+		buttonAdd.setHeight("-1px");
+		horizontalLayoutToolbar.addComponent(buttonAdd);
+		
+		// buttonClone
+		buttonClone = new Button();
+		buttonClone.setCaption("Clone Configuration");
+		buttonClone.setImmediate(true);
+		buttonClone.setWidth("-1px");
+		buttonClone.setHeight("-1px");
+		horizontalLayoutToolbar.addComponent(buttonClone);
+		
+		// buttonRemove
+		buttonRemove = new Button();
+		buttonRemove.setCaption("Remove Configuration");
+		buttonRemove.setImmediate(true);
+		buttonRemove.setWidth("-1px");
+		buttonRemove.setHeight("-1px");
+		horizontalLayoutToolbar.addComponent(buttonRemove);
+		
+		// buttonImport
+		buttonImport = new Button();
+		buttonImport.setCaption("Import Configuration");
+		buttonImport.setImmediate(false);
+		buttonImport
+				.setDescription("Imports a configuration from a properties file.");
+		buttonImport.setWidth("-1px");
+		buttonImport.setHeight("-1px");
+		horizontalLayoutToolbar.addComponent(buttonImport);
+		
+		return horizontalLayoutToolbar;
+	}
+
+}
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/components/PolicyEditor.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/components/PolicyEditor.java
new file mode 100644
index 0000000..f6ab0f8
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/components/PolicyEditor.java
@@ -0,0 +1,1679 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ *
+ */
+
+package org.apache.openaz.xacml.admin.components;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionsType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AllOfType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AnyOfType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeValueType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.ConditionType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.MatchType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObligationExpressionType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObligationExpressionsType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicySetType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.RuleType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.TargetType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.VariableDefinitionType;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.openaz.xacml.admin.jpa.Attribute;
+import org.apache.openaz.xacml.admin.model.GitRepositoryContainer;
+import org.apache.openaz.xacml.admin.model.PolicyContainer;
+import org.apache.openaz.xacml.admin.util.AdminNotification;
+import org.apache.openaz.xacml.admin.util.JPAUtils;
+import org.apache.openaz.xacml.admin.view.windows.AttributeSelectionWindow;
+import org.apache.openaz.xacml.admin.view.windows.AttributeValueEditorWindow;
+import org.apache.openaz.xacml.admin.view.windows.ExpressionBuilderComponent;
+import org.apache.openaz.xacml.admin.view.windows.MatchEditorWindow;
+import org.apache.openaz.xacml.admin.view.windows.ObligationAdviceEditorWindow;
+import org.apache.openaz.xacml.admin.view.windows.PolicyEditorWindow;
+import org.apache.openaz.xacml.admin.view.windows.PolicySetEditorWindow;
+import org.apache.openaz.xacml.admin.view.windows.RuleEditorWindow;
+import org.apache.openaz.xacml.admin.view.windows.VariableDefinitionEditorWindow;
+import org.apache.openaz.xacml.util.XACMLObjectCopy;
+import org.apache.openaz.xacml.util.XACMLPolicyWriter;
+import com.vaadin.annotations.AutoGenerated;
+import com.vaadin.data.Container.ItemSetChangeEvent;
+import com.vaadin.data.Container.ItemSetChangeListener;
+import com.vaadin.data.Item;
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.data.Property.ValueChangeListener;
+import com.vaadin.event.Action;
+import com.vaadin.event.Action.Handler;
+import com.vaadin.event.DataBoundTransferable;
+import com.vaadin.event.ItemClickEvent;
+import com.vaadin.event.ItemClickEvent.ItemClickListener;
+import com.vaadin.event.ShortcutAction;
+import com.vaadin.event.dd.DragAndDropEvent;
+import com.vaadin.event.dd.DropHandler;
+import com.vaadin.event.dd.acceptcriteria.AcceptAll;
+import com.vaadin.event.dd.acceptcriteria.AcceptCriterion;
+import com.vaadin.server.BrowserWindowOpener;
+import com.vaadin.server.FileDownloader;
+import com.vaadin.server.StreamResource;
+import com.vaadin.shared.ui.dd.VerticalDropLocation;
+import com.vaadin.ui.AbstractSelect.AbstractSelectTargetDetails;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Button.ClickListener;
+import com.vaadin.ui.CheckBox;
+import com.vaadin.ui.CustomComponent;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.TabSheet.Tab;
+import com.vaadin.ui.Table.TableDragMode;
+import com.vaadin.ui.TreeTable;
+import com.vaadin.ui.UI;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.Window.CloseEvent;
+import com.vaadin.ui.Window.CloseListener;
+
+public class PolicyEditor extends CustomComponent {
+	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */
+
+	@AutoGenerated
+	private VerticalLayout mainLayout;
+
+	@AutoGenerated
+	private TreeTable tree;
+
+	@AutoGenerated
+	private HorizontalLayout horizontalLayoutToolbar;
+
+	@AutoGenerated
+	private Button buttonExport;
+
+	@AutoGenerated
+	private Button buttonViewXML;
+
+	@AutoGenerated
+	private Button buttonSave;
+
+	@AutoGenerated
+	private CheckBox checkBoxAutoSave;
+
+	@AutoGenerated
+	private CheckBox checkBoxReadOnly;
+
+	private static final long serialVersionUID = 1L;
+	private static Log logger	= LogFactory.getLog(PolicyEditor.class);
+	private final PolicyEditor self = this;
+
+	private static final Action CREATE_POLICY =			new Action ("New Policy");
+	private static final Action CREATE_POLICYSET =		new Action ("New Policy Set");
+	private static final Action CREATE_RULE =			new Action ("New Rule");
+	private static final Action EDIT_POLICY =			new Action ("Edit Policy");
+	private static final Action EDIT_POLICYSET =		new Action ("Edit Policy Set");
+	private static final Action EDIT_RULE =				new Action ("Edit Rule");
+	private static final Action DELETE_POLICYSET =		new Action ("Delete Policy Set");
+	private static final Action DELETE_POLICY = 		new Action ("Delete Policy");
+	private static final Action DELETE_RULE = 			new Action ("Delete Rule");
+	private static final Action CREATE_NEWANYOF =		new Action ("New Any Of (Match)");
+	private static final Action CREATE_NEWALLOF =		new Action ("New All Of (Match)");
+	private static final Action CREATE_NEWMATCH =		new Action ("New Match");
+	private static final Action DELETE_ANYOF =			new Action ("Delete Any Of");
+	private static final Action DELETE_ALLOF =			new Action ("Delete All Of");
+	private static final Action DELETE_MATCH =			new Action ("Delete Match");
+	private static final Action EDIT_MATCH =			new Action ("Edit Match");
+	private static final Action EDIT_OBLIGATIONS =		new Action ("Edit Obligations");
+	private static final Action DELETE_OBLIGATIONS = 	new Action ("Delete Obligations");
+	private static final Action EDIT_ADVICE =			new Action ("Edit Advice");
+	private static final Action DELETE_ADVICE = 		new Action ("Delete Advice");
+	private static final Action CREATE_VARIABLE =		new Action ("Create Variable");
+	private static final Action EDIT_VARIABLE =			new Action ("Edit Variable");
+	private static final Action DELETE_VARIABLE =		new Action ("Delete Variable");
+	private static final Action CREATE_TARGET = 		new Action ("Create Target");
+	private static final Action CREATE_CONDITION =		new Action ("Create Condition");
+	private static final Action EDIT_CONDITION =		new Action ("Edit Condition");
+	private static final Action DELETE_CONDITION =		new Action ("Delete Condition");
+	private static final Action EDIT_EXPRESSIONS =		new Action ("Edit Expressions");
+	
+	private static final Action CLIPBOARD_CUT =			new ShortcutAction ("Cut", ShortcutAction.KeyCode.S, new int[] {ShortcutAction.ModifierKey.CTRL});
+	private static final Action CLIPBOARD_COPY =		new ShortcutAction ("Copy", ShortcutAction.KeyCode.C, new int[] {ShortcutAction.ModifierKey.CTRL});
+	private static final Action CLIPBOARD_PASTE = 		new ShortcutAction ("Paste", ShortcutAction.KeyCode.V, new int[] {ShortcutAction.ModifierKey.CTRL});
+
+	private static final Object[] VISIBLE_COLUMNS = new Object[] {PolicyContainer.PROPERTY_NAME, PolicyContainer.PROPERTY_SHORTALGORITHM, PolicyContainer.PROPERTY_DESCRIPTION};
+	private static final String[] COLUMN_HEADERS = new String[] { "Name", "Algorithm or Effect", "Description"};
+
+	private final File file;
+	private final GitRepositoryContainer gitContainer;
+	private final PolicyContainer policyContainer;
+	private Tab tab = null;
+	private boolean isModified = false;
+	
+	private Object clipboardObject = null;
+
+	/**
+	 * The constructor should first build the main layout, set the
+	 * composition root and then do any custom initialization.
+	 *
+	 * The constructor will not be automatically regenerated by the
+	 * visual editor.
+	 * @throws IOException 
+	 */
+	public PolicyEditor(File policyFile, GitRepositoryContainer gitContainer, boolean readOnly) throws IOException {
+		buildMainLayout();
+		setCompositionRoot(mainLayout);
+		this.mainLayout.setSizeFull();
+		//
+		// Save
+		//
+		this.file = policyFile;
+		this.gitContainer = gitContainer;
+		this.policyContainer = new PolicyContainer(this.file);
+		//
+		// Its our data also
+		//
+		this.setData(policyFile);
+		//
+		// Initialize GUI
+		//
+		this.initializeCheckboxes(readOnly);
+		this.initializeButtons();
+		this.initializeDownload();
+		this.initializeTree();
+// PLD TODO next release		this.initializeContextMenu();
+		//
+		// setup the caption etc.
+		//
+		this.setupCaption();
+		this.resetComponents();
+	}
+	
+	protected void initializeCheckboxes(boolean readOnly) {
+		//
+		// The readonly check box
+		//
+		this.checkBoxReadOnly.setImmediate(true);
+		this.checkBoxReadOnly.setValue(readOnly);
+		this.checkBoxReadOnly.addValueChangeListener(new ValueChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void valueChange(ValueChangeEvent event) {
+				self.resetComponents();
+				self.setupCaption();
+			}
+			
+		});
+		//
+		// The autosave check box
+		//
+		this.checkBoxAutoSave.setImmediate(true);
+		this.checkBoxAutoSave.setValue(true);
+	}
+	
+	protected void initializeButtons() {
+		//
+		// The Save button
+		//
+		this.buttonSave.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				self.savePolicy();
+			}
+		});
+		//
+		// Attach a window opener to the View XML button
+		//
+		BrowserWindowOpener opener = new BrowserWindowOpener(new StreamResource(new StreamResource.StreamSource() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public InputStream getStream() {
+				try {
+					if (logger.isDebugEnabled()) {
+						logger.debug("Setting view xml button to: " + self.file.getAbsolutePath());
+					}
+					return new FileInputStream(self.file);
+				} catch (Exception e) {
+					logger.error("Failed to open input stream " + self.file);
+				}
+				return null;
+			}
+		}, self.file.getName()));
+		opener.setWindowName("_new");
+		opener.extend(this.buttonViewXML);
+	}
+	
+	protected void initializeDownload() {
+		//
+		// Create a stream resource pointing to the file
+		//
+		StreamResource r = new StreamResource(new StreamResource.StreamSource() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public InputStream getStream() {
+				try {
+					return new FileInputStream(self.file);
+				} catch (Exception e) {
+					logger.error("Failed to open input stream " + self.file);
+				}
+				return null;
+			}
+		}, self.file.getName());
+		r.setCacheTime(-1);
+		r.setMIMEType("application/xml");
+		//
+		// Extend a downloader to attach to the Export Button
+		//
+		FileDownloader downloader = new FileDownloader(r);
+		downloader.extend(this.buttonExport);
+	}
+	
+	public void setTab(Tab tab) {
+		this.tab = tab;
+		this.setupCaption();
+	}
+	
+	public boolean isAutoSave() {
+		if (this.checkBoxAutoSave.isEnabled() == false) {
+			return false;
+		}
+		return this.checkBoxAutoSave.getValue();
+	}
+	
+	public boolean isReadOnly() {
+		return this.checkBoxReadOnly.getValue();
+	}
+
+	protected void initializeTree() {
+		//
+		// Create our container and set it as the tree's data source
+		//
+		this.tree.setContainerDataSource(this.policyContainer);
+		this.tree.setItemIconPropertyId("Icon");
+		this.tree.setVisibleColumns(VISIBLE_COLUMNS);
+		this.tree.setColumnHeaders(COLUMN_HEADERS);
+		this.tree.setSelectable(true);
+		this.tree.setSizeFull();
+		//
+		// Expand it down a few items
+		//
+		for (Object id : this.tree.getItemIds()) {
+			this.tree.setCollapsed(id, false);
+			for (Object child : this.tree.getChildren(id)) {
+				this.tree.setCollapsed(child, false);
+			}
+		}
+		//
+		// Respond to double-click's
+		//
+		this.tree.addItemClickListener(new ItemClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void itemClick(ItemClickEvent event) {
+				if (event.isDoubleClick()) {
+					if (self.isReadOnly()) {
+						AdminNotification.info("You are in read-only mode.");
+						return;
+					}
+					Object target = event.getItemId();
+					if (target instanceof PolicySetType) {
+						self.editPolicySet((PolicySetType) target, (PolicySetType) self.policyContainer.getParent(target));
+					} else if (target instanceof PolicyType) {
+						self.editPolicy((PolicyType) target, (PolicySetType) self.policyContainer.getParent(target));
+					} else if (target instanceof RuleType) {
+						self.editRule((RuleType) target, (PolicyType) self.policyContainer.getParent(target));
+					} else if (target instanceof ConditionType) {
+						self.editCondition((ConditionType) target, (RuleType) self.policyContainer.getParent(target));
+					} else if (target instanceof VariableDefinitionType) {
+						self.editVariable((VariableDefinitionType) target, (PolicyType) self.policyContainer.getParent(target));
+					} else if (target instanceof MatchType) {
+						self.editMatch((MatchType) target, (AllOfType) self.policyContainer.getParent(target), null, null, "Edit Match");
+					} else if (target instanceof ObligationExpressionType) {
+						self.editObAdvice(true, self.policyContainer.getParent(target));
+					} else if (target instanceof AdviceExpressionType) {
+						self.editObAdvice(false, self.policyContainer.getParent(target));
+					}
+				}
+			}
+			
+		});
+		//
+		// Respond to container changes
+		//
+		this.policyContainer.addItemSetChangeListener(new ItemSetChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void containerItemSetChange(ItemSetChangeEvent event) {
+				self.isModified = true;
+				if (self.isAutoSave()) {
+					self.savePolicy();
+				} else {
+					self.setupCaption();
+					self.buttonSave.setEnabled(true);
+				}
+			}
+		});
+		//
+		// Implement drag-n-drop
+		//
+		this.tree.setDropHandler(new DropHandler() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void drop(DragAndDropEvent event) {
+				DataBoundTransferable t = (DataBoundTransferable) event.getTransferable();
+			    AbstractSelectTargetDetails target = (AbstractSelectTargetDetails) event.getTargetDetails();
+			    
+			    //
+			    // Get ids of the dragged item and the target item
+			    //
+			    Object sourceItemId = t.getData("itemId");
+				Object targetItemId = target.getItemIdOver();
+				VerticalDropLocation location = target.getDropLocation();
+				if (logger.isDebugEnabled()) {
+					logger.debug("Drop " + sourceItemId + " target " + targetItemId + " location " + location);
+				}
+				//
+				// Tell our container what to do
+				//
+				try {
+					if (location == VerticalDropLocation.MIDDLE) {
+						//
+						// Drop right on top of item making it a child
+						//
+						self.policyContainer.setParent(sourceItemId, targetItemId);
+					}
+
+					/*
+					} else if (location == VerticalDropLocation.TOP) {
+						//
+						// Drop at the top of the tree making it the previous
+						//
+						Object parent = self.policyContainer.getParent(targetItemId);
+						self.policyContainer.setParent(sourceItemId, parent);
+						self.policyContainer.moveAfterSibling(sourceItemId, targetItemId);
+						self.policyContainer.moveAfterSibling(targetItemId, sourceItemId);
+					} else if (location == VerticalDropLocation.BOTTOM) {
+						//
+						// Drop below another item
+						//
+						Object parent = self.policyContainer.getParent(targetItemId);
+						self.policyContainer.setParent(sourceItemId, targetItemId);
+						self.policyContainer.moveAfterSibling(sourceItemId, targetItemId);
+					}
+					*/
+				} catch (UnsupportedOperationException e) {
+					logger.error("Unsupported " + e.getLocalizedMessage());
+				}
+			}
+
+			@Override
+			public AcceptCriterion getAcceptCriterion() {
+				return AcceptAll.get();
+			}
+		});
+	}
+	
+	protected void removeObject(Object target) {
+		if (target instanceof PolicySetType) {
+			this.removePolicySet((PolicySetType) target);
+		} else if (target instanceof PolicyType) {
+			this.removePolicy((PolicyType) target);
+		} else if (target instanceof RuleType) {
+			this.removeRule((RuleType) target);
+		} else if (target instanceof ConditionType) {
+			this.removeCondition((ConditionType) target);
+		} else if (target instanceof VariableDefinitionType) {
+			this.removeVariable((VariableDefinitionType) target);
+		} else if (target instanceof AdviceExpressionType) {
+			this.removeAdvice((AdviceExpressionType) target);
+		} else if (target instanceof ObligationExpressionType) {
+			this.removeObligations((ObligationExpressionType) target);
+		}
+	}
+
+	protected void removeAdvice(AdviceExpressionType target) {
+		if (this.tree.removeItem(target) == false) {
+			logger.error("Failed to remove advice.");
+		}
+	}
+
+	protected void removeVariable(VariableDefinitionType target) {
+		if (this.tree.removeItem(target) == false) {
+			logger.error("Failed to remove variable.");
+		}
+	}
+
+	protected void removeCondition(ConditionType target) {
+		if (this.tree.removeItem(target) == false) {
+			logger.error("Failed to remove condition.");
+		}
+	}
+
+	protected void removeObligations(ObligationExpressionType target) {
+		if (this.tree.removeItem(target) == false) {
+			logger.error("Failed to remove obligations.");
+		}
+	}
+
+	protected void removeRule(RuleType target) {
+		if (this.tree.removeItem(target) == false) {
+			logger.error("Failed to remove rule.");
+		}
+	}
+
+	protected void removePolicy(PolicyType target) {
+		Object parent = this.tree.getParent(target);
+		if (parent == null) {
+			this.deleteRoot(target);
+		} else {
+			if (this.tree.removeItem(target) == false) {
+				logger.error("Failed to remove policy.");
+			}
+		}
+	}
+
+	protected void removePolicySet(PolicySetType target) {
+		Object parent = this.tree.getParent(target);
+		if (parent == null) {
+			this.deleteRoot(target);
+		} else {
+			if (this.tree.removeItem(target) == false) {
+				logger.error("Failed to remove policy set.");
+			}
+		}
+	}
+
+	/*
+	protected void initializeContextMenu() {
+		ContextMenu menu = new ContextMenu();
+		menu.setAsTableContextMenu(this.tree);
+		menu.addContextMenuTableListener(new TableListener() {
+
+			@Override
+			public void onContextMenuOpenFromFooter(
+					ContextMenuOpenedOnTableFooterEvent event) {
+				// TODO Auto-generated method stub
+				
+			}
+
+			@Override
+			public void onContextMenuOpenFromHeader(
+					ContextMenuOpenedOnTableHeaderEvent event) {
+				// TODO Auto-generated method stub
+				
+			}
+
+			@Override
+			public void onContextMenuOpenFromRow(ContextMenuOpenedOnTableRowEvent event) {
+				logger.info("context menu row");
+			}
+		});
+		menu.addItem("test");
+	}
+	*/
+	
+	protected void savePolicy() {
+		if (this.isReadOnly()) {
+			logger.warn("Should not call savePolicy when in read only mode.");
+			return;
+		}
+		Collection<?> roots = this.policyContainer.rootItemIds();
+		if (roots.size() > 1) {
+			logger.warn("More than one root policy.");
+		}
+		//
+		// There should only be one root
+		// Save the policy to disk.
+		//
+		for (Object root : roots) {
+			logger.info("Saving policy: " + this.file.getName());
+			//
+			// TODO - Bump the version?
+			//
+			if (root instanceof PolicySetType) {
+				XACMLPolicyWriter.writePolicyFile(Paths.get(this.file.getAbsolutePath()), (PolicySetType) root);
+			} else if (root instanceof PolicyType) {
+				XACMLPolicyWriter.writePolicyFile(Paths.get(this.file.getAbsolutePath()), (PolicyType) root);
+			}
+			//
+			// TODO ????
+			//
+			this.gitContainer.updateItem(this.file);
+			break; // NOPMD
+		}
+		//
+		// No longer modified
+		//
+		this.isModified = false;
+		this.setupCaption();
+		this.resetComponents();
+	}
+	
+	protected void installTreeActionHandler() {
+		//
+		// Remove any existing action handlers
+		//
+		this.tree.removeAllActionHandlers();
+		//
+		// Are we read-only?
+		//
+		if (this.isReadOnly()) {
+			//
+			// Yes - no action handler's allowed
+			//
+			return;
+		}
+		//
+		// Setup our action handlers
+		//
+		this.tree.addActionHandler(new Handler() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public Action[] getActions(Object target, Object sender) {
+				//
+				// Are we read-only?
+				//
+				if (self.isReadOnly()) {
+					if (logger.isDebugEnabled()) {
+						logger.debug("Policy is read-only");
+					}
+					return null;
+				}
+				if (target == null) {
+					//
+					// Nothing is selected, they right-clicked empty space
+					//
+					if (logger.isDebugEnabled()) {
+						logger.debug("action tree target is null");
+					}
+					return null;
+				}
+				if (target instanceof PolicySetType) {
+					List<Action> actions = new ArrayList<Action>();
+					actions.add(EDIT_POLICYSET);
+					if (((PolicySetType) target).getTarget() == null) {
+						actions.add(CREATE_TARGET);
+					}
+					/*
+					actions.add(CLIPBOARD_CUT);
+					actions.add(CLIPBOARD_COPY);
+					actions.add(CLIPBOARD_PASTE);
+					*/
+					actions.add(CREATE_POLICYSET);
+					actions.add(CREATE_POLICY);
+					actions.add(EDIT_OBLIGATIONS);
+					actions.add(EDIT_ADVICE);
+					actions.add(DELETE_POLICYSET);
+					return (Action[]) actions.toArray(new Action[0]);
+				}
+				if (target instanceof PolicyType) {
+					List<Action> actions = new ArrayList<Action>();
+					actions.add(EDIT_POLICY);
+					if (((PolicyType) target).getTarget() ==  null) {
+						actions.add(CREATE_TARGET);
+					}
+					/*
+					actions.add(CLIPBOARD_CUT);
+					actions.add(CLIPBOARD_COPY);
+					actions.add(CLIPBOARD_PASTE);
+					*/
+					actions.add(CREATE_RULE);
+					actions.add(CREATE_VARIABLE);
+					actions.add(EDIT_OBLIGATIONS);
+					actions.add(EDIT_ADVICE);
+					actions.add(DELETE_POLICY);
+					return (Action[]) actions.toArray(new Action[0]);
+				}
+				if (target instanceof RuleType) {
+					List<Action> actions = new ArrayList<Action>();
+					actions.add(EDIT_RULE);
+					if (((RuleType) target).getTarget() == null) {
+						actions.add(CREATE_TARGET);
+					}
+					/*
+					actions.add(CLIPBOARD_CUT);
+					actions.add(CLIPBOARD_COPY);
+					actions.add(CLIPBOARD_PASTE);
+					*/
+					if (((RuleType)target).getCondition() == null) {
+						actions.add(CREATE_CONDITION);
+					}
+					actions.add(EDIT_OBLIGATIONS);
+					actions.add(EDIT_ADVICE);
+					actions.add(DELETE_RULE);
+					return (Action[]) actions.toArray(new Action[0]);
+				}
+				if (target instanceof TargetType) {
+					return new Action[] {CREATE_NEWANYOF};
+				}
+				if (target instanceof AnyOfType) {
+					return new Action[] {CREATE_NEWALLOF, DELETE_ANYOF};
+				}
+				if (target instanceof AllOfType) {
+					return new Action[] {CREATE_NEWMATCH, DELETE_ALLOF};
+				}
+				if (target instanceof MatchType) {
+					return new Action[] {EDIT_MATCH, DELETE_MATCH};
+				}
+				if (target instanceof ConditionType) {
+					return new Action[] {EDIT_CONDITION, DELETE_CONDITION};
+				}
+				if (target instanceof VariableDefinitionType) {
+					return new Action[] {EDIT_VARIABLE, DELETE_VARIABLE};
+				}
+				if (target instanceof ObligationExpressionType) {
+					return new Action[] {EDIT_OBLIGATIONS, DELETE_OBLIGATIONS};
+				}
+				if (target instanceof AdviceExpressionType) {
+					return new Action[] {EDIT_ADVICE, DELETE_ADVICE};
+				}
+				return null;
+			}
+			
+			@Override
+			public void handleAction(Action action, Object sender, Object target) {
+				if (action == CLIPBOARD_CUT) {
+					assert target != null;
+					self.clipboardObject = XACMLObjectCopy.deepCopy(target);
+					self.removeObject(target);
+					return;
+				}
+				if (action == CLIPBOARD_COPY) {
+					assert target != null;
+					self.clipboardObject = XACMLObjectCopy.deepCopy(target);
+					return;
+				}
+				if (action == CLIPBOARD_PASTE) {
+					assert target != null;
+					self.clipboardPaste(target, true);
+					return;
+				}
+				if (action == CREATE_POLICYSET) {
+					assert target instanceof PolicySetType;
+					self.editPolicySet(null, (PolicySetType) target);
+					return;
+				}
+				if (action == CREATE_POLICY) {
+					assert target instanceof PolicySetType;
+					self.editPolicy(null, (PolicySetType) target);
+					return;
+				}
+				if (action == CREATE_RULE) {
+					assert target instanceof PolicyType;
+					self.editRule(null, (PolicyType) target);
+					return;
+				}
+				if (action == CREATE_TARGET) {
+					assert target instanceof RuleType || target instanceof PolicyType || target instanceof PolicySetType;
+					TargetType newTarget = new TargetType();
+					self.policyContainer.addItem(newTarget, target);
+					return;
+				}
+				if (action == EDIT_POLICYSET) {
+					assert target instanceof PolicySetType;
+					self.editPolicySet((PolicySetType) target, (PolicySetType) self.policyContainer.getParent(target));
+					return;
+				}
+				if (action == EDIT_POLICY) {
+					assert target instanceof PolicyType;
+					self.editPolicy((PolicyType) target, (PolicySetType) self.policyContainer.getParent(target));
+					return;
+				}
+				if (action == EDIT_RULE) {
+					assert target instanceof RuleType;
+					self.editRule((RuleType) target, (PolicyType) self.policyContainer.getParent(target));
+					return;
+				}				
+				if (action == DELETE_POLICYSET) {
+					assert target instanceof PolicySetType;
+					self.removePolicySet((PolicySetType) target);
+					return;
+				}
+				if (action == DELETE_POLICY) {
+					assert target instanceof PolicyType;
+					self.removePolicy((PolicyType) target);
+					return;
+				}
+				if (action == DELETE_RULE) {
+					assert target instanceof RuleType;
+					self.removeRule((RuleType) target);
+					return;
+				}
+				if (action == CREATE_NEWANYOF) {
+					assert target instanceof TargetType;
+					self.editMatch(null, null, null, (TargetType) target, "Create New Match");
+					return;
+				}
+				if (action == CREATE_NEWALLOF) {
+					assert target instanceof AnyOfType;
+					self.editMatch(null, null, (AnyOfType) target, null, "Create New Match");
+					return;
+				}
+				if (action == CREATE_NEWMATCH) {
+					if (target instanceof AllOfType) {
+						self.editMatch(null, (AllOfType) target, null, null, "Create New Match");
+					} else if (target instanceof TargetType) {
+						self.editMatch(null, null, null, (TargetType) target, "Create New Match");
+					} else {
+						assert false;
+					}
+					return;
+				}
+				if (action == DELETE_ANYOF) {
+					assert target instanceof AnyOfType;
+					self.removeAnyOf((AnyOfType) target, (TargetType) self.policyContainer.getParent(target));
+					return;
+				}
+				if (action == DELETE_ALLOF) {
+					assert target instanceof AllOfType;
+					self.removeAllOf((AllOfType) target, (AnyOfType) self.policyContainer.getParent(target));
+					return;
+				}
+				if (action == DELETE_MATCH) {
+					assert target instanceof MatchType;
+					self.removeMatch((MatchType) target, (AllOfType) self.policyContainer.getParent(target));
+					return;
+				}
+				if (action == EDIT_MATCH) {
+					assert target instanceof MatchType;
+					self.editMatch((MatchType) target, (AllOfType) self.policyContainer.getParent(target), null, null, "Edit Match");
+					return;
+				}
+				if (action == EDIT_OBLIGATIONS) {
+					assert target instanceof RuleType || 
+							target instanceof PolicyType || 
+							target instanceof PolicySetType ||
+							target instanceof ObligationExpressionType;
+					if (target instanceof ObligationExpressionType) {
+						self.editObAdvice(true, self.policyContainer.getParent(target));
+					} else {
+						self.editObAdvice(true, target);
+					}
+					return;
+				}
+				if (action == DELETE_OBLIGATIONS) {
+					assert target instanceof ObligationExpressionType;
+					self.removeObligations((ObligationExpressionType) target);
+					return;
+				}
+				if (action == EDIT_ADVICE) {
+					assert target instanceof RuleType || 
+							target instanceof PolicyType || 
+							target instanceof PolicySetType ||
+							target instanceof AdviceExpressionType;
+					if (target instanceof AdviceExpressionType) {
+						self.editObAdvice(false, self.policyContainer.getParent(target));
+					} else {
+						self.editObAdvice(false, target);
+					}
+					return;
+				}
+				if (action == DELETE_ADVICE) {
+					assert target instanceof AdviceExpressionType;
+					self.removeAdvice((AdviceExpressionType) target);
+					return;
+				}
+				if (action == CREATE_VARIABLE) {
+					assert target instanceof PolicyType;
+					self.editVariable(null, (PolicyType) target);
+					return;
+				}
+				if (action == CREATE_CONDITION) {
+					assert target instanceof RuleType;
+					self.editCondition(null, (RuleType) target);
+					return;
+				}
+				if (action == EDIT_CONDITION) {
+					assert target instanceof ConditionType;
+					self.editCondition((ConditionType) target, (RuleType) self.policyContainer.getParent(target));
+					return;
+				}
+				if (action == DELETE_CONDITION) {
+					assert target instanceof ConditionType;
+					self.removeCondition((ConditionType) target);
+					return;
+				}
+				if (action == EDIT_EXPRESSIONS) {
+					return;
+				}
+				if (action == DELETE_VARIABLE) {
+					assert target instanceof VariableDefinitionType;
+					self.removeVariable((VariableDefinitionType) target);
+					return;
+				}
+				if (action == EDIT_VARIABLE) {
+					assert target instanceof VariableDefinitionType;
+					self.editVariable((VariableDefinitionType) target, (PolicyType) self.policyContainer.getParent(target));
+					return;
+				}
+			}
+		});		
+	}
+	
+	protected void resetComponents() {
+		if (this.isReadOnly()) {
+			this.checkBoxAutoSave.setEnabled(false);
+			this.buttonSave.setEnabled(false);
+			this.tree.setDragMode(TableDragMode.NONE);
+			this.tree.removeAllActionHandlers();
+			this.tree.setReadOnly(true);
+		} else {
+			this.checkBoxAutoSave.setEnabled(true);
+			this.buttonSave.setEnabled(this.isModified);
+			this.tree.setReadOnly(false);
+			this.tree.setDragMode(TableDragMode.ROW);
+			this.installTreeActionHandler();
+		}
+	}
+		
+	public void	setupCaption() {
+		String caption = this.file.getName();
+		if (this.isModified) {
+			caption = caption + " *";
+		}
+		if (this.isReadOnly()) {
+			caption = caption + " (Read-Only)";
+		}
+		if (this.tab != null) {
+			this.tab.setCaption(caption);
+		}
+	}
+	
+	protected void editPolicySet(final PolicySetType policy, final PolicySetType parent) {
+		logger.info("editPolicySet: " + policy + " parent " + parent);
+		//
+		// Create a copy
+		//
+		final PolicySetType newPolicySet = (policy == null ? new PolicySetType() : XACMLObjectCopy.copy(policy));
+		//
+		// Create window
+		//
+		final PolicySetEditorWindow window = new PolicySetEditorWindow(newPolicySet);
+		window.setCaption(policy == null ? "Create New Policy Set" : "Edit Policy Set");
+		window.setModal(true);
+		window.addCloseListener(new CloseListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void windowClose(CloseEvent e) {
+				//
+				// Did the user click save?
+				//
+				if (window.isSaved() == false) {
+					if (logger.isDebugEnabled()) {
+						logger.debug("user did NOT save");
+					}
+					return;
+				}
+				//
+				// Was it a new Policy Set?
+				//
+				if (policy == null) {
+					logger.info("adding new policy set " + newPolicySet.getPolicySetId());
+					//
+					// Yes - new add it in
+					//
+					if (newPolicySet.getTarget() == null) {
+						newPolicySet.setTarget(new TargetType());
+					}
+					if (self.policyContainer.addItem(newPolicySet, parent) == null) {
+						logger.error("Failed to add new policy set");
+					} else {
+						self.tree.setCollapsed(parent, false);
+						self.tree.setCollapsed(newPolicySet, false);
+						self.tree.select(newPolicySet);
+					}
+				} else {
+					logger.info("updating new policy set " + newPolicySet.getPolicySetId());
+					//
+					// No - copy everything
+					//
+					policy.setDescription(newPolicySet.getDescription());
+					policy.setVersion(newPolicySet.getVersion());
+					policy.setPolicyCombiningAlgId(newPolicySet.getPolicyCombiningAlgId());
+					//
+					// Update
+					//
+					self.policyContainer.updateItem(policy);
+				}
+			}			
+		});
+		window.center();
+		UI.getCurrent().addWindow(window);
+	}
+	
+	protected void editPolicy(final PolicyType policy, final PolicySetType parent) {
+		//
+		// Create a copy
+		//
+		final PolicyType newPolicy = (policy == null ? new PolicyType() : XACMLObjectCopy.copy(policy));
+		//
+		// Create window
+		//
+		final PolicyEditorWindow window = new PolicyEditorWindow(newPolicy);
+		window.setCaption(policy == null ? "Create New Policy" : "Edit Policy");
+		window.setModal(true);
+		window.addCloseListener(new CloseListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void windowClose(CloseEvent e) {
+				//
+				// Did the user click save?
+				//
+				if (window.isSaved() == false) {
+					return;
+				}
+				//
+				// Was it a new Policy?
+				//
+				if (policy == null) {
+					//
+					// Yes - new add it in
+					//
+					if (newPolicy.getTarget() == null) {
+						newPolicy.setTarget(new TargetType());
+					}
+					if (self.policyContainer.addItem(newPolicy, parent) == null) {
+						logger.error("Failed to add policy");
+					} else {
+						self.tree.setCollapsed(parent, false);
+						self.tree.setCollapsed(newPolicy, false);
+						self.tree.select(newPolicy);
+					}
+				} else {
+					//
+					// No - copy everything
+					//
+					policy.setDescription(newPolicy.getDescription());
+					policy.setVersion(newPolicy.getVersion());
+					policy.setRuleCombiningAlgId(newPolicy.getRuleCombiningAlgId());
+					//
+					// Update
+					//
+					self.policyContainer.updateItem(policy);
+				}
+			}			
+		});
+		window.center();
+		UI.getCurrent().addWindow(window);
+	}
+	
+	protected void editRule(final RuleType rule, final PolicyType parent) {
+		//
+		// Create a copy
+		//
+		final RuleType newRule = (rule == null ? new RuleType() : XACMLObjectCopy.copy(rule));
+		//
+		// Create window
+		//
+		final RuleEditorWindow window = new RuleEditorWindow(newRule);
+		window.setCaption(rule == null ? "Create New Rule" : "Edit Rule");
+		window.setModal(true);
+		window.addCloseListener(new CloseListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void windowClose(CloseEvent e) {
+				//
+				// Did the user click save?
+				//
+				if (window.isSaved() == false) {
+					return;
+				}
+				//
+				// Was this a new rule?
+				//
+				if (rule == null) {
+					//
+					// Yes a new rule
+					//
+					if (newRule.getTarget() == null) {
+						newRule.setTarget(new TargetType());
+					}
+					if (self.policyContainer.addItem(newRule, parent) == null) {
+						logger.error("Failed to add new rule");
+					} else {
+						self.tree.setCollapsed(parent, false);
+						self.tree.setCollapsed(newRule, false);
+						self.tree.select(newRule);
+					}
+				} else {
+					//
+					// No - editing existing rule. Copy everything
+					//
+					rule.setEffect(newRule.getEffect());
+					rule.setDescription(newRule.getDescription());
+					self.policyContainer.updateItem(rule);
+				}
+			}
+		});
+		window.center();
+		UI.getCurrent().addWindow(window);
+	}
+
+	protected void editCondition(final ConditionType condition, final RuleType rule) {
+		//
+		// Make a copy of it first, in case the user manipulates it
+		// and then decides to NOT save it
+		//
+		final ConditionType copyCondition = (condition == null ? new ConditionType() : XACMLObjectCopy.copy(condition));
+		//
+		// Create the window
+		//
+		final ExpressionBuilderComponent expression = new ExpressionBuilderComponent(copyCondition, 
+											(copyCondition.getExpression() != null ? copyCondition.getExpression().getValue() : null), 
+											null,
+											self.policyContainer.getVariables());
+		if (condition == null) {
+			expression.setCaption("Create An Expression For The Condition");
+		} else {
+			expression.setCaption("Edit The Condition Expression");
+		}
+		expression.setModal(true);
+		//
+		// Add the close listener
+		//
+		expression.addCloseListener(new CloseListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void windowClose(CloseEvent e) {
+				//
+				// Did the user hit save?
+				//
+				if (expression.isSaved() == false) {
+					return;
+				}
+				//
+				// Were we creating something new?
+				//
+				if (condition == null) {
+					//
+					// Yes add the new one into the container
+					//
+					if (self.policyContainer.addItem(copyCondition, rule) == null) {
+						logger.error("Failed to add condition");
+					} else {
+						self.tree.setCollapsed(rule, false);
+						self.tree.setCollapsed(copyCondition, false);
+						self.tree.select(copyCondition);
+					}
+				} else {
+					//
+					// We were editing an existing condition, so copy
+					// over the new edited expression.
+					//
+					condition.setExpression(copyCondition.getExpression());
+					//
+					// Update the container
+					//
+					self.policyContainer.updateItem(condition);
+				}
+			}			
+		});
+		expression.center();
+		UI.getCurrent().addWindow(expression);
+	}
+
+	protected void editVariable(final VariableDefinitionType variable, final PolicyType parent) {
+		//
+		// Make a copy of it first, in case the user manipulates it
+		// and then decides to NOT save it
+		//
+		final VariableDefinitionType copyVariable = (variable == null ? new VariableDefinitionType(): XACMLObjectCopy.copy(variable));
+		//
+		// Have the user create or edit the Variables ID
+		//
+		final VariableDefinitionEditorWindow editor = new VariableDefinitionEditorWindow(copyVariable);
+		if (variable == null) {
+			editor.setCaption("Create Variable");			
+		} else {
+			editor.setCaption("Edit Variable" + (copyVariable.getVariableId() == null ? "" : copyVariable.getVariableId()));
+		}
+		editor.setModal(true);
+		editor.addCloseListener(new CloseListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void windowClose(CloseEvent e) {
+				//
+				// Did the user click save button?
+				//
+				if (editor.isSaved() == false) {
+					return;
+				}
+				//
+				// Create the window
+				//
+				final ExpressionBuilderComponent expression = new ExpressionBuilderComponent(copyVariable, 
+													(copyVariable.getExpression() != null ? copyVariable.getExpression().getValue() : null), 
+													null, 
+													self.policyContainer.getVariables());
+				expression.setCaption("Edit The Variable \"" + copyVariable.getVariableId() + "\" Expression");
+				//
+				// Add the close listener
+				//
+				expression.addCloseListener(new CloseListener() {
+					private static final long serialVersionUID = 1L;
+		
+					@Override
+					public void windowClose(CloseEvent e) {
+						//
+						// Did the user click save button?
+						//
+						if (expression.isSaved() == false) {
+							return;
+						}
+						//
+						// Was it a new variable or were we editing an existing one?
+						//
+						if (variable == null) {
+							//
+							// New one, add it to the container
+							//
+							if (self.policyContainer.addItem(copyVariable, parent) == null) {
+								logger.error("Failed to add variable");
+							} else {
+								self.tree.setCollapsed(parent, false);
+								self.tree.setCollapsed(copyVariable, false);
+								self.tree.select(copyVariable);
+							}
+						} else {
+							//
+							// We were editing one, copy it back over.
+							//
+							variable.setVariableId(copyVariable.getVariableId());
+							variable.setExpression(copyVariable.getExpression());
+							//
+							// Update the container
+							//
+							self.policyContainer.updateItem(variable);
+						}
+					}
+				});
+				expression.center();
+				UI.getCurrent().addWindow(expression);
+			}
+		});
+		editor.center();
+		UI.getCurrent().addWindow(editor);
+	}
+
+	protected void editMatch(final MatchType match, final AllOfType allOf, final AnyOfType anyOf, final TargetType target, final String caption) {
+		//
+		// Create an empty match or copy the one we are going to edit.
+		//
+		final MatchType newMatch = (match == null ? new MatchType() : XACMLObjectCopy.copy(match));
+		//
+		// Have user select an attribute
+		//
+		final AttributeSelectionWindow selection = new AttributeSelectionWindow(null, 
+									(newMatch.getAttributeDesignator() != null ? newMatch.getAttributeDesignator() : newMatch.getAttributeSelector()));
+		selection.setCaption("Select Attribute To Match Against");
+		selection.setModal(true);
+		selection.addCloseListener(new CloseListener() {
+			private static final long serialVersionUID = 1L;
+			
+			@Override
+			public void windowClose(CloseEvent event) {
+				//
+				// Did the user save anything?
+				//
+				if (selection.isSaved() == false) {
+					return;
+				}
+				//
+				// Save the selected attribute
+				//
+				final Attribute attribute = selection.getAttribute();
+				if (attribute.isDesignator()) {
+					newMatch.setAttributeDesignator(JPAUtils.createDesignator(attribute));
+				} else {
+					newMatch.setAttributeSelector(JPAUtils.createSelector(attribute));
+				}
+				//
+				// Yes - now match it up to a function
+				//
+				final MatchEditorWindow editor = new MatchEditorWindow(newMatch, attribute.getDatatypeBean());
+				editor.setCaption(caption);
+				editor.setModal(true);
+				editor.addCloseListener(new CloseListener() {
+					private static final long serialVersionUID = 1L;
+					
+					@Override
+					public void windowClose(CloseEvent event) {
+						//
+						// Did the user hit save?
+						//
+						if (editor.isSaved() == false) {
+							return;
+						}
+						//
+						// Yes - now we need the value to check the attribute against
+						//
+						final AttributeValueType copyAttributeValue = (newMatch.getAttributeValue() == null ? new AttributeValueType() : newMatch.getAttributeValue());
+//						String currentValue = null;
+//						if (newMatch.getAttributeValue() != null) {
+//							currentValue = XACMLObjectCopy.getContent(newMatch.getAttributeValue().getContent());
+//						}
+						final AttributeValueEditorWindow value = new AttributeValueEditorWindow(copyAttributeValue, attribute.getDatatypeBean());
+						value.setCaption("Set the value the attribute should match against.");
+						value.setModal(true);
+						value.addCloseListener(new CloseListener() {
+							private static final long serialVersionUID = 1L;
+							
+							@Override
+							public void windowClose(CloseEvent event) {
+								//
+								// Did the user save?
+								//
+								if (value.isSaved() == false) {
+									return;
+								}
+								//
+								// Yes - copy the value into the match
+								//
+								AttributeValueType val = new AttributeValueType();
+								val.getContent().add(value.getValue());
+								val.setDataType(value.getDatatype().getXacmlId());
+								newMatch.setAttributeValue(val);
+								//
+								// Was this a new match or were we editing an
+								// existing match?
+								//
+								if (match != null) {
+									//
+									// Editing - now we can save it
+									//
+									match.setAttributeDesignator(newMatch.getAttributeDesignator());
+									match.setAttributeSelector(newMatch.getAttributeSelector());
+									match.setAttributeValue(newMatch.getAttributeValue());
+									match.setMatchId(newMatch.getMatchId());
+									//
+									// Update the container
+									//
+									self.policyContainer.updateItem(match);
+								} else {
+									//
+									// Do we have a parent(s)?
+									//
+									AllOfType allOfParent = allOf;
+									AnyOfType anyOfParent = anyOf;
+									if (allOfParent == null) {
+										//
+										// No direct AllOfParent
+										//
+										if (anyOfParent == null) {
+											//
+											// No AnyOfParent
+											//
+											if (target == null) {
+												logger.error("We should NOT get this");
+												return;
+											}
+											anyOfParent = new AnyOfType();
+											if (self.policyContainer.addItem(anyOfParent, target) == null) {
+												logger.error("Failed to add anyOf parent");
+												assert false;
+											}
+											self.tree.setCollapsed(anyOfParent, false);
+										}
+										allOfParent = new AllOfType();
+										if (self.policyContainer.addItem(allOfParent, anyOfParent) == null) {
+											logger.error("Failed to add allOf parent");
+											assert false;
+										}
+										self.tree.setCollapsed(allOfParent, false);
+									}
+									//
+									// Add the MatchType into the Tree
+									//
+									if (self.policyContainer.addItem(newMatch, allOfParent) == null) {
+										logger.error("Failed to add match");
+										assert false;
+									}
+									self.tree.select(newMatch);
+								}
+							}								
+						});
+						value.center();
+						UI.getCurrent().addWindow(value);
+					}
+				});
+				editor.center();
+				UI.getCurrent().addWindow(editor);
+			}
+		});
+		selection.center();
+		UI.getCurrent().addWindow(selection);
+	}
+	
+	protected void deleteRoot(Object root) {
+		//
+		// TODO - prompt user for new root object
+		//
+		
+	}
+	
+	protected void editObAdvice(boolean isObligation, final Object target) {
+		//
+		// Get the object
+		//
+		String caption;
+		Object expressionsObject = null;
+		if (target instanceof RuleType) {
+			if (isObligation) {
+				expressionsObject = ((RuleType) target).getObligationExpressions();
+				if (expressionsObject == null) {
+					caption = "Create New Obligation for Rule";
+				} else {
+					caption = "Edit Obligations for Rule"; 
+				}
+			} else {
+				expressionsObject = ((RuleType) target).getAdviceExpressions();
+				if (expressionsObject == null) {
+					caption = "Create New Advice for Rule";
+				} else {
+					caption = "Edit Advice for Rule"; 
+				}
+			}
+		} else if (target instanceof PolicyType) {
+			if (isObligation) {
+				expressionsObject = ((PolicyType) target).getObligationExpressions();
+				if (expressionsObject == null) {
+					caption = "Create New Obligation for Policy";
+				} else {
+					caption = "Edit Obligations for Policy"; 
+				}
+			} else {
+				expressionsObject = ((PolicyType) target).getAdviceExpressions();
+				if (expressionsObject == null) {
+					caption = "Create New Advice for Policy";
+				} else {
+					caption = "Edit Advice for Policy"; 
+				}
+			}
+		} else if (target instanceof PolicySetType) {
+			if (isObligation) {
+				expressionsObject = ((PolicySetType) target).getObligationExpressions();
+				if (expressionsObject == null) {
+					caption = "Create New Obligation for Policy Set";
+				} else {
+					caption = "Edit Obligation for Policy Set"; 
+				}
+			} else {
+				expressionsObject = ((PolicySetType) target).getAdviceExpressions();
+				if (expressionsObject == null) {
+					caption = "Create New Advice for Policy Set";
+				} else {
+					caption = "Edit Advice for Policy Set"; 
+				}
+			}
+		} else {
+			throw new IllegalArgumentException("Expected a rule/policy/policyset.");
+		}
+		//
+		// Make a copy
+		//
+		final Object originalExpressions = expressionsObject;
+		final Object copyExpression = (originalExpressions == null 
+										? (isObligation ? new ObligationExpressionsType() : new AdviceExpressionsType())
+										: originalExpressions instanceof ObligationExpressionsType 
+												? XACMLObjectCopy.copy((ObligationExpressionsType) originalExpressions)
+												: XACMLObjectCopy.copy((AdviceExpressionsType) originalExpressions))
+										;
+		//
+		// Invoke the editor window
+		//
+		final ObligationAdviceEditorWindow window = new ObligationAdviceEditorWindow(copyExpression, this.policyContainer.getVariables());
+		window.setCaption(caption);
+		window.setModal(true);
+		window.addCloseListener(new CloseListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void windowClose(CloseEvent e) {
+				//
+				// Did the user save?
+				//
+				if (window.isSaved() == false) {
+					return;
+				}
+				//
+				// It was saved - is this a new object?
+				//
+				if (originalExpressions == null) {
+					//
+					// New object
+					//
+					if (self.policyContainer.addItem(copyExpression, target) == null) {
+						logger.error("Failed to add expression");
+						assert false;
+					}
+				} else {
+					//
+					// Editing an existing object.
+					//
+					if (originalExpressions instanceof ObligationExpressionsType) {
+						//
+						// Remove old obligations
+						//
+						while (((ObligationExpressionsType) originalExpressions).getObligationExpression().isEmpty() == false) {
+//						for (ObligationExpressionType old : ((ObligationExpressionsType) originalExpressions).getObligationExpression()) {
+							ObligationExpressionType old  = ((ObligationExpressionsType) originalExpressions).getObligationExpression().get(0);
+							self.policyContainer.removeItem(old);
+						}
+						//
+						// Copy new ones in
+						//
+						for (ObligationExpressionType newObligation : ((ObligationExpressionsType) copyExpression).getObligationExpression()) {
+							self.policyContainer.addItem(newObligation, (ObligationExpressionsType) originalExpressions);
+						}
+					} else if (originalExpressions instanceof AdviceExpressionsType) {
+						((AdviceExpressionsType) originalExpressions).getAdviceExpression().clear();
+						((AdviceExpressionsType) originalExpressions).getAdviceExpression().addAll(((AdviceExpressionsType) copyExpression).getAdviceExpression());
+					}
+				}
+			}
+		});
+		window.center();
+		UI.getCurrent().addWindow(window);
+	}
+	
+	protected void removeMatch(MatchType match, AllOfType parent) {
+		assert match != null && parent != null;
+		if (self.policyContainer.removeItem(match) == false) {
+			logger.error("Failed to remove match");
+			assert false;
+		}
+		//
+		// Check for empty AllOf's
+		//
+		if (parent.getMatch().isEmpty()) {
+			this.removeAllOf(parent, (AnyOfType) this.policyContainer.getParent(parent));
+		}
+	}
+
+	protected void removeAllOf(AllOfType allOf, AnyOfType parent) {
+		assert allOf != null && parent != null;
+		if (self.policyContainer.removeItem(allOf) == false) {
+			logger.error("Failed to remove AllOf");
+			assert false;
+		}
+		//
+		// Check for empty AnyOf's
+		//
+		if (parent.getAllOf().isEmpty()) {
+			this.removeAnyOf(parent, (TargetType) this.policyContainer.getParent(parent));
+		}
+	}
+
+	protected void removeAnyOf(AnyOfType anyOf, TargetType parent) {
+		assert anyOf != null && parent != null;
+		if (self.policyContainer.removeItem(anyOf) == false) {
+			logger.error("Failed to remove anyOf");
+			assert false;
+		}
+	}
+
+	protected boolean clipboardPaste(final Object target, boolean performPaste) {
+		if (this.clipboardObject == null) {
+			if (logger.isDebugEnabled()) {
+				logger.debug("nothing in clipboard.");
+			}
+			return false;
+		}
+		boolean doPaste = false;
+		if (this.clipboardObject instanceof PolicySetType && target instanceof PolicySetType) {
+			doPaste = true;
+		}
+		if (this.clipboardObject instanceof PolicyType && target instanceof PolicySetType) {
+			doPaste = true;
+		}
+		if (this.clipboardObject instanceof RuleType && target instanceof PolicyType) {
+			doPaste = true;
+		}
+		if (doPaste == false) {
+			//
+			// Pasting clipboard object onto target not
+			// possible.
+			//
+			return false;
+		}
+		if (performPaste == false) {
+			//
+			// They did not ask to do the actual paste,
+			// but the called wanted to know if it was
+			// possible.
+			//
+			return true;
+		}
+		//
+		// Do the actual paste
+		//
+		Item item = this.policyContainer.addItem(XACMLObjectCopy.deepCopy(this.clipboardObject), target);
+		assert item != null;
+		this.tree.select(this.clipboardObject);
+		
+		return true;
+	}
+	
+	@AutoGenerated
+	private VerticalLayout buildMainLayout() {
+		// common part: create layout
+		mainLayout = new VerticalLayout();
+		mainLayout.setImmediate(false);
+		mainLayout.setWidth("-1px");
+		mainLayout.setHeight("100.0%");
+		mainLayout.setMargin(false);
+		mainLayout.setSpacing(true);
+		
+		// top-level component properties
+		setWidth("-1px");
+		setHeight("100.0%");
+		
+		// horizontalLayoutToolbar
+		horizontalLayoutToolbar = buildHorizontalLayoutToolbar();
+		mainLayout.addComponent(horizontalLayoutToolbar);
+		mainLayout.setExpandRatio(horizontalLayoutToolbar, 1.0f);
+		
+		// tree
+		tree = new TreeTable();
+		tree.setImmediate(true);
+		tree.setWidth("100.0%");
+		tree.setHeight("100.0%");
+		mainLayout.addComponent(tree);
+		mainLayout.setExpandRatio(tree, 1.0f);
+		
+		return mainLayout;
+	}
+
+	@AutoGenerated
+	private HorizontalLayout buildHorizontalLayoutToolbar() {
+		// common part: create layout
+		horizontalLayoutToolbar = new HorizontalLayout();
+		horizontalLayoutToolbar.setImmediate(false);
+		horizontalLayoutToolbar.setWidth("-1px");
+		horizontalLayoutToolbar.setHeight("-1px");
+		horizontalLayoutToolbar.setMargin(true);
+		horizontalLayoutToolbar.setSpacing(true);
+		
+		// checkBoxReadOnly
+		checkBoxReadOnly = new CheckBox();
+		checkBoxReadOnly.setCaption("Read Only");
+		checkBoxReadOnly.setImmediate(false);
+		checkBoxReadOnly
+				.setDescription("Check this to turn-off policy editing.");
+		checkBoxReadOnly.setWidth("-1px");
+		checkBoxReadOnly.setHeight("-1px");
+		horizontalLayoutToolbar.addComponent(checkBoxReadOnly);
+		
+		// checkBoxAutoSave
+		checkBoxAutoSave = new CheckBox();
+		checkBoxAutoSave.setCaption("Auto Save");
+		checkBoxAutoSave.setImmediate(false);
+		checkBoxAutoSave
+				.setDescription("Check this to turn-on automatic saving of policy when a change occurs.");
+		checkBoxAutoSave.setWidth("-1px");
+		checkBoxAutoSave.setHeight("-1px");
+		horizontalLayoutToolbar.addComponent(checkBoxAutoSave);
+		
+		// buttonSave
+		buttonSave = new Button();
+		buttonSave.setCaption("Save");
+		buttonSave.setImmediate(true);
+		buttonSave.setDescription("Click to save the policy.");
+		buttonSave.setWidth("-1px");
+		buttonSave.setHeight("-1px");
+		horizontalLayoutToolbar.addComponent(buttonSave);
+		
+		// buttonViewXML
+		buttonViewXML = new Button();
+		buttonViewXML.setCaption("View XML");
+		buttonViewXML.setImmediate(true);
+		buttonViewXML.setWidth("-1px");
+		buttonViewXML.setHeight("-1px");
+		horizontalLayoutToolbar.addComponent(buttonViewXML);
+		
+		// buttonExport
+		buttonExport = new Button();
+		buttonExport.setCaption("Export Policy");
+		buttonExport.setImmediate(false);
+		buttonExport.setWidth("-1px");
+		buttonExport.setHeight("-1px");
+		horizontalLayoutToolbar.addComponent(buttonExport);
+		
+		return horizontalLayoutToolbar;
+	}
+}
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/components/PolicyWorkspace.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/components/PolicyWorkspace.java
new file mode 100644
index 0000000..8e006d1
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/components/PolicyWorkspace.java
@@ -0,0 +1,1640 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ *
+ */
+
+package org.apache.openaz.xacml.admin.components;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.Collection;
+import java.util.Iterator;
+
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicySetType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.RuleType;
+
+import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
+import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
+import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.Status;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.dircache.DirCache;
+import org.eclipse.jgit.dircache.DirCacheEntry;
+import org.eclipse.jgit.errors.NoWorkTreeException;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.transport.PushResult;
+import org.vaadin.dialogs.ConfirmDialog;
+import org.vaadin.dialogs.ConfirmDialog.ContentMode;
+
+import org.apache.openaz.xacml.admin.XacmlAdminAuthorization;
+import org.apache.openaz.xacml.admin.XacmlAdminUI;
+import org.apache.openaz.xacml.admin.model.GitRepositoryContainer;
+import org.apache.openaz.xacml.admin.util.AdminNotification;
+import org.apache.openaz.xacml.admin.util.OnDemandFileDownloader;
+import org.apache.openaz.xacml.admin.util.OnDemandFileDownloader.OnDemandStreamResource;
+import org.apache.openaz.xacml.admin.util.XACMLPolicyImporter;
+import org.apache.openaz.xacml.admin.view.windows.GitPushWindow;
+import org.apache.openaz.xacml.admin.view.windows.GitSynchronizeWindow;
+import org.apache.openaz.xacml.admin.view.windows.PolicyNameEditorWindow;
+import org.apache.openaz.xacml.admin.view.windows.PolicyUploadWindow;
+import org.apache.openaz.xacml.admin.view.windows.RenamePolicyFileWindow;
+import org.apache.openaz.xacml.admin.view.windows.SubDomainEditorWindow;
+import org.apache.openaz.xacml.std.pap.StdPDPPolicy;
+import org.apache.openaz.xacml.util.XACMLPolicyScanner;
+import org.apache.openaz.xacml.util.XACMLPolicyScanner.CallbackResult;
+import org.apache.openaz.xacml.util.XACMLPolicyWriter;
+import com.vaadin.annotations.AutoGenerated;
+import com.vaadin.data.Item;
+import com.vaadin.event.Action;
+import com.vaadin.event.Action.Handler;
+import com.vaadin.event.ItemClickEvent;
+import com.vaadin.event.ItemClickEvent.ItemClickListener;
+import com.vaadin.event.ShortcutAction.KeyCode;
+import com.vaadin.event.Transferable;
+import com.vaadin.event.dd.DragAndDropEvent;
+import com.vaadin.event.dd.DropHandler;
+import com.vaadin.event.dd.acceptcriteria.AcceptAll;
+import com.vaadin.event.dd.acceptcriteria.AcceptCriterion;
+import com.vaadin.ui.AbstractSelect.AbstractSelectTargetDetails;
+import com.vaadin.ui.Alignment;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Button.ClickListener;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.CustomComponent;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.HorizontalSplitPanel;
+import com.vaadin.ui.Notification;
+import com.vaadin.ui.TabSheet;
+import com.vaadin.ui.TabSheet.CloseHandler;
+import com.vaadin.ui.TabSheet.Tab;
+import com.vaadin.ui.Table.TableDragMode;
+import com.vaadin.ui.Table.TableTransferable;
+import com.vaadin.ui.TreeTable;
+import com.vaadin.ui.UI;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.Window.CloseEvent;
+import com.vaadin.ui.Window.CloseListener;
+
+/**
+ * The class represents Policy Editor in Policy Authoring Tool
+ */
+public class PolicyWorkspace extends CustomComponent implements DropHandler, OnDemandStreamResource {
+	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */
+
+	@AutoGenerated
+	private VerticalLayout mainLayout;
+
+	@AutoGenerated
+	private HorizontalSplitPanel horizontalSplitPanel;
+
+	@AutoGenerated
+	private VerticalLayout verticalLayoutRightPanel;
+
+	@AutoGenerated
+	private TabSheet tabSheet;
+
+	@AutoGenerated
+	private HorizontalLayout horizontalLayoutRightToolbar;
+
+	@AutoGenerated
+	private Button buttonRight;
+
+	@AutoGenerated
+	private VerticalLayout verticalLayoutLeftPanel;
+
+	@AutoGenerated
+	private TreeTable treeWorkspace;
+
+	@AutoGenerated
+	private HorizontalLayout horizontalLayoutLeftToolbar;
+
+	@AutoGenerated
+	private Button buttonLeft;
+
+	@AutoGenerated
+	private HorizontalLayout horizontalLayoutLeftToolbarLeft;
+
+	@AutoGenerated
+	private Button buttonExport;
+
+	@AutoGenerated
+	private Button buttonSynchronize;
+
+	private static final long serialVersionUID = 1L;
+	private static final Log logger	= LogFactory.getLog(PolicyWorkspace.class);
+	private final PolicyWorkspace self = this;
+	private final OnDemandFileDownloader downloader = new OnDemandFileDownloader(this);
+	
+	private GitRepositoryContainer treeContainer;
+	
+	private static final Action EXPORT_REPOSITORY = 	new Action ("Export Repository");
+	private static final Action SYNCHRONIZE_REPOSITORY =new Action ("Synchronize");
+	private static final Action PUSH_CHANGES = 			new Action ("Push Changes");
+	private static final Action CREATE_SUBDOMAIN = 		new Action("Create Sub Domain");
+	private static final Action RENAME_SUBDOMAIN = 		new Action("Rename Sub Domain");
+	private static final Action CREATE_NEWPOLICY =		new Action ("Create New Policy");
+	private static final Action RENAME_POLICY =			new Action ("Rename Policy");
+	private static final Action IMPORT_POLICY = 		new Action ("Import Policy");
+	private static final Action DELETE_SUBDOMAIN = 		new Action ("Delete Sub Domain");
+	private static final Action CLONE_POLICY = 			new Action ("Clone Policy");
+	private static final Action VIEW_POLICY = 			new Action ("View Policy");
+	private static final Action EDIT_POLICY = 			new Action ("Edit Policy");
+	private static final Action EXPORT_POLICY = 		new Action ("Export Policy");
+	private static final Action DELETE_POLICY = 		new Action ("Delete Policy");
+	
+	public static final String VIEWNAME = PolicyWorkspace.class.getCanonicalName();
+	
+	/**
+	 * The constructor should first build the main layout, set the
+	 * composition root and then do any custom initialization.
+	 *
+	 * The constructor will not be automatically regenerated by the
+	 * visual editor.
+	 */
+	public PolicyWorkspace() {
+		buildMainLayout();
+		setCompositionRoot(mainLayout);
+		//
+		// Initialize GUI
+		//
+		this.initializeTree();
+		this.initializeButtons();
+	}
+	
+	protected void initializeButtons() {
+		buttonLeft.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				if (horizontalSplitPanel.getSplitPosition() == 100.0)
+					horizontalSplitPanel.setSplitPosition(36, Unit.PERCENTAGE);
+				else
+					horizontalSplitPanel.setSplitPosition(0);
+			}
+		});
+		buttonRight.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				if (horizontalSplitPanel.getSplitPosition() == 0.0)
+					horizontalSplitPanel.setSplitPosition(36, Unit.PERCENTAGE);
+				else
+					horizontalSplitPanel.setSplitPosition(100, Unit.PERCENTAGE);
+			}
+		});
+		//
+		// Check user write-access
+		//
+		if (((XacmlAdminUI)UI.getCurrent()).isAuthorized( 
+				XacmlAdminAuthorization.AdminAction.ACTION_WRITE, 
+				XacmlAdminAuthorization.AdminResource.RESOURCE_POLICY_WORKSPACE)) {
+			this.buttonSynchronize.addClickListener(new ClickListener() {
+				private static final long serialVersionUID = 1L;
+	
+				@Override
+				public void buttonClick(ClickEvent event) {
+					self.synchronizeRepository();
+				}			
+			});
+		} else {
+			logger.info("user not authorized to write, removing synchronize button.");
+			this.buttonSynchronize.setVisible(false);
+		}
+		//
+		// The export button is attached to dynamic downloader
+		//
+		downloader.extend(this.buttonExport);
+	}
+	
+	protected void initializeTree() {
+		//
+		// This is where the user's Git repository is located
+		//
+		final Path gitPath = ((XacmlAdminUI)UI.getCurrent()).getUserGitPath();
+		//
+		// Create our Git file system container
+		//
+		this.treeContainer = new GitRepositoryContainer(gitPath, gitPath.toFile());
+		//
+		// Create our own filter to filter out File extensions and
+		// also the Git directory.
+		//
+		this.treeContainer.setFilter(new FilenameFilter() {
+
+			@Override
+			public boolean accept(File dir, String name) {
+				//
+				// We don't want any of the hidden files
+				//
+				if (name.startsWith(".git") || name.equals(".DS_Store")) {
+					return false;
+				}
+				//
+				// We definitely want xml files
+				//
+				if (name.endsWith(".xml")) {
+					return true;
+				}
+				//
+				// We should test if its a directory, we want those
+				// included.
+				//
+				Path path = Paths.get(dir.getAbsolutePath(), name);
+				if (Files.isDirectory(path)) {
+					return true;
+				}
+				logger.warn("Filtering out: " + path.toString());
+				return false;
+			}
+			
+		});
+		//
+		// Set TreeTables datasource as our git container
+		//
+		this.treeWorkspace.setContainerDataSource(this.treeContainer);
+		//
+		// Setup other properties etc.
+		//
+		this.treeWorkspace.setItemIconPropertyId("Icon");
+		this.treeWorkspace.setVisibleColumns(new Object[]{"Name", "Version", "Size", "Last Modified", "Status"});
+		this.treeWorkspace.setSizeFull();
+		this.treeWorkspace.setSelectable(true);
+		this.treeWorkspace.setEditable(false);
+		//
+		// Expand the first couple of directories
+		//
+		for (Object id : this.treeWorkspace.getItemIds()) {
+			this.treeWorkspace.setCollapsed(id, false);
+			for (Object child : this.treeWorkspace.getChildren(id)) {
+				this.treeWorkspace.setCollapsed(child, false);
+			}
+		}
+		//
+		// Respond to table selections
+		//
+		/*
+		this.treeWorkspace.addValueChangeListener(new ValueChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void valueChange(ValueChangeEvent event) {
+				File selection = (File) self.treeWorkspace.getValue();
+				if (selection != null) {
+					self.buttonImport.setEnabled(selection.isDirectory());
+					self.buttonExport.setEnabled(selection.isFile());
+				} else {
+					
+				}
+			}
+			
+		});
+		*/
+		this.treeWorkspace.addItemClickListener(new ItemClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void itemClick(ItemClickEvent event) {
+				if (event.isDoubleClick() && 
+					event.getItemId() instanceof File &&
+					((File) event.getItemId()).isFile()) {
+					self.openPolicyTab((File) event.getItemId(), true);
+				}				
+			}
+		});
+		//
+		// Setup our action handlers
+		//
+		this.treeWorkspace.addActionHandler(new Handler() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public Action[] getActions(Object target, Object sender) {
+				if (target == null) {
+					//
+					// Nothing is selected, they right-clicked empty space
+					//
+					return new Action[] {SYNCHRONIZE_REPOSITORY, EXPORT_REPOSITORY, CREATE_SUBDOMAIN};
+				}
+				if (! (target instanceof File)) {
+					return null;
+				}
+				if (((File)target).isDirectory()) {
+					//
+					// Selected a directory
+					//
+					return new Action[] {CREATE_SUBDOMAIN, RENAME_SUBDOMAIN, DELETE_SUBDOMAIN, CREATE_NEWPOLICY, IMPORT_POLICY, PUSH_CHANGES};
+				}
+				if (((File)target).isFile()) {
+					//
+					// Selected a policy file
+					//
+					return new Action[] {VIEW_POLICY, EDIT_POLICY, CLONE_POLICY, EXPORT_POLICY, RENAME_POLICY, DELETE_POLICY, PUSH_CHANGES};
+				}
+				return null;
+			}
+
+			@Override
+			public void handleAction(Action action, Object sender, Object target) {
+				if (action == SYNCHRONIZE_REPOSITORY) {
+					self.synchronizeRepository();
+					return;
+				}
+				if (action == EXPORT_REPOSITORY) {
+					self.exportRepository();
+					return;
+				}
+				if (action == PUSH_CHANGES) {
+					self.pushChanges((File) target);
+					return;
+				}
+				if (action == CREATE_SUBDOMAIN) {
+					self.editSubDomain((File) target, null);
+					return;
+				}
+				if (action == RENAME_SUBDOMAIN) {
+					self.editSubDomain((File) self.treeWorkspace.getParent(target), ((File)target).getName());
+					return;
+				}
+				if (action == CREATE_NEWPOLICY) {
+					self.createPolicy((File) target);
+					return;
+				}
+				if (action == RENAME_POLICY) {
+					self.renamePolicy((File) target);
+					return;
+					
+				}
+				if (action == IMPORT_POLICY) {
+					self.importPolicy((File) target);
+					return;
+				}
+				if (action == DELETE_SUBDOMAIN) {
+					self.deleteSubDomain((File) target);
+					return;
+				}
+				if (action == CLONE_POLICY) {
+					self.clonePolicy((File) target);
+					return;
+				}
+				if (action == VIEW_POLICY) {
+					self.openPolicyTab((File) target, true);
+					return;
+				}
+				if (action == EDIT_POLICY) {
+					self.openPolicyTab((File) target, false);
+					return;
+				}
+				if (action == EXPORT_POLICY) {
+					return;
+
+				}
+				if (action == DELETE_POLICY) {
+					self.deletePolicy((File) target);
+					return;
+				}
+			}
+		});
+		//
+		// Set the drop handler
+		//
+		this.treeWorkspace.setDragMode(TableDragMode.ROW);
+		this.treeWorkspace.setDropHandler(this);
+		//
+		// Detect when a tab closes and remove it from the
+		// tab sheet.
+		//
+		this.tabSheet.setCloseHandler(new CloseHandler() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void onTabClose(TabSheet tabsheet, Component tabContent) {
+				logger.info("tabsheet closing: " + tabsheet.getCaption());
+				tabsheet.removeTab(tabsheet.getTab(tabContent));
+			}
+			
+		});
+	}
+
+	protected void	editSubDomain(final File parent, final String subdomain) {
+		final SubDomainEditorWindow editor = new SubDomainEditorWindow(null);
+		editor.setCaption((subdomain == null ? "Create New SubDomain" : "Edit SubDomain"));
+		editor.setCloseShortcut(KeyCode.ESCAPE);
+		editor.setModal(true);
+		editor.addCloseListener(new CloseListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void windowClose(CloseEvent event) {
+				//
+				// Did the user save it
+				//
+				if (editor.isSaved() == false) {
+					return;
+				}
+				String newSubDomain = editor.getSubDomain();
+				if (newSubDomain == null) {
+					logger.warn("Shouldn't have a null subdomain if the user clicked save button");
+					return;
+				}
+				//
+				// New subdomain?
+				//
+				if (subdomain == null) {
+					//
+					// Create new one
+					//
+					Path createDir;
+					if (parent == null) {
+						//
+						// New Root domain
+						//
+						createDir = Paths.get(((XacmlAdminUI)UI.getCurrent()).getUserGitPath().toAbsolutePath().toString(), newSubDomain);
+					} else {
+						//
+						// New subdomain
+						//
+						createDir = Paths.get(parent.getAbsolutePath(), newSubDomain);
+					}
+					try {
+						//
+						// Does the new subdomain exist?
+						//
+						Path newDir;
+						if (Files.exists(createDir)) {
+							//
+							// It already exists
+							//
+							newDir = createDir;
+						} else {
+							//
+							// Create it
+							//
+							newDir = Files.createDirectory(createDir);
+							//
+							// Create empty .gitignore file
+							//
+							Files.createFile(Paths.get(newDir.toString(), ".gitignore"));
+						}
+						//
+						// Setup the TreeTable
+						//
+						File file = newDir.toFile();
+						if (parent == null) {
+							Item item = self.treeWorkspace.addItem(file);
+							if (item != null) {
+								self.treeWorkspace.setCollapsed(file, false);
+								self.treeWorkspace.select(file);
+							}
+						} else {
+							Item item = self.treeWorkspace.addItem(file);
+							if (item != null) {
+								self.treeWorkspace.setParent(file, parent);
+								self.treeWorkspace.setCollapsed(parent, false);
+								self.treeWorkspace.select(file);
+							}
+						}
+					} catch (IOException e) {
+						logger.error("Failed to create subdomain: " + createDir.toString(), e);
+					}
+				} else {
+					//
+					// Get our paths
+					//
+					Path oldDir = Paths.get(parent.getAbsolutePath(), subdomain);
+					Path newDir = Paths.get(parent.getAbsolutePath(), newSubDomain);
+					try {
+						//
+						// Rename the subdomain
+						//
+						Files.move(oldDir, newDir);
+						//
+						// Add to the TreeTable
+						//
+						File newFile = newDir.toFile();
+						File oldFile = oldDir.toFile();
+						Item item = self.treeWorkspace.addItem(newFile);
+						if (item != null) {
+							self.treeWorkspace.setChildrenAllowed(newFile, true);
+							//
+							// Make sure its parent is the same as the old one, unless they
+							// renamed the top-level.
+							//
+							Object parent = self.treeWorkspace.getParent(oldFile);
+							if (parent != null) {
+								self.treeWorkspace.setParent(newFile, parent);
+							}
+							//
+							// Make any children of the old subdomain now children
+							// of the new subdomain.
+							//
+							Collection<?> children = self.treeWorkspace.getChildren(oldFile);
+							Iterator<?> iter = children.iterator();
+							while (iter.hasNext()) {
+								Object child = iter.next();
+								self.treeWorkspace.setParent(child, newFile);
+							}
+							//
+							// Finally remove the old subdomain
+							//
+							self.treeWorkspace.removeItem(oldFile);
+						}
+					} catch (IOException e) {
+						logger.error("Failed to rename subdomain: " + oldDir.toString() + " to: " + newDir.toString(), e);
+					}
+				}
+			}
+		});
+		editor.center();
+		UI.getCurrent().addWindow(editor);
+	}
+	
+	protected void	deleteSubDomain(final File subdomain) {
+		String message = "Are you sure you want to delete subdomain\n" + subdomain.getName() + "\nThis will remove <B>ALL</B> of its subdomains and policy files.";
+		ConfirmDialog dialog = ConfirmDialog.getFactory().create("Confirm SubDomain Deletion", message, "Delete", "Cancel");
+		dialog.setContentMode(ContentMode.HTML);
+		dialog.show(getUI(), new ConfirmDialog.Listener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void onClose(ConfirmDialog dialog) {
+				if (dialog.isConfirmed()) {
+					//
+					// Iterate the subdomain
+					//
+					try {
+						Files.walkFileTree(Paths.get(subdomain.getAbsolutePath()), new SimpleFileVisitor<Path>() {
+							@Override
+							public FileVisitResult visitFile(Path deleteFile, BasicFileAttributes attrs)
+									throws IOException {
+								try {
+									boolean removeFromTree = deleteFile.getFileName().toString().endsWith(".xml");
+									Files.delete(deleteFile);									
+									if (removeFromTree) {
+										self.treeWorkspace.removeItem(deleteFile.toFile());
+									}
+									if (logger.isDebugEnabled()) {
+										logger.debug("Deleted file: " + deleteFile.toString());
+									}
+								} catch (IOException e) {
+									logger.error("Failed to delete file: " + deleteFile.toString(), e);
+									return FileVisitResult.TERMINATE;
+								}
+								return super.visitFile(deleteFile, attrs);
+							}
+
+							@Override
+							public FileVisitResult postVisitDirectory(Path dir, IOException exc)
+									throws IOException {
+								try {
+									Files.delete(dir);									
+									self.treeWorkspace.removeItem(dir.toFile());
+									if (logger.isDebugEnabled()) {
+										logger.debug("Deleted dir: " + dir.toString());
+									}
+								} catch (IOException e) {
+									logger.error("Failed to delete directory: " + dir.toString(), e);
+									return FileVisitResult.TERMINATE;
+								}
+								return super.postVisitDirectory(dir, exc);
+							}
+							
+						});
+					} catch (IOException e) {
+						logger.error("Failed to walk subdomain: " + subdomain.getAbsolutePath(), e);
+					}
+				}
+			}
+			
+		}, true);
+		
+	}
+	
+	protected void	createPolicy(final File parentDirectory) {
+		//
+		// Construct our parameters
+		//
+		Path parent = Paths.get(parentDirectory.getAbsolutePath());
+		Path newFile = this.getNextFilename(parent, "Policy");
+		//
+		// Run the window
+		//
+		this.runPolicyWindow("Create New Policy", parent, newFile, null, null);
+	}
+	
+	protected void	renamePolicy(final File policy) {
+		//
+		// Run the rename window
+		//
+		final RenamePolicyFileWindow window = new RenamePolicyFileWindow(policy.getName());
+		window.setCaption("Rename Policy");
+		window.setModal(true);
+		window.addCloseListener(new CloseListener() {
+			private static final long serialVersionUID = 1L;
+			
+			@Override
+			public void windowClose(CloseEvent event) {
+				String newFilename = window.getNewFilename();
+				if (newFilename == null) {
+					//
+					// User cancelled
+					//
+					return;
+				}
+				Path newPolicy = Paths.get(policy.getParent(), newFilename);
+				if (Files.exists(newPolicy)) {
+					Notification.show("Cannot rename to an existing file", Notification.Type.ERROR_MESSAGE);
+					return;
+				}
+				try {
+					if (policy.renameTo(newPolicy.toFile()) == false) {
+						throw new Exception("No known error, rename failed");
+					}
+					self.treeContainer.updateItem(newPolicy.getParent().toFile());
+				} catch (Exception e) {
+					Notification.show("Failed to rename file: " + e.getLocalizedMessage());
+				}
+			}
+		});
+		window.center();
+		UI.getCurrent().addWindow(window);
+	}
+	
+	protected void	clonePolicy(final File policy) {
+		//
+		// Figure out a new name for the cloned policy
+		//
+		Path policyClone = Paths.get(policy.getAbsolutePath());
+		Path newFile = this.getNextFilename(policyClone.getParent(), policy.getName());
+		if (newFile == null) {
+			return;
+		}
+		//
+		// Scan the policy in, replace policy ID's and rule ID's
+		//
+		Object policyData = new XACMLPolicyScanner(policyClone, new XACMLPolicyScanner.SimpleCallback() {
+
+			@Override
+			public CallbackResult onPreVisitRule(PolicyType parent, RuleType rule) {
+				rule.setRuleId(((XacmlAdminUI)getUI()).newRuleID());
+				return CallbackResult.CONTINUE;
+			}
+			
+			@Override
+			public CallbackResult onPreVisitPolicySet(PolicySetType parent, PolicySetType policySet) {
+				policySet.setPolicySetId(((XacmlAdminUI)getUI()).newPolicyID());
+				policySet.setVersion("1");
+				return CallbackResult.CONTINUE;
+			}
+			
+			@Override
+			public CallbackResult onPreVisitPolicy(PolicySetType parent, PolicyType policy) {
+				policy.setPolicyId(((XacmlAdminUI)getUI()).newPolicyID());
+				policy.setVersion("1");
+				return CallbackResult.CONTINUE;
+			}
+			
+		}).scan();
+		//
+		// Run the window
+		//
+		this.runPolicyWindow("Clone Policy", newFile.getParent(), newFile.getFileName(), policyData, null);
+	}
+	
+	protected void	runPolicyWindow(String caption, final Path parentPath, final Path policyPath, final Object policyData, final Path oldPolicyFile) {
+		//
+		// Create our editor window
+		//
+		final PolicyNameEditorWindow editor = new PolicyNameEditorWindow((policyPath != null ? policyPath.getFileName().toString() : null), 
+															policyData, 
+															((XacmlAdminUI)getUI()).getPolicyAlgorithms(),
+															((XacmlAdminUI)getUI()).getRuleAlgorithms());
+		editor.setCaption(caption);
+		editor.setCloseShortcut(KeyCode.ESCAPE);
+		editor.setModal(true);
+		editor.addCloseListener(new CloseListener() {
+			private static final long serialVersionUID = 1L;
+			
+			@Override
+			public void windowClose(CloseEvent event) {
+				//
+				// Did the user hit save button or esc?
+				//
+				if (editor.isSaved() == false) {
+					return;
+				}
+				final Object data = editor.getPolicyData();
+				String filename = editor.getPolicyFilename();
+				if (filename == null || data == null) {
+					logger.warn("Editor said is was saved but filename/data is null.");
+					return;
+				}
+				//
+				// Determine new path
+				//
+				final Path newPolicyPath = Paths.get(parentPath.toString(), filename);
+				//
+				// Is it ok to overwrite the new file?
+				//
+				try {
+					//
+					// Handle if we are not replacing an old file and we are overwriting
+					// an existing file.
+					//
+					if (self.isOverwritingAPolicy(newPolicyPath, oldPolicyFile) == false && Files.exists(newPolicyPath)) {
+						//
+						// Confirm they wanted to do this, and figure out
+						// new version number.
+						//
+						String message = "You are overwriting a file: " + newPolicyPath.getFileName().toString();
+						ConfirmDialog dialog = ConfirmDialog.getFactory().create("Confirm Policy File Overwriting", message, "Overwrite", "Cancel");
+						dialog.setData(false);
+						dialog.setContentMode(ContentMode.HTML);
+						dialog.setModal(true);
+						dialog.show(getUI(), new ConfirmDialog.Listener() {
+							private static final long serialVersionUID = 1L;
+
+							@Override
+							public void onClose(ConfirmDialog dialog) {
+								if (dialog.isConfirmed()) {
+									//
+									// Yep the user wants to overwrite it
+									//
+									self.savePolicy(newPolicyPath, data, oldPolicyFile);
+									//
+									// Open it for editing
+									//
+									self.openPolicyTab(newPolicyPath.toFile(), false);
+								}
+							}
+							
+						}, true);
+						//
+						// Exit out of this thread
+						//
+						return;
+					}
+				} catch (Exception e) {
+					logger.error(e);
+					return;
+				}
+				//
+				// Save it off
+				//
+				self.savePolicy(newPolicyPath, data, oldPolicyFile);
+				//
+				// Open it for editing
+				//
+				self.openPolicyTab(newPolicyPath.toFile(), false);
+			}
+		});
+		editor.center();
+		UI.getCurrent().addWindow(editor);
+	}
+
+	protected Path	getNextFilename(Path parent, String filename) {
+		filename = FilenameUtils.removeExtension(filename);
+		Path newFile = null;
+		int i = 0;
+		while (true) {
+			newFile = Paths.get(parent.toString(), String.format("%s(%02d)", filename, i++) + ".xml");
+			if (Files.notExists(newFile)) {
+				return newFile;
+			}
+			if (i == 100) {
+				logger.error("Could not construct a new name for cloned policy.");
+				return null;
+			}
+		}
+		
+	}
+	
+	protected boolean isOverwritingAPolicy(Path newPolicyPath, Path oldPolicyPath) throws Exception {
+		//
+		// Check to see if we were editing an existing file. Then check if the
+		// new file actually exists. Then check if we are overwriting the original old file
+		//
+		if (oldPolicyPath != null && Files.exists(newPolicyPath) && Files.isSameFile(newPolicyPath, oldPolicyPath)) {
+			//
+			// Yes its the same, overwriting it is expected.
+			//
+			logger.info("isOverwritingAPolicy");
+			return true;
+		}
+		return false;
+	}
+
+	protected void	savePolicy(final Path newPolicyPath, final Object policyData, Path oldPolicyPath) {
+		//
+		// Are they overwriting another policy?
+		//
+		String version = "1.0";
+		boolean delete = false;
+		if (oldPolicyPath != null) {
+			//
+			// This policy name was being edited. Is it still the same?
+			//
+			try {
+				delete = true;
+				if (Files.exists(newPolicyPath) && Files.isSameFile(newPolicyPath, oldPolicyPath)) {
+					delete = false;
+				}
+			} catch (Exception e) {
+				logger.error("Could not determine if same file", e);
+				return;
+			}
+			logger.info("Deleting old file: " + delete);
+		}
+		//
+		// Are we now overwriting another file?
+		//
+		if (Files.exists(newPolicyPath)) {
+			//
+			// Yes
+			//
+			logger.info("Overwriting file");
+			//
+			// Overwrite is happening. Bump the version (IF WE CAN)
+			//
+//TODO - What if user wants to change something other than the last number?  For example, changing 1.5.23 to 2.0.0.
+//TODO	  We need a mechanism that allows the user to specify the new policy version (disallowing backtracking) if they desire
+//TODO	  and get that new number (if any) passed down to here.  This code then becomes the "then" branch of "If new version has been specified..."
+			try {
+				int[] versionArray = StdPDPPolicy.versionStringToArray(XACMLPolicyScanner.getVersion(newPolicyPath));
+				// increment the right-most digit
+				versionArray[versionArray.length - 1]++;
+				version = StdPDPPolicy.versionArrayToString(versionArray);
+			} catch (NumberFormatException | IOException e) {
+				try {
+					logger.warn("Previous version '" + XACMLPolicyScanner.getVersion(newPolicyPath) + "' not a series of itegers");
+				} catch (IOException e1) {
+					logger.error("could not get previous version");
+				}
+//TODO - This may not be wise since the intent is to increase the version number.  Perhaps we should abort this an go back to the user?
+				version = "1.0";
+			}
+			if (policyData instanceof PolicySetType) {
+				((PolicySetType) policyData).setVersion(version);
+			} else if (policyData instanceof PolicyType) {
+				((PolicyType) policyData).setVersion(version);
+			}
+		} else {
+			//
+			// Nope, a completely new file
+			//
+			logger.info("New file");
+		}
+		//
+		// Is the root a PolicySet or Policy?
+		//
+		Path finalPolicyPath;
+		if (policyData instanceof PolicySetType) {
+			//
+			// Write it out
+			//
+			finalPolicyPath = XACMLPolicyWriter.writePolicyFile(newPolicyPath, (PolicySetType) policyData);
+		} else if (policyData instanceof PolicyType) {
+			//
+			// Write it out
+			//
+			finalPolicyPath = XACMLPolicyWriter.writePolicyFile(newPolicyPath, (PolicyType) policyData);
+		} else {
+			logger.error("Unknown data type sent back.");
+			return;
+		}
+		//
+		// Did it get written?
+		//
+		if (finalPolicyPath == null || ! Files.exists(finalPolicyPath)) {
+			logger.error("Failed to write policy file.");
+			return;
+		}
+		//
+		// Add it into our tree
+		//
+		this.addPolicyFileToTree(finalPolicyPath.getParent().toFile(), finalPolicyPath.toFile());
+		//
+		// Do we need to delete the old file?
+		//
+		if (oldPolicyPath != null && delete) {
+			try {
+				Files.delete(oldPolicyPath);
+			} catch (Exception e) {
+				logger.error("Failed to delete old policy", e);
+			}
+			if (self.treeWorkspace.removeItem(oldPolicyPath.toFile()) == false) {
+				logger.warn("Failed to remove old policy path");
+			}
+		}
+	}	
+
+	protected void	deletePolicy(final File policy) {
+		String message = "Are you sure you want to delete policy: " + policy.getName();
+		ConfirmDialog dialog = ConfirmDialog.getFactory().create("Confirm Policy File Deletion", message, "Delete", "Cancel");
+		dialog.setContentMode(ContentMode.HTML);
+		dialog.show(getUI(), new ConfirmDialog.Listener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void onClose(ConfirmDialog dialog) {
+				if (dialog.isConfirmed() && policy.delete()) {
+					self.treeWorkspace.removeItem(policy);
+					if (logger.isDebugEnabled()) {
+						logger.debug("Deleted file: " + policy.toString());
+					}
+				}
+			}
+			
+		}, true);
+		
+	}
+
+	protected void	importPolicy(final File domain) {
+		//
+		// Get the current domain
+		//
+		if (! domain.isDirectory()) {
+			logger.error("Table must have a directory selected to import the file.");
+			return;
+		}
+		//
+		// Create the upload window
+		//
+		final PolicyUploadWindow upload = new PolicyUploadWindow(Paths.get(domain.toURI()));
+		upload.setCaption("Import Xacml 3.0 Policy File");
+		upload.setCloseShortcut(KeyCode.ESCAPE);
+		upload.setModal(true);
+		upload.addCloseListener(new CloseListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void windowClose(CloseEvent e) {
+				//
+				// Was it successful?
+				//
+				Path newFile = upload.getUploadedFile();
+				if (newFile == null) {
+					return;
+				}
+				//
+				// Add it
+				//
+				self.addPolicyFileToTree(domain, newFile.toFile());
+				//
+				// Are we importing anything in the policy file?
+				//
+				boolean importAttributes = upload.importAttributes();
+				boolean importObligations = upload.importObligations();
+				boolean importAdvice = upload.importAdvice();
+				if (importAttributes || importObligations || importAdvice) {
+					//
+					// Create our importer
+					//
+					XACMLPolicyImporter importer = new XACMLPolicyImporter();
+					importer.setImportAttributes(importAttributes);
+					importer.setImportObligations(importObligations);
+					importer.setImportAdvice(importAdvice);		
+					importer.setIgnoreStandardAttributes(upload.ignoreStandard());
+					//
+					// Yes load and scan the policy
+					//
+					new XACMLPolicyScanner(newFile, importer).scan();
+				}
+			}
+		});
+		upload.center();
+		UI.getCurrent().addWindow(upload);
+	}
+	
+	protected	void	addPolicyFileToTree(File domain, File file) {
+		//
+		// Add it into our tree
+		//
+		if (this.treeWorkspace.addItem(file) != null) {
+			//
+			// Make sure it has the right parent
+			//
+			this.treeWorkspace.setParent(file, domain);
+			//
+			// Select our new policy
+			//
+			self.treeWorkspace.select(file);
+		} else {
+			logger.error("Failed to add policy to workspace tree");
+		}
+	}
+	
+	/*
+	protected void	publishPolicy(final File policy) {
+		//
+		// Get its ID
+		//
+		Item item = this.treeContainer.getItem(policy);
+		if (item == null) {
+			logger.error("Failed to get the item");
+			return;
+		}
+		Object policyData = item.getItemProperty("Data");
+		if (policyData == null) {
+			logger.error("Failed to get item data property.");
+			return;
+		}
+		String fullId = XACMLPolicyScanner.getID(policyData);
+		String version = XACMLPolicyScanner.getVersion(policyData);
+		if (fullId == null || version == null) {
+			logger.error("Failed to get policy Id");
+			return;
+		}
+		List<String> ids = Lists.newArrayList(Splitter.on(':').split(fullId));
+		if (ids.isEmpty()) {
+			logger.error("Couldn't parse policy Id");
+			return;
+		}
+		final String id = ids.get(ids.size() - 1) + "." + version;
+		//
+		// Is there only one group?
+		//
+		PAPEngine engine = ((XacmlAdminUI)getUI()).getPAPEngine();
+		Set<PDPGroup> groups;
+		PDPGroup defaultGroup;
+		try {
+			groups = engine.getPDPGroups();
+		} catch (PAPException e) {
+			String message = "Unable to retrieve Groups from server: " + e;
+			logger.error(message, e);
+			throw new RuntimeException(message);
+		}
+		try {
+			defaultGroup = engine.getDefaultGroup();
+		} catch (PAPException e) {
+			String message = "Unable to retrieve Default Group from server: " + e;
+			logger.error(message, e);
+			throw new RuntimeException(message);
+		}
+		if (groups.size() == 1) {
+			this.doPublish(id, policy, defaultGroup);
+			return;
+		}
+		//
+		// Have user select a group
+		//
+		final SelectPDPGroupWindow window = new SelectPDPGroupWindow(groups, "Select PDP Group to publish in");
+		window.setCaption("Select PDP Group");
+		window.setCloseShortcut(KeyCode.ESCAPE);
+		window.setModal(true);
+		window.addCloseListener(new CloseListener() {
+			private static final long serialVersionUID = 1L;
+			
+			@Override
+			public void windowClose(CloseEvent event) {
+				PDPGroup group = window.selectedGroup();
+				if (group != null) {
+					self.doPublish(id, policy, group);
+				}
+			}
+		});
+		window.center();
+		UI.getCurrent().addWindow(window);
+
+	}
+	
+	protected void	doPublish(String id, File policy, PDPGroup group) {
+		//
+		// The policy status must be up-to-date
+		//
+		// TODO
+		
+		//
+		// TODO - get list of referenced policies and publish
+		// them first.
+		//
+		
+		//
+		// Publish the policy
+		//
+		
+		PAPEngine engine = ((XacmlAdminUI)getUI()).getPAPEngine();
+		try (InputStream is = new FileInputStream(policy)) {
+			engine.publishPolicy(id, policy.getName(), true, is, group);
+		} catch (PAPException | IOException e) {
+			logger.error("Failed to publish policy: ", e);
+		}
+	}
+	*/
+	
+	protected void	pushChanges(final File target) {
+		try {
+			//
+			// Grab our working repository
+			//
+    		Path repoPath = ((XacmlAdminUI)getUI()).getUserGitPath();
+			final Git git = Git.open(repoPath.toFile());
+			//
+			// Get our status
+			//
+			final String base;
+			Status status;
+			if (target == null) {
+				base = ".";
+			} else {
+				Path relativePath = repoPath.relativize(Paths.get(target.getPath()));
+				base = relativePath.toString();
+			}
+			if (logger.isDebugEnabled()) {
+				logger.debug("Status on base: " + base);
+			}
+			status = git.status().addPath(base).call();
+			//
+			// Check if its clean
+			//
+			if (status.isClean()) {
+				//
+				// Its clean
+				//
+				AdminNotification.warn(target.getName() + " is clean!");
+				return;
+			}
+			//
+			// Create the window
+			//
+			final GitPushWindow window = new GitPushWindow(git, target, status);
+			window.setCaption("Push Changes");
+			window.setModal(true);
+			window.addCloseListener(new CloseListener() {
+				private static final long serialVersionUID = 1L;
+
+				@Override
+				public void windowClose(CloseEvent e) {
+					if (window.isSaved() == false) {
+						return;
+					}
+					try {
+						//
+						// Needs to be added first
+						//
+						DirCache cache = git.add().addFilepattern(base).call();
+						for (int i = 0; i < cache.getEntryCount(); i++) {
+							DirCacheEntry entry = cache.getEntry(i);
+							if (logger.isDebugEnabled()) {
+								logger.debug("Entry: " + entry);
+							}
+						}
+						//
+						// Next they need to be committed
+						//
+						RevCommit rev = git.commit().setMessage(window.getComment()).call();
+						if (logger.isDebugEnabled()) {
+							logger.debug("RevCommit: " + rev);
+						}
+						//
+						// Now we can push changes to the Git repository
+						//
+						Iterable<PushResult> results = git.push().call();
+						for (PushResult result : results) {
+							logger.info(result);
+						}
+						//
+						// Have the container fire an item set change notification
+						//
+						self.treeContainer.updateItem(target);
+					} catch (NoWorkTreeException | GitAPIException e1) {
+						logger.error(e);
+						AdminNotification.error("Exception occurred while trying to push: " + e1);
+					}
+				}
+				
+			});
+			window.center();
+			UI.getCurrent().addWindow(window);
+		} catch (IOException | GitAPIException e) {
+			logger.error(e);
+			AdminNotification.error("Exception occurred while trying to get status: " + e);
+		}
+	}
+	
+	protected void synchronizeRepository() {
+		final GitSynchronizeWindow window = new GitSynchronizeWindow();
+		window.setCaption("Synchronize with server repository?");
+		window.setModal(true);
+		window.center();
+		UI.getCurrent().addWindow(window);
+	}
+	
+	protected void exportRepository() {
+		this.buttonExport.click();
+	}
+	
+	@Override
+	public String getFilename() {
+		return "Repository.tgz";
+	}
+
+	@Override
+	public InputStream getStream() {
+		//
+		// Grab our working repository
+		//
+		final Path repoPath = ((XacmlAdminUI)getUI()).getUserGitPath();
+		Path workspacePath = ((XacmlAdminUI)getUI()).getUserWorkspace();
+		final Path tarFile = Paths.get(workspacePath.toString(), "Repository.tgz");
+		
+		try (OutputStream os = Files.newOutputStream(tarFile)) {
+			try (GzipCompressorOutputStream gzOut = new GzipCompressorOutputStream(os)) {
+				try (TarArchiveOutputStream tarOut = new TarArchiveOutputStream(gzOut)) {
+					
+					tarOut.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);
+					
+					Files.walkFileTree(repoPath, new SimpleFileVisitor<Path>() {
+
+						@Override
+						public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
+							if (dir.getFileName().toString().startsWith(".git")) {
+								return FileVisitResult.SKIP_SUBTREE;
+							}
+							Path relative = repoPath.relativize(dir);
+							if (relative.toString().isEmpty()) {
+								return super.preVisitDirectory(dir, attrs);
+							}
+							TarArchiveEntry entry = new TarArchiveEntry(relative.toFile());
+							tarOut.putArchiveEntry(entry);
+							tarOut.closeArchiveEntry();
+							return super.preVisitDirectory(dir, attrs);
+						}
+
+						@Override
+						public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
+							if (file.getFileName().toString().endsWith(".xml") == false) {
+								return super.visitFile(file, attrs);
+							}
+							Path relative = repoPath.relativize(file);
+							TarArchiveEntry entry = new TarArchiveEntry(relative.toFile());
+							entry.setSize(Files.size(file));
+							tarOut.putArchiveEntry(entry);
+							try {
+								IOUtils.copy(Files.newInputStream(file), tarOut);
+							} catch (IOException e) {
+								logger.error(e);
+							}
+							tarOut.closeArchiveEntry();
+							return super.visitFile(file, attrs);
+						}
+						
+					});
+					tarOut.finish();
+				}				
+			}
+		} catch (IOException e) {
+			logger.error(e);
+		}
+		try {
+			return Files.newInputStream(tarFile);
+		} catch (IOException e) {
+			logger.error(e);
+		}
+		return null;
+	}
+
+	protected void openPolicyTab(File policy, boolean readOnly) {
+		//
+		// Sanity check
+		//
+		assert policy != null;
+		assert policy.isFile();
+		if (policy == null || ! policy.isFile()) {
+			throw new IllegalArgumentException("You must specify a file.");
+		}
+		Status status;
+		Path relativePath;
+		String base;
+		try {
+			//
+			// Grab our working repository
+			//
+			Path repoPath = ((XacmlAdminUI)getUI()).getUserGitPath();
+			final Git git = Git.open(repoPath.toFile());
+			//
+			// Get our status
+			//
+			relativePath = repoPath.relativize(Paths.get(policy.getPath()));
+			base = relativePath.toString();
+			if (logger.isDebugEnabled()) {
+				logger.debug("Status on base: " + base);
+			}
+			status = git.status().addPath(base).call();
+		} catch (NoWorkTreeException | IOException | GitAPIException e) {
+			logger.error("Failed to get status on " + policy + " " + e);
+			AdminNotification.error("Could not get Git status on the file.");
+			return;
+		}
+		//
+		// Check if its clean
+		//
+		if (status.isClean() == false) {
+			//
+			// Check if its conflicting
+			//
+			for (String conflict : status.getConflicting()) {
+				if (conflict.equals(base)) {
+					//
+					// Yes - we won't be able to edit it
+					//
+					AdminNotification.error("Policy has conflicts with master, please synchronize the repository.");
+					return;
+				}
+			}
+		}
+		//
+		// Check to see if there already is a tab open
+		//
+		Iterator<Component> iter = self.tabSheet.iterator();
+		while (iter.hasNext()) {
+			Component c = iter.next();
+			if (c instanceof PolicyEditor) {
+				Object data = ((PolicyEditor) c).getData();
+				if (data != null && data instanceof File && ((File)data).equals(policy)) {
+					self.tabSheet.setSelectedTab(c);
+					return;
+				}
+			}
+		}
+		//
+		// No tab is open, create a new one
+		//
+		PolicyEditor editor = null;
+		try {
+			editor = new PolicyEditor(policy, this.treeContainer, readOnly);
+		} catch (IOException e) {
+			logger.error("Failed to open policy");
+			editor = null;
+		}
+		if (editor != null) {
+			editor.setWidth("100%");
+			Tab tab = self.tabSheet.addTab(editor);
+			editor.setTab(tab);
+			tab.setClosable(true);
+			
+			self.tabSheet.setSelectedTab(editor);
+		} else {
+			AdminNotification.error("The Policy File is not a Xacml 3.0 policy.");
+		}
+	}
+
+	@Override
+	public void drop(DragAndDropEvent event) {
+		Transferable t = event.getTransferable();
+		Component source = t.getSourceComponent();
+		if (source != this.treeWorkspace) {
+			assert false;
+			throw new IllegalArgumentException();
+		}
+		TableTransferable tt = (TableTransferable) t;
+		File sourceFile = (File) tt.getItemId();
+		
+		AbstractSelectTargetDetails target = (AbstractSelectTargetDetails)event.getTargetDetails();
+		File targetFile = (File) target.getItemIdOver();
+		
+		if (sourceFile.isFile() && targetFile != null && targetFile.isDirectory()) {
+			//
+			// Construct destination filename
+			//
+			Path dest = targetFile.toPath().resolve(sourceFile.getName());
+			//
+			// Check if the target domain exists
+			//
+			if (Files.exists(dest)) {
+				//
+				// Prompt the user
+				//
+				Notification.show("A policy file with that name already exists in that directory.", Notification.Type.ERROR_MESSAGE);
+			} else {
+				//
+				// Go ahead and rename it
+				//
+				this.renamePolicyFile(sourceFile, dest.toFile(), targetFile);
+			}
+		}
+	}
+	
+	protected void renamePolicyFile(File sourceFile, File dest, File parent) {
+		try {
+			if (sourceFile.renameTo(dest)) {
+				this.treeContainer.setParent(sourceFile, parent);
+				this.treeContainer.updateItem(parent);
+			}
+		} catch (Exception e) {
+			String error = "Failed to rename " + sourceFile + " to: " + dest + System.lineSeparator() + e.getLocalizedMessage();
+			logger.error(error);
+			AdminNotification.error(error);
+		}
+	}
+
+	@Override
+	public AcceptCriterion getAcceptCriterion() {
+        return AcceptAll.get();
+	}
+	
+	@AutoGenerated
+	private VerticalLayout buildMainLayout() {
+		// common part: create layout
+		mainLayout = new VerticalLayout();
+		mainLayout.setImmediate(false);
+		mainLayout.setWidth("100%");
+		mainLayout.setHeight("100%");
+		mainLayout.setMargin(false);
+		
+		// top-level component properties
+		setWidth("100.0%");
+		setHeight("100.0%");
+		
+		// horizontalSplitPanel
+		horizontalSplitPanel = buildHorizontalSplitPanel();
+		mainLayout.addComponent(horizontalSplitPanel);
+		mainLayout.setExpandRatio(horizontalSplitPanel, 1.0f);
+		
+		return mainLayout;
+	}
+
+	@AutoGenerated
+	private HorizontalSplitPanel buildHorizontalSplitPanel() {
+		// common part: create layout
+		horizontalSplitPanel = new HorizontalSplitPanel();
+		horizontalSplitPanel.setImmediate(false);
+		horizontalSplitPanel.setWidth("100.0%");
+		horizontalSplitPanel.setHeight("100.0%");
+		
+		// verticalLayoutLeftPanel
+		verticalLayoutLeftPanel = buildVerticalLayoutLeftPanel();
+		horizontalSplitPanel.addComponent(verticalLayoutLeftPanel);
+		
+		// verticalLayoutRightPanel
+		verticalLayoutRightPanel = buildVerticalLayoutRightPanel();
+		horizontalSplitPanel.addComponent(verticalLayoutRightPanel);
+		
+		return horizontalSplitPanel;
+	}
+
+	@AutoGenerated
+	private VerticalLayout buildVerticalLayoutLeftPanel() {
+		// common part: create layout
+		verticalLayoutLeftPanel = new VerticalLayout();
+		verticalLayoutLeftPanel.setImmediate(false);
+		verticalLayoutLeftPanel.setWidth("100.0%");
+		verticalLayoutLeftPanel.setHeight("100.0%");
+		verticalLayoutLeftPanel.setMargin(true);
+		verticalLayoutLeftPanel.setSpacing(true);
+		
+		// horizontalLayoutLeftToolbar
+		horizontalLayoutLeftToolbar = buildHorizontalLayoutLeftToolbar();
+		verticalLayoutLeftPanel.addComponent(horizontalLayoutLeftToolbar);
+		
+		// treeWorkspace
+		treeWorkspace = new TreeTable();
+		treeWorkspace.setImmediate(true);
+		treeWorkspace.setWidth("100.0%");
+		treeWorkspace.setHeight("100.0%");
+		verticalLayoutLeftPanel.addComponent(treeWorkspace);
+		verticalLayoutLeftPanel.setExpandRatio(treeWorkspace, 1.0f);
+		
+		return verticalLayoutLeftPanel;
+	}
+
+	@AutoGenerated
+	private HorizontalLayout buildHorizontalLayoutLeftToolbar() {
+		// common part: create layout
+		horizontalLayoutLeftToolbar = new HorizontalLayout();
+		horizontalLayoutLeftToolbar.setImmediate(false);
+		horizontalLayoutLeftToolbar.setWidth("100.0%");
+		horizontalLayoutLeftToolbar.setHeight("-1px");
+		horizontalLayoutLeftToolbar.setMargin(false);
+		horizontalLayoutLeftToolbar.setSpacing(true);
+		
+		// horizontalLayoutLeftToolbarLeft
+		horizontalLayoutLeftToolbarLeft = buildHorizontalLayoutLeftToolbarLeft();
+		horizontalLayoutLeftToolbar
+				.addComponent(horizontalLayoutLeftToolbarLeft);
+		
+		// buttonLeft
+		buttonLeft = new Button();
+		buttonLeft.setCaption("<<");
+		buttonLeft.setImmediate(true);
+		buttonLeft.setDescription("Minimize left panel.");
+		buttonLeft.setWidth("-1px");
+		buttonLeft.setHeight("-1px");
+		horizontalLayoutLeftToolbar.addComponent(buttonLeft);
+		horizontalLayoutLeftToolbar.setComponentAlignment(buttonLeft,
+				new Alignment(34));
+		
+		return horizontalLayoutLeftToolbar;
+	}
+
+	@AutoGenerated
+	private HorizontalLayout buildHorizontalLayoutLeftToolbarLeft() {
+		// common part: create layout
+		horizontalLayoutLeftToolbarLeft = new HorizontalLayout();
+		horizontalLayoutLeftToolbarLeft.setImmediate(false);
+		horizontalLayoutLeftToolbarLeft.setWidth("-1px");
+		horizontalLayoutLeftToolbarLeft.setHeight("-1px");
+		horizontalLayoutLeftToolbarLeft.setMargin(false);
+		horizontalLayoutLeftToolbarLeft.setSpacing(true);
+		
+		// buttonSynchronize
+		buttonSynchronize = new Button();
+		buttonSynchronize.setCaption("Synchronize Repository");
+		buttonSynchronize.setImmediate(true);
+		buttonSynchronize
+				.setDescription("Synchronize local repository with main branch.");
+		buttonSynchronize.setWidth("-1px");
+		buttonSynchronize.setHeight("-1px");
+		horizontalLayoutLeftToolbarLeft.addComponent(buttonSynchronize);
+		
+		// buttonExport
+		buttonExport = new Button();
+		buttonExport.setCaption("Export Workspace");
+		buttonExport.setImmediate(true);
+		buttonExport.setDescription("Export your workspace to your local drive.");
+		buttonExport.setWidth("-1px");
+		buttonExport.setHeight("-1px");
+		horizontalLayoutLeftToolbarLeft.addComponent(buttonExport);
+		
+		return horizontalLayoutLeftToolbarLeft;
+	}
+
+	@AutoGenerated
+	private VerticalLayout buildVerticalLayoutRightPanel() {
+		// common part: create layout
+		verticalLayoutRightPanel = new VerticalLayout();
+		verticalLayoutRightPanel.setImmediate(false);
+		verticalLayoutRightPanel.setWidth("100.0%");
+		verticalLayoutRightPanel.setHeight("-1px");
+		verticalLayoutRightPanel.setMargin(true);
+		verticalLayoutRightPanel.setSpacing(true);
+		
+		// horizontalLayoutRightToolbar
+		horizontalLayoutRightToolbar = buildHorizontalLayoutRightToolbar();
+		verticalLayoutRightPanel.addComponent(horizontalLayoutRightToolbar);
+		
+		// tabSheet
+		tabSheet = new TabSheet();
+		tabSheet.setImmediate(true);
+		tabSheet.setWidth("100.0%");
+		tabSheet.setHeight("-1px");
+		verticalLayoutRightPanel.addComponent(tabSheet);
+		verticalLayoutRightPanel.setExpandRatio(tabSheet, 1.0f);
+		
+		return verticalLayoutRightPanel;
+	}
+
+	@AutoGenerated
+	private HorizontalLayout buildHorizontalLayoutRightToolbar() {
+		// common part: create layout
+		horizontalLayoutRightToolbar = new HorizontalLayout();
+		horizontalLayoutRightToolbar.setImmediate(false);
+		horizontalLayoutRightToolbar.setWidth("100.0%");
+		horizontalLayoutRightToolbar.setHeight("-1px");
+		horizontalLayoutRightToolbar.setMargin(false);
+		horizontalLayoutRightToolbar.setSpacing(true);
+		
+		// buttonRight
+		buttonRight = new Button();
+		buttonRight.setCaption(">>");
+		buttonRight.setImmediate(true);
+		buttonRight.setDescription("Restore left panel.");
+		buttonRight.setWidth("-1px");
+		buttonRight.setHeight("-1px");
+		horizontalLayoutRightToolbar.addComponent(buttonRight);
+		
+		return horizontalLayoutRightToolbar;
+	}
+}
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/components/Simulator.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/components/Simulator.java
new file mode 100644
index 0000000..c554568
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/components/Simulator.java
@@ -0,0 +1,69 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ *
+ */
+
+package org.apache.openaz.xacml.admin.components;
+
+import com.vaadin.annotations.AutoGenerated;
+import com.vaadin.annotations.Theme;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.ui.AbsoluteLayout;
+import com.vaadin.ui.CustomComponent;
+import com.vaadin.ui.UI;
+
+public class Simulator extends CustomComponent {
+
+	@AutoGenerated
+	private AbsoluteLayout mainLayout;
+
+	private static final long serialVersionUID = 1L;
+
+	@Theme("xacml_pap_admin")
+	public static class SimulatorUI extends UI {
+		private static final long serialVersionUID = 1L;
+
+		@Override
+		protected void init(VaadinRequest request) {
+			// TODO Auto-generated method stub
+
+		}
+
+	}
+	
+	/**
+	 * The constructor should first build the main layout, set the
+	 * composition root and then do any custom initialization.
+	 *
+	 * The constructor will not be automatically regenerated by the
+	 * visual editor.
+	 */
+	public Simulator() {
+		buildMainLayout();
+		setCompositionRoot(mainLayout);
+
+		// TODO add user code here
+	}
+
+	@AutoGenerated
+	private void buildMainLayout() {
+		// the main layout and components will be created here
+		mainLayout = new AbsoluteLayout();
+	}
+
+}
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/components/UserManagement.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/components/UserManagement.java
new file mode 100644
index 0000000..a883dec
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/components/UserManagement.java
@@ -0,0 +1,114 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ *
+ */
+
+package org.apache.openaz.xacml.admin.components;
+
+import com.vaadin.annotations.AutoGenerated;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.CustomComponent;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.Table;
+import com.vaadin.ui.VerticalLayout;
+
+public class UserManagement extends CustomComponent {
+	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */
+
+	@AutoGenerated
+	private VerticalLayout mainLayout;
+	@AutoGenerated
+	private Table tableUsers;
+	@AutoGenerated
+	private HorizontalLayout horizontalLayoutToolbar;
+	@AutoGenerated
+	private Button buttonRemove;
+	@AutoGenerated
+	private Button buttonAdd;
+	private static final long serialVersionUID = 1L;
+	/**
+	 * The constructor should first build the main layout, set the
+	 * composition root and then do any custom initialization.
+	 *
+	 * The constructor will not be automatically regenerated by the
+	 * visual editor.
+	 */
+	public UserManagement() {
+		buildMainLayout();
+		setCompositionRoot(mainLayout);
+
+		// TODO add user code here
+	}
+
+	@AutoGenerated
+	private VerticalLayout buildMainLayout() {
+		// common part: create layout
+		mainLayout = new VerticalLayout();
+		mainLayout.setImmediate(false);
+		mainLayout.setWidth("100%");
+		mainLayout.setHeight("-1px");
+		mainLayout.setMargin(false);
+		
+		// top-level component properties
+		setWidth("100.0%");
+		setHeight("-1px");
+		
+		// horizontalLayoutToolbar
+		horizontalLayoutToolbar = buildHorizontalLayoutToolbar();
+		mainLayout.addComponent(horizontalLayoutToolbar);
+		
+		// tableUsers
+		tableUsers = new Table();
+		tableUsers.setImmediate(false);
+		tableUsers.setWidth("100.0%");
+		tableUsers.setHeight("-1px");
+		mainLayout.addComponent(tableUsers);
+		
+		return mainLayout;
+	}
+
+	@AutoGenerated
+	private HorizontalLayout buildHorizontalLayoutToolbar() {
+		// common part: create layout
+		horizontalLayoutToolbar = new HorizontalLayout();
+		horizontalLayoutToolbar.setImmediate(false);
+		horizontalLayoutToolbar.setWidth("-1px");
+		horizontalLayoutToolbar.setHeight("-1px");
+		horizontalLayoutToolbar.setMargin(true);
+		horizontalLayoutToolbar.setSpacing(true);
+		
+		// buttonAdd
+		buttonAdd = new Button();
+		buttonAdd.setCaption("Add User");
+		buttonAdd.setImmediate(false);
+		buttonAdd.setWidth("-1px");
+		buttonAdd.setHeight("-1px");
+		horizontalLayoutToolbar.addComponent(buttonAdd);
+		
+		// buttonRemove
+		buttonRemove = new Button();
+		buttonRemove.setCaption("Remove User");
+		buttonRemove.setImmediate(false);
+		buttonRemove.setWidth("-1px");
+		buttonRemove.setHeight("-1px");
+		horizontalLayoutToolbar.addComponent(buttonRemove);
+		
+		return horizontalLayoutToolbar;
+	}
+
+}
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/components/package-info.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/components/package-info.java
new file mode 100644
index 0000000..947702e
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/components/package-info.java
@@ -0,0 +1,28 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ *
+ */
+
+/**
+ * 
+ */
+/**
+ * @author pameladragosh
+ *
+ */
+package org.apache.openaz.xacml.admin.components;
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/converters/CategoryConverter.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/converters/CategoryConverter.java
new file mode 100644
index 0000000..4229a4e
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/converters/CategoryConverter.java
@@ -0,0 +1,71 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ *
+ */
+
+package org.apache.openaz.xacml.admin.converters;
+
+import java.util.Locale;
+
+import org.apache.openaz.xacml.admin.jpa.Category;
+import org.apache.openaz.xacml.api.Identifier;
+import com.vaadin.data.util.converter.Converter;
+
+public class CategoryConverter implements Converter<Object, Category> {
+	private static final long serialVersionUID = 1L;
+
+	@Override
+	public Category convertToModel(Object value,
+			Class<? extends Category> targetType, Locale locale)
+			throws Converter.ConversionException {
+		Category category = new Category();
+		if (value == null) {
+			return category;
+		}
+		if (value instanceof Identifier) {
+			category.setXacmlId(((Identifier)value).stringValue());
+		} else {
+			category.setXacmlId(value.toString());
+		}
+		return category;
+	}
+
+	@Override
+	public Object convertToPresentation(Category value,
+			Class<? extends Object> targetType, Locale locale)
+			throws Converter.ConversionException {
+		if (targetType.getName().equals(String.class.getName())) {
+			return value.getXacmlId();
+		}
+		if (targetType.getName().equals(Identifier.class.getName())) {
+			return value.getIdentifer();
+		}
+		return value.getIdentifer();
+	}
+
+	@Override
+	public Class<Category> getModelType() {
+		return Category.class;
+	}
+
+	@Override
+	public Class<Object> getPresentationType() {
+		return Object.class;
+	}
+
+}
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/converters/ConstraintTypeConverter.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/converters/ConstraintTypeConverter.java
new file mode 100644
index 0000000..c6705ca
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/converters/ConstraintTypeConverter.java
@@ -0,0 +1,79 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ *
+ */
+
+package org.apache.openaz.xacml.admin.converters;
+
+import java.util.Locale;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.openaz.xacml.admin.jpa.ConstraintType;
+import com.vaadin.data.util.converter.Converter;
+
+public class ConstraintTypeConverter  implements Converter<Object, ConstraintType> {
+	private static final long serialVersionUID = 1L;
+	private static final Log logger	= LogFactory.getLog(ConstraintTypeConverter.class);
+
+	@Override
+	public ConstraintType convertToModel(Object value,
+			Class<? extends ConstraintType> targetType, Locale locale)
+			throws Converter.ConversionException {
+		if (logger.isTraceEnabled()) {
+			logger.trace("convertToModel:" + value + " target " + targetType);
+		}
+		ConstraintType constraintValue = new ConstraintType();
+		if (value == null) {
+			return constraintValue;
+		}
+		// PLD TODO??
+		return constraintValue;
+	}
+
+	@Override
+	public Object convertToPresentation(ConstraintType value,
+			Class<? extends Object> targetType, Locale locale)
+			throws Converter.ConversionException {
+		if (logger.isTraceEnabled()) {
+			logger.trace("convertToPresentation:" + value + " target " + targetType);
+		}
+		if (value == null) {
+			return null;
+		}
+		if (targetType.isAssignableFrom(String.class)) {
+			return value.getConstraintType();
+		}
+		if (targetType.isInstance(Integer.class)) {
+			return value.getId();
+		}
+		return null;
+	}
+
+	@Override
+	public Class<ConstraintType> getModelType() {
+		return ConstraintType.class;
+	}
+
+	@Override
+	public Class<Object> getPresentationType() {
+		return Object.class;
+	}
+
+}
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/converters/ConstraintValueConverter.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/converters/ConstraintValueConverter.java
new file mode 100644
index 0000000..03c76be
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/converters/ConstraintValueConverter.java
@@ -0,0 +1,73 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ *
+ */
+
+package org.apache.openaz.xacml.admin.converters;
+
+import java.util.Locale;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.openaz.xacml.admin.jpa.ConstraintValue;
+import com.vaadin.data.util.converter.Converter;
+
+public class ConstraintValueConverter implements Converter<Object, ConstraintValue> {
+	private static final long serialVersionUID = 1L;
+	private static final Log logger	= LogFactory.getLog(ConstraintValueConverter.class);
+	
+	@Override
+	public ConstraintValue convertToModel(Object value,
+			Class<? extends ConstraintValue> targetType, Locale locale)
+			throws Converter.ConversionException {
+		if (logger.isTraceEnabled()) {
+			logger.trace("convertToModel:" + value + " target " + targetType);
+		}
+		ConstraintValue newValue = new ConstraintValue();
+		if (value == null) {
+			return newValue;
+		}
+		// PLD TODO?
+		return newValue;
+	}
+
+	@Override
+	public Object convertToPresentation(ConstraintValue value,
+			Class<? extends Object> targetType, Locale locale)
+			throws Converter.ConversionException {
+		if (logger.isTraceEnabled()) {
+			logger.trace("convertToPresentation:" + value + " target " + targetType);
+		}
+		if (value == null) {
+			return null;
+		}
+		return value.getProperty();
+	}
+
+	@Override
+	public Class<ConstraintValue> getModelType() {
+		return ConstraintValue.class;
+	}
+
+	@Override
+	public Class<Object> getPresentationType() {
+		return Object.class;
+	}
+
+}
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/converters/DatatypeConverter.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/converters/DatatypeConverter.java
new file mode 100644
index 0000000..8817428
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/converters/DatatypeConverter.java
@@ -0,0 +1,76 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ *
+ */
+
+package org.apache.openaz.xacml.admin.converters;
+
+import java.util.Locale;
+
+import org.apache.openaz.xacml.admin.jpa.Datatype;
+import org.apache.openaz.xacml.api.Identifier;
+import com.vaadin.data.util.converter.Converter;
+
+public class DatatypeConverter implements Converter<Object, Datatype> {
+	private static final long serialVersionUID = 1L;
+
+	@Override
+	public Datatype convertToModel(Object value,
+			Class<? extends Datatype> targetType, Locale locale)
+			throws Converter.ConversionException {
+		Datatype datatype = new Datatype();
+		if (value == null) {
+			return datatype;
+		}
+		if (value instanceof Identifier) {
+			datatype.setXacmlId(((Identifier)value).stringValue());
+		} else {
+			datatype.setXacmlId(value.toString());
+		}
+		return datatype;
+	}
+
+	@Override
+	public Object convertToPresentation(Datatype value,
+			Class<? extends Object> targetType, Locale locale)
+			throws Converter.ConversionException {
+		if (value == null) {
+			return null;
+		}
+		if (targetType.isInstance(String.class) ||
+			targetType.getName().equals(String.class.getName())) {
+			return value.getXacmlId();
+		}
+		if (targetType.isInstance(Identifier.class) ||
+			targetType.getName().equals(Identifier.class.getName())) {
+			return value.getIdentifer();
+		}
+		return value.getIdentifer();
+	}
+
+	@Override
+	public Class<Datatype> getModelType() {
+		return Datatype.class;
+	}
+
+	@Override
+	public Class<Object> getPresentationType() {
+		return Object.class;
+	}
+
+}
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/converters/IdentifierConverter.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/converters/IdentifierConverter.java
new file mode 100644
index 0000000..07b810d
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/converters/IdentifierConverter.java
@@ -0,0 +1,61 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ *
+ */
+
+package org.apache.openaz.xacml.admin.converters;
+
+import java.util.Locale;
+
+import org.apache.openaz.xacml.api.Identifier;
+import org.apache.openaz.xacml.std.IdentifierImpl;
+import com.vaadin.data.util.converter.Converter;
+
+
+public class IdentifierConverter implements Converter<Object, Identifier> {
+	private static final long serialVersionUID = 1L;
+
+	@Override
+	public Identifier convertToModel(Object value,
+			Class<? extends Identifier> targetType, Locale locale)
+			throws Converter.ConversionException {
+		return new IdentifierImpl(value.toString());
+	}
+
+	@Override
+	public Object convertToPresentation(Identifier value,
+			Class<? extends Object> targetType, Locale locale)
+			throws Converter.ConversionException {
+		if (targetType.isInstance(String.class) ||
+			targetType.getName().equals(String.class.getName())) {
+			return value.stringValue();
+		}
+		return null;
+	}
+
+	@Override
+	public Class<Identifier> getModelType() {
+		return Identifier.class;
+	}
+
+	@Override
+	public Class<Object> getPresentationType() {
+		return Object.class;
+	}
+
+}
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/converters/XacmlConverterFactory.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/converters/XacmlConverterFactory.java
new file mode 100644
index 0000000..32fb8bf
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/converters/XacmlConverterFactory.java
@@ -0,0 +1,83 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ *
+ */
+
+package org.apache.openaz.xacml.admin.converters;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.openaz.xacml.admin.jpa.Category;
+import org.apache.openaz.xacml.admin.jpa.ConstraintType;
+import org.apache.openaz.xacml.admin.jpa.ConstraintValue;
+import org.apache.openaz.xacml.admin.jpa.Datatype;
+import org.apache.openaz.xacml.api.Identifier;
+import com.vaadin.data.util.converter.Converter;
+import com.vaadin.data.util.converter.DefaultConverterFactory;
+
+public class XacmlConverterFactory extends DefaultConverterFactory {
+	private static final long serialVersionUID = 1L;
+	private static final Log logger	= LogFactory.getLog(XacmlConverterFactory.class);
+	
+    @SuppressWarnings("unchecked")
+	@Override
+    public <PRESENTATION, MODEL> Converter<PRESENTATION, MODEL>
+            createConverter(Class<PRESENTATION> presentationType,
+                            Class<MODEL> modelType) {
+    	if (logger.isTraceEnabled()) {
+    		logger.trace("createConverter: " + presentationType + " from model " + modelType);
+    	}
+    	//
+        // Handle one particular type conversion for Categories
+    	//
+        if (Category.class == modelType) {
+            return (Converter<PRESENTATION, MODEL>) new CategoryConverter();
+        }
+        //
+        // Handle one particular type conversion for Datatypes
+        //
+        if (Datatype.class == modelType) {
+            return (Converter<PRESENTATION, MODEL>) new DatatypeConverter();
+        }
+        //
+        // Handle one particular type conversion for ConstraintType
+        //
+        if (ConstraintType.class == modelType) {
+        	return (Converter<PRESENTATION, MODEL>) new ConstraintTypeConverter();
+        }
+        //
+        // Handle one particular type conversion for ConstraintType
+        //
+        if (ConstraintValue.class == modelType) {
+        	return (Converter<PRESENTATION, MODEL>) new ConstraintValueConverter();
+        }
+        //
+        // Handle one particular type conversion for Identifiers
+        //
+        if (Identifier.class == modelType) {
+        	return (Converter<PRESENTATION, MODEL>) new IdentifierConverter();
+        }
+        //
+        // Default to the supertype
+        //
+        return super.createConverter(presentationType,
+                                     modelType);
+    }
+
+}
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/Attribute.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/Attribute.java
new file mode 100644
index 0000000..84ec82a
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/Attribute.java
@@ -0,0 +1,327 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ *
+ */
+
+package org.apache.openaz.xacml.admin.jpa;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.NamedQuery;
+import javax.persistence.OneToMany;
+import javax.persistence.PrePersist;
+import javax.persistence.PreUpdate;
+import javax.persistence.Table;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+import javax.persistence.Transient;
+
+import org.apache.openaz.xacml.api.Identifier;
+import org.apache.openaz.xacml.std.IdentifierImpl;
+
+
+/**
+ * The persistent class for the Attribute database table.
+ * 
+ */
+@Entity
+@Table(name="Attribute")
+@NamedQuery(name="Attribute.findAll", query="SELECT a FROM Attribute a")
+public class Attribute implements Serializable {
+	private static final long serialVersionUID = 1L;
+	
+	public static String	ATTRIBUTE_DESIGNATOR = "Attribute Designator";
+	public static String	ATTRIBUTE_SELECTOR = "Attribute Selector";
+
+	@Id
+	@GeneratedValue(strategy = GenerationType.AUTO)
+	@Column(name="id")
+	private int id;
+
+	//bi-directional many-to-one association to Category
+	@ManyToOne
+	@JoinColumn(name="constraint_type", nullable=true)
+	private ConstraintType constraintType;
+
+	@Column(name="created_by", nullable=false, length=255)
+	private String createdBy = "guest";
+
+	@Temporal(TemporalType.TIMESTAMP)
+	@Column(name="created_date", updatable=false)
+	private Date createdDate;
+
+	@Column(name="description", nullable=true, length=2048)
+	private String description;
+
+	@Column(name="modified_by", nullable=false, length=255)
+	private String modifiedBy = "guest";
+
+	@Temporal(TemporalType.TIMESTAMP)
+	@Column(name="modified_date", nullable=false)
+	private Date modifiedDate;
+
+	@Column(name="xacml_id", nullable=false)
+	private String xacmlId = "urn";
+
+	//bi-directional many-to-one association to ConstraintValue
+	@OneToMany(mappedBy="attribute", orphanRemoval=true, cascade=CascadeType.REMOVE)
+	private Set<ConstraintValue> constraintValues = new HashSet<ConstraintValue>();
+
+	//bi-directional many-to-one association to Category
+	@ManyToOne
+	@JoinColumn(name="category")
+	private Category categoryBean;
+
+	//bi-directional many-to-one association to Datatype
+	@ManyToOne
+	@JoinColumn(name="datatype")
+	private Datatype datatypeBean;
+
+	@Column(name="is_designator", nullable=false)
+	private char isDesignator = '1';
+
+	@Column(name="selector_path", nullable=true, length=2048)
+	private String selectorPath;
+	
+	@Transient
+	private String issuer = null;
+	
+	@Transient
+	private boolean mustBePresent = false;
+
+	public Attribute() {
+	}
+	
+	public Attribute(String domain) {
+		this.xacmlId = domain;
+	}
+	
+	public Attribute(String domain, String user) {
+		this(domain);
+		this.createdBy = user;
+		this.modifiedBy = user;
+	}
+	public Attribute(Attribute copy, String user) {
+		this(copy.getXacmlId() + ":(0)", user);
+		this.constraintType = copy.getConstraintType();
+		this.categoryBean = copy.getCategoryBean();
+		this.datatypeBean = copy.getDatatypeBean();
+		this.description = copy.getDescription();
+		for (ConstraintValue value : copy.getConstraintValues()) {
+			ConstraintValue newValue = new ConstraintValue(value);
+			newValue.setAttribute(this);
+			this.addConstraintValue(newValue);
+		}
+	}
+
+	@PrePersist
+	public void	prePersist() {
+		Date date = new Date();
+		this.createdDate = date;
+		this.modifiedDate = date;
+	}
+	
+	@PreUpdate
+	public void preUpdate() {
+		this.modifiedDate = new Date();
+	}
+
+	public int getId() {
+		return this.id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+
+	public ConstraintType getConstraintType() {
+		return this.constraintType;
+	}
+
+	public void setConstraintType(ConstraintType constraintType) {
+		this.constraintType = constraintType;
+	}
+
+	public String getCreatedBy() {
+		return this.createdBy;
+	}
+
+	public void setCreatedBy(String createdBy) {
+		this.createdBy = createdBy;
+	}
+
+	public Date getCreatedDate() {
+		return this.createdDate;
+	}
+
+	public void setCreatedDate(Date createdDate) {
+		this.createdDate = createdDate;
+	}
+
+	public String getDescription() {
+		return this.description;
+	}
+
+	public void setDescription(String description) {
+		this.description = description;
+	}
+
+	public String getModifiedBy() {
+		return this.modifiedBy;
+	}
+
+	public void setModifiedBy(String modifiedBy) {
+		this.modifiedBy = modifiedBy;
+	}
+
+	public Date getModifiedDate() {
+		return this.modifiedDate;
+	}
+
+	public void setModifiedDate(Date modifiedDate) {
+		this.modifiedDate = modifiedDate;
+	}
+
+	public String getXacmlId() {
+		return this.xacmlId;
+	}
+	
+	@Transient
+	public Identifier getXacmlIdentifier() {
+		return new IdentifierImpl(this.xacmlId);
+	}
+
+	public void setXacmlId(String xacmlId) {
+		this.xacmlId = xacmlId;
+	}
+
+	public Set<ConstraintValue> getConstraintValues() {
+		return this.constraintValues;
+	}
+
+	public void setConstraintValues(Set<ConstraintValue> constraintValues) {
+		for (ConstraintValue value : this.constraintValues) {
+			value.setAttribute(this);
+		}
+		this.constraintValues = constraintValues;
+	}
+
+	public ConstraintValue addConstraintValue(ConstraintValue constraintValue) {
+		if (this.constraintValues == null) {
+			this.constraintValues = new HashSet<ConstraintValue>();
+		}
+		this.constraintValues.add(constraintValue);
+		constraintValue.setAttribute(this);
+
+		return constraintValue;
+	}
+
+	public ConstraintValue removeConstraintValue(ConstraintValue constraintValue) {
+		this.constraintValues.remove(constraintValue);
+		constraintValue.setAttribute(null);
+
+		return constraintValue;
+	}
+	
+	public void removeAllConstraintValues() {
+		if (this.constraintValues == null) {
+			return;
+		}
+		for (ConstraintValue value : this.constraintValues) {
+			value.setAttribute(null);
+		}
+		this.constraintValues.clear();
+	}
+
+	public Category getCategoryBean() {
+		return this.categoryBean;
+	}
+
+	public void setCategoryBean(Category categoryBean) {
+		this.categoryBean = categoryBean;
+	}
+
+	public Datatype getDatatypeBean() {
+		return this.datatypeBean;
+	}
+
+	public void setDatatypeBean(Datatype datatypeBean) {
+		this.datatypeBean = datatypeBean;
+	}
+
+	public char getIsDesignator() {
+		return this.isDesignator;
+	}
+	
+	public void setIsDesignator(char is) {
+		this.isDesignator = is;
+	}
+	
+	public String getSelectorPath() {
+		return this.selectorPath;
+	}
+	
+	public void setSelectorPath(String path) {
+		this.selectorPath = path;
+	}
+	
+	@Transient
+	public String getIssuer() {
+		return issuer;
+	}
+
+	@Transient
+	public void setIssuer(String issuer) {
+		this.issuer = issuer;
+	}
+
+	@Transient
+	public boolean isMustBePresent() {
+		return mustBePresent;
+	}
+
+	@Transient
+	public void setMustBePresent(boolean mustBePresent) {
+		this.mustBePresent = mustBePresent;
+	}
+
+	@Transient
+	public boolean isDesignator() {
+		return this.isDesignator == '1';
+	}
+	
+	@Transient
+	public void setIsDesignator(boolean is) {
+		if (is) {
+			this.isDesignator = '1';
+		} else {
+			this.isDesignator = '0';
+		}
+	}
+}
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/AttributeAssignment.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/AttributeAssignment.java
new file mode 100644
index 0000000..344b7f8
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/AttributeAssignment.java
@@ -0,0 +1,94 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ *
+ */
+
+package org.apache.openaz.xacml.admin.jpa;
+
+import java.io.Serializable;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+import javax.persistence.NamedQuery;
+import javax.persistence.Table;
+
+
+/**
+ * The persistent class for the ObadviceExpressions database table.
+ * 
+ */
+@Entity
+@Table(name="AttributeAssignment")
+@NamedQuery(name="AttributeAssignment.findAll", query="SELECT a FROM AttributeAssignment a")
+public class AttributeAssignment implements Serializable {
+	private static final long serialVersionUID = 1L;
+
+	public static final String EXPRESSION_APPLY = "Apply";
+	public static final String EXPRESSION_SELECTOR = "AttributeSelector";
+	public static final String EXPRESSION_VALUE = "AttributeValue";
+	public static final String EXPRESSION_FUNCTION = "Function";
+	public static final String EXPRESSION_REFERENCE = "VarableReference";
+	public static final String EXPRESSION_DESIGNATOR = "AttributeDesignator";
+
+	@Id
+	@GeneratedValue(strategy = GenerationType.AUTO)
+	@Column(name="id")
+	private int id;
+
+	@Column(name="attribute_id")
+	private int attributeId;
+
+	//bi-directional many-to-one association to Obadvice
+	@Column(name="expression", nullable=false)
+	private String expression;
+
+	//bi-directional many-to-one association to Obadvice
+	@ManyToOne
+	private Obadvice obadvice; //NOPMD
+
+	public AttributeAssignment() {
+	}
+
+	public int getId() {
+		return this.id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+
+	public int getAttributeId() {
+		return this.attributeId;
+	}
+
+	public void setAttributeId(int attributeId) {
+		this.attributeId = attributeId;
+	}
+
+	public String getExpression() {
+		return expression;
+	}
+
+	public void setExpression(String expression) {
+		this.expression = expression;
+	}
+}
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/Category.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/Category.java
new file mode 100644
index 0000000..fdcbd3d
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/Category.java
@@ -0,0 +1,216 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ *
+ */
+
+package org.apache.openaz.xacml.admin.jpa;
+
+import java.io.Serializable;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.NamedQuery;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+
+import org.apache.openaz.xacml.api.Identifier;
+import org.apache.openaz.xacml.api.XACML3;
+import org.apache.openaz.xacml.std.IdentifierImpl;
+
+
+/**
+ * The persistent class for the Categories database table.
+ * 
+ */
+@Entity
+@Table(name="Category")
+@NamedQuery(name="Category.findAll", query="SELECT c FROM Category c")
+public class Category implements Serializable {
+	private static final long serialVersionUID = 1L;
+	
+	public static final char STANDARD = 'S';
+	public static final char CUSTOM = 'C';
+
+	@Id
+	@GeneratedValue(strategy = GenerationType.AUTO)
+	@Column(name="id")
+	private int id;
+
+	@Column(name="grouping", nullable=false, length=64)
+	private String grouping;
+
+	@Column(name="is_standard", nullable=false)
+	private char isStandard;
+
+	@Column(name="xacml_id", nullable=false, unique=true, length=255)
+	private String xacmlId;
+	
+	@Column(name="short_name", nullable=false, length=64)
+	private String shortName;
+	
+	//bi-directional many-to-one association to Attribute
+	@OneToMany(mappedBy="categoryBean")
+	private Set<Attribute> attributes = new HashSet<>();
+
+	public Category() {
+		this.xacmlId = XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT.stringValue();
+		this.grouping = "subject";
+		this.isStandard = Category.STANDARD;
+		this.shortName = "subject";
+	}
+
+	public Category(Identifier cat, String grouping, char isStandard) {
+		if (cat != null) {
+			this.xacmlId = cat.stringValue();
+		}
+		this.isStandard = isStandard;
+		if (grouping != null) {
+			this.grouping = grouping;
+		} else {
+			this.grouping = Category.extractGrouping(this.xacmlId);
+		}
+	}
+
+	public Category(Identifier cat, String grouping) {
+		this(cat, grouping, Category.STANDARD);
+	}
+
+	public Category(Identifier cat, char standard) {
+		this(cat, null, standard);
+	}
+
+	public Category(Identifier cat) {
+		this(cat, Category.STANDARD);
+	}
+
+	public int getId() {
+		return this.id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+
+	public String getGrouping() {
+		return this.grouping;
+	}
+
+	public void setGrouping(String grouping) {
+		this.grouping = grouping;
+	}
+
+	public char getIsStandard() {
+		return this.isStandard;
+	}
+
+	public void setIsStandard(char isStandard) {
+		this.isStandard = isStandard;
+	}
+
+	public String getXacmlId() {
+		return this.xacmlId;
+	}
+
+	public void setXacmlId(String xacmlId) {
+		this.xacmlId = xacmlId;
+	}
+
+	public String getShortName() {
+		return this.shortName;
+	}
+
+	public void setShortName(String shortName) {
+		this.shortName = shortName;
+	}
+
+	public Set<Attribute> getAttributes() {
+		return this.attributes;
+	}
+
+	public void setAttributes(Set<Attribute> attributes) {
+		this.attributes = attributes;
+	}
+
+	public Attribute addAttribute(Attribute attribute) {
+		getAttributes().add(attribute);
+		attribute.setCategoryBean(this);
+
+		return attribute;
+	}
+
+	public Attribute removeAttribute(Attribute attribute) {
+		getAttributes().remove(attribute);
+		attribute.setCategoryBean(null);
+
+		return attribute;
+	}
+
+	@Transient
+	public boolean isStandard() {
+		return this.isStandard == Category.STANDARD;
+	}
+	
+	@Transient
+	public boolean isCustom() {
+		return this.isStandard == Category.CUSTOM;
+	}
+	
+	@Transient
+	public static String	extractGrouping(String xacmlId) {
+		if (xacmlId == null) {
+			return null;
+		}
+		if (xacmlId.matches(".*:attribute\\-category:.*")) {
+			String[] parts = xacmlId.split("[:]");
+			if (parts != null && parts.length > 0) {
+				return parts[parts.length - 1];
+			}
+		} else if (xacmlId.matches(".*:[a-zA-Z]+[\\-]category:.*")) {
+			String[] parts = xacmlId.split("[:]");
+			if (parts != null && parts.length > 0) {
+				for (String part : parts) {
+					int index = part.indexOf("-category");
+					if (index > 0) {
+						return part.substring(0, index);
+					}
+				}
+			}
+		}
+		return null;
+	}
+	
+	@Transient
+	public Identifier getIdentifer() {
+		return new IdentifierImpl(this.xacmlId);
+	}
+
+	@Transient
+	@Override
+	public String toString() {
+		return "Category [id=" + id + ", grouping=" + grouping
+				+ ", isStandard=" + isStandard + ", xacmlId=" + xacmlId
+				+ ", attributes=" + attributes + "]";
+	}
+
+}
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/ConstraintType.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/ConstraintType.java
new file mode 100644
index 0000000..14b9008
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/ConstraintType.java
@@ -0,0 +1,117 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ *
+ */
+
+package org.apache.openaz.xacml.admin.jpa;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.NamedQuery;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+
+@Entity
+@Table(name="ConstraintType")
+@NamedQuery(name="ConstraintType.findAll", query="SELECT a FROM ConstraintType a")
+public class ConstraintType implements Serializable {
+	private static final long serialVersionUID = 1L;
+	
+	public static String ENUMERATION_TYPE = "Enumeration";
+	public static String RANGE_TYPE = "Range";
+	public static String REGEXP_TYPE = "Regular Expression";
+	
+	public static Map<String, String> defaults = new HashMap<String, String>();
+	static {
+		defaults.put(ENUMERATION_TYPE, "Enumerate a set of values that the attribute may be set to during policy creation.");
+		defaults.put(RANGE_TYPE, "Set a range of min and/or max integer/double values the attribute can be set to during policy creation.");
+		defaults.put(REGEXP_TYPE, "Define a regular expression the attribute must match against during policy creation.");
+	}
+	public static final String[] RANGE_TYPES = {"minExclusive", "minInclusive", "maxExclusive", "maxInclusive"};
+	
+	@Id
+	@GeneratedValue(strategy = GenerationType.AUTO)
+	@Column(name="id")
+	private int id;
+
+	@Column(name="constraint_type", nullable=false, length=64)
+	private String constraintType;
+	
+	@Column(name="description", nullable=false, length=255)
+	private String description;
+
+	//bi-directional many-to-one association to Attribute
+	@OneToMany(mappedBy="constraintType")
+	private Set<Attribute> attributes = new HashSet<>();
+
+	public ConstraintType() {
+		
+	}
+
+	public ConstraintType(String constraintType) {
+		this();
+		this.constraintType = constraintType;
+	}
+	
+	public ConstraintType(String constraintType, String description) {
+		this(constraintType);
+		this.description = description;
+	}
+
+	public int getId() {
+		return id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+
+	public String getConstraintType() {
+		return constraintType;
+	}
+
+	public void setConstraintType(String constraintType) {
+		this.constraintType = constraintType;
+	}
+
+	public String getDescription() {
+		return description;
+	}
+
+	public void setDescription(String description) {
+		this.description = description;
+	}
+
+	public Set<Attribute> getAttributes() {
+		return attributes;
+	}
+
+	public void setAttributes(Set<Attribute> attributes) {
+		this.attributes = attributes;
+	}
+
+}
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/ConstraintValue.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/ConstraintValue.java
new file mode 100644
index 0000000..e1f66d4
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/ConstraintValue.java
@@ -0,0 +1,116 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ *
+ */
+
+package org.apache.openaz.xacml.admin.jpa;
+
+import java.io.Serializable;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.NamedQuery;
+import javax.persistence.Table;
+
+
+/**
+ * The persistent class for the ConstraintValues database table.
+ * 
+ */
+@Entity
+@Table(name="ConstraintValues")
+@NamedQuery(name="ConstraintValue.findAll", query="SELECT c FROM ConstraintValue c")
+public class ConstraintValue implements Serializable {
+	private static final long serialVersionUID = 1L;
+
+	@Id
+	@GeneratedValue(strategy = GenerationType.AUTO)
+	@Column(name="id")
+	private int id;
+
+	@Column(name="property")
+	private String property;
+
+	@Column(name="value")
+	private String value;
+
+	//bi-directional many-to-one association to Attribute
+	@ManyToOne
+	@JoinColumn(name="attribute_id")
+	private Attribute attribute;
+
+	public ConstraintValue() {
+	}
+
+	public ConstraintValue(String property, String value) {
+		this.property = property;
+		this.value = value;
+	}
+	
+	public ConstraintValue(ConstraintValue value) {
+		this.property = value.getProperty();
+		this.value = value.getValue();
+	}
+
+	public int getId() {
+		return this.id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+
+	public String getProperty() {
+		return this.property;
+	}
+
+	public void setProperty(String property) {
+		this.property = property;
+	}
+
+	public String getValue() {
+		return this.value;
+	}
+
+	public void setValue(String value) {
+		this.value = value;
+	}
+
+	public Attribute getAttribute() {
+		return this.attribute;
+	}
+
+	public void setAttribute(Attribute attribute) {
+		this.attribute = attribute;
+	}
+	
+	public ConstraintValue clone() {
+		ConstraintValue constraint = new ConstraintValue();
+		
+		constraint.property = this.property;
+		constraint.value = this.value;
+		constraint.attribute = this.attribute;
+		
+		return constraint;
+	}
+}
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/Datatype.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/Datatype.java
new file mode 100644
index 0000000..50d4488
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/Datatype.java
@@ -0,0 +1,230 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ *
+ */
+
+package org.apache.openaz.xacml.admin.jpa;
+
+import java.io.Serializable;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.NamedQuery;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+
+import org.apache.openaz.xacml.api.Identifier;
+import org.apache.openaz.xacml.api.XACML3;
+import org.apache.openaz.xacml.std.IdentifierImpl;
+
+
+/**
+ * The persistent class for the Datatype database table.
+ * 
+ */
+@Entity
+@Table(name="Datatype")
+@NamedQuery(name="Datatype.findAll", query="SELECT d FROM Datatype d")
+public class Datatype implements Serializable {
+	private static final long serialVersionUID = 1L;
+	
+	public static final char STANDARD = 'S';
+	public static final char CUSTOM = 'C';
+
+	@Id
+	@GeneratedValue(strategy = GenerationType.AUTO)
+	@Column(name="id")
+	private int id;
+
+	@Column(name="is_standard", nullable=false)
+	private char isStandard;
+
+	@Column(name="xacml_id", nullable=false, unique=true, length=255)
+	private String xacmlId;
+
+	@Column(name="short_name", nullable=false, length=64)
+	private String shortName;
+
+	//bi-directional many-to-one association to Attribute
+	@OneToMany(mappedBy="datatypeBean")
+	private Set<Attribute> attributes = new HashSet<>();
+
+	//bi-directional many-to-one association to Attribute
+	@OneToMany(mappedBy="datatypeBean")
+	private Set<FunctionDefinition> functions = new HashSet<>();
+
+	//bi-directional many-to-one association to Attribute
+	@OneToMany(mappedBy="datatypeBean")
+	private Set<FunctionArgument> arguments = new HashSet<>();
+
+	public Datatype() {
+		this.xacmlId = XACML3.ID_DATATYPE_STRING.stringValue();
+		this.isStandard = Datatype.STANDARD;
+	}
+	
+	public Datatype(int id, Datatype dt) {
+		this.id = id;
+		this.isStandard = dt.isStandard;
+		this.xacmlId = dt.xacmlId;
+		this.shortName = dt.shortName;
+		//
+		// Make a copy?
+		//
+		this.attributes = new HashSet<>();
+	}
+	
+	public Datatype(Identifier identifier, char standard) {
+		if (identifier != null) {
+			this.xacmlId = identifier.stringValue();
+		}
+		this.isStandard = standard;
+	}
+	
+	public Datatype(Identifier identifier) {
+		this(identifier, Datatype.STANDARD);
+	}
+	
+	public int getId() {
+		return this.id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+
+	public char getIsStandard() {
+		return this.isStandard;
+	}
+
+	public void setIsStandard(char isStandard) {
+		this.isStandard = isStandard;
+	}
+
+	public String getXacmlId() {
+		return this.xacmlId;
+	}
+
+	public void setXacmlId(String xacmlId) {
+		this.xacmlId = xacmlId;
+	}
+
+	public String getShortName() {
+		return shortName;
+	}
+
+	public void setShortName(String shortName) {
+		this.shortName = shortName;
+	}	
+
+	public Set<Attribute> getAttributes() {
+		return this.attributes;
+	}
+
+	public void setAttributes(Set<Attribute> attributes) {
+		this.attributes = attributes;
+	}
+
+	public Attribute addAttribute(Attribute attribute) {
+		getAttributes().add(attribute);
+		attribute.setDatatypeBean(this);
+
+		return attribute;
+	}
+
+	public Attribute removeAttribute(Attribute attribute) {
+		getAttributes().remove(attribute);
+		attribute.setDatatypeBean(null);
+
+		return attribute;
+	}
+
+	public Set<FunctionDefinition> getFunctions() {
+		return this.functions;
+	}
+
+	public void setFunctions(Set<FunctionDefinition> functions) {
+		this.functions = functions;
+	}
+
+	public FunctionDefinition addFunction(FunctionDefinition function) {
+		getFunctions().add(function);
+		function.setDatatypeBean(this);
+
+		return function;
+	}
+
+	public FunctionDefinition removeAttribute(FunctionDefinition function) {
+		getFunctions().remove(function);
+		function.setDatatypeBean(null);
+
+		return function;
+	}
+
+	public Set<FunctionArgument> getArguments() {
+		return this.arguments;
+	}
+
+	public void setArguments(Set<FunctionArgument> argument) {
+		this.arguments = argument;
+	}
+
+	public FunctionArgument addArgument(FunctionArgument argument) {
+		getArguments().add(argument);
+		argument.setDatatypeBean(this);
+
+		return argument;
+	}
+
+	public FunctionArgument removeArgument(FunctionArgument argument) {
+		getArguments().remove(argument);
+		argument.setDatatypeBean(null);
+
+		return argument;
+	}
+
+	@Transient
+	public Identifier getIdentifer() {
+		return new IdentifierImpl(this.xacmlId);
+	}
+
+	@Transient
+	public boolean isStandard() {
+		return this.isStandard == Datatype.STANDARD;
+	}
+	
+	@Transient
+	public boolean isCustom() {
+		return this.isStandard == Datatype.CUSTOM;
+	}
+	
+	@Transient
+	@Override
+	public String toString() {
+		return "Datatype [id=" + id + ", isStandard=" + isStandard
+				+ ", xacmlId=" + xacmlId + ", shortName=" + shortName
+				+ ", attributes=" + attributes + ", functions=" + functions
+				+ ", arguments=" + arguments + "]";
+	}
+
+}
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/FunctionArgument.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/FunctionArgument.java
new file mode 100644
index 0000000..109e26d
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/FunctionArgument.java
@@ -0,0 +1,122 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ *
+ */
+
+package org.apache.openaz.xacml.admin.jpa;
+
+import java.io.Serializable;
+
+import javax.persistence.*;
+
+
+/**
+ * The persistent class for the FunctionArguments database table.
+ * 
+ */
+@Entity
+@Table(name="FunctionArguments")
+@NamedQuery(name="FunctionArgument.findAll", query="SELECT f FROM FunctionArgument f")
+public class FunctionArgument implements Serializable {
+	private static final long serialVersionUID = 1L;
+
+	@Id
+	@GeneratedValue(strategy=GenerationType.AUTO)
+	@Column(name="id")
+	private int id;
+
+	@Column(name="is_bag", nullable=false)
+	private int isBag;
+
+	//bi-directional many-to-one association to FunctionDefinition
+	@ManyToOne
+	@JoinColumn(name="function_id")
+	private FunctionDefinition functionDefinition;
+
+	@Column(name="arg_index", nullable=false)
+	private int argIndex;
+
+	//bi-directional many-to-one association to Datatype
+	@ManyToOne
+	@JoinColumn(name="datatype_id")
+	private Datatype datatypeBean;
+
+	public FunctionArgument() {
+	}
+
+	public FunctionArgument(final FunctionArgument argument) {
+		this.argIndex = argument.argIndex;
+		this.datatypeBean = argument.datatypeBean;
+		this.isBag = argument.isBag;
+		this.functionDefinition = argument.functionDefinition;
+	}
+
+	public int getId() {
+		return this.id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+
+	public int getArgIndex() {
+		return this.argIndex;
+	}
+
+	public void setArgIndex(int argIndex) {
+		this.argIndex = argIndex;
+	}
+
+	public Datatype getDatatypeBean() {
+		return this.datatypeBean;
+	}
+
+	public void setDatatypeBean(Datatype datatypeBean) {
+		this.datatypeBean = datatypeBean;
+	}
+
+	public FunctionDefinition getFunctionDefinition() {
+		return this.functionDefinition;
+	}
+
+	public int getIsBag() {
+		return isBag;
+	}
+
+	public void setIsBag(int isBag) {
+		this.isBag = isBag;
+	}
+
+	public void setFunctionDefinition(FunctionDefinition functionDefinition) {
+		this.functionDefinition = functionDefinition;
+	}
+
+	@Transient
+	@Override
+	public String toString() {
+		return "FunctionArgument [id=" + id + ", argIndex=" + argIndex
+				+ ", datatypeBean=" + datatypeBean + ", isBag=" + isBag
+				+ ", functionDefinition=" + functionDefinition + "]";
+	}
+	
+	@Transient
+	public boolean isBag() {
+		return this.isBag == 1;
+	}
+
+}
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/FunctionDefinition.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/FunctionDefinition.java
new file mode 100644
index 0000000..fc0cc91
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/FunctionDefinition.java
@@ -0,0 +1,217 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ *
+ */
+
+package org.apache.openaz.xacml.admin.jpa;
+
+import java.io.Serializable;
+
+import javax.persistence.*;
+
+import java.util.List;
+
+
+/**
+ * The persistent class for the FunctionDefinition database table.
+ * 
+ */
+@Entity
+@Table(name="FunctionDefinition")
+@NamedQuery(name="FunctionDefinition.findAll", query="SELECT f FROM FunctionDefinition f")
+public class FunctionDefinition implements Serializable {
+	private static final long serialVersionUID = 1L;
+
+	@Id
+	@GeneratedValue(strategy=GenerationType.AUTO)
+	@Column(name="id")
+	private int id;
+
+	@Column(name="short_name", nullable=false, length=64)
+	private String shortname;
+
+	@Column(name="xacml_id", nullable=false, length=255)
+	private String xacmlid;
+	
+	//bi-directional many-to-one association to Datatype
+	@ManyToOne
+	@JoinColumn(name="return_datatype", nullable=true)
+	private Datatype datatypeBean;
+
+	@Column(name="is_bag_return", nullable=false)
+	private int isBagReturn;
+	
+	@Column(name="is_higher_order", nullable=false)
+	private int isHigherOrder;
+
+	@Column(name="arg_lb", nullable=false)
+	private int argLb;
+
+	@Column(name="arg_ub", nullable=false)
+	private int argUb;
+
+	@Column(name="ho_arg_lb", nullable=true)
+	private int higherOrderArg_LB;
+	
+	@Column(name="ho_arg_ub", nullable=true)
+	private int higherOrderArg_UB;
+	
+	@Column(name="ho_primitive", nullable=true)
+	private char higherOrderIsPrimitive;
+
+	//bi-directional many-to-one association to FunctionArgument
+	@OneToMany(mappedBy="functionDefinition")
+	private List<FunctionArgument> functionArguments;
+
+	public FunctionDefinition() {
+	}
+
+	public int getId() {
+		return this.id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+
+	public int getArgLb() {
+		return this.argLb;
+	}
+
+	public void setArgLb(int argLb) {
+		this.argLb = argLb;
+	}
+
+	public int getArgUb() {
+		return this.argUb;
+	}
+
+	public void setArgUb(int argUb) {
+		this.argUb = argUb;
+	}
+
+	public int getIsBagReturn() {
+		return isBagReturn;
+	}
+
+	public void setIsBagReturn(int isBagReturn) {
+		this.isBagReturn = isBagReturn;
+	}
+
+	public int getIsHigherOrder() {
+		return isHigherOrder;
+	}
+
+	public void setIsHigherOrder(int isHigherOrder) {
+		this.isHigherOrder = isHigherOrder;
+	}
+
+	public Datatype getDatatypeBean() {
+		return this.datatypeBean;
+	}
+
+	public void setDatatypeBean(Datatype datatypeBean) {
+		this.datatypeBean = datatypeBean;
+	}
+
+	public String getShortname() {
+		return this.shortname;
+	}
+
+	public void setShortname(String shortname) {
+		this.shortname = shortname;
+	}
+
+	public String getXacmlid() {
+		return this.xacmlid;
+	}
+
+	public void setXacmlid(String xacmlid) {
+		this.xacmlid = xacmlid;
+	}
+
+	public int getHigherOrderArg_LB() {
+		return higherOrderArg_LB;
+	}
+
+	public void setHigherOrderArg_LB(int higherOrderArg_LB) {
+		this.higherOrderArg_LB = higherOrderArg_LB;
+	}
+
+	public int getHigherOrderArg_UB() {
+		return higherOrderArg_UB;
+	}
+
+	public void setHigherOrderArg_UB(int higherOrderArg_UB) {
+		this.higherOrderArg_UB = higherOrderArg_UB;
+	}
+
+	public char getHigherOrderIsPrimitive() {
+		return higherOrderIsPrimitive;
+	}
+
+	public void setHigherOrderIsPrimitive(char higherOrderIsPrimitive) {
+		this.higherOrderIsPrimitive = higherOrderIsPrimitive;
+	}
+
+	public List<FunctionArgument> getFunctionArguments() {
+		return this.functionArguments;
+	}
+
+	public void setFunctionArguments(List<FunctionArgument> functionArguments) {
+		this.functionArguments = functionArguments;
+	}
+
+	public FunctionArgument addFunctionArgument(FunctionArgument functionArgument) {
+		getFunctionArguments().add(functionArgument);
+		functionArgument.setFunctionDefinition(this);
+
+		return functionArgument;
+	}
+
+	public FunctionArgument removeFunctionArgument(FunctionArgument functionArgument) {
+		getFunctionArguments().remove(functionArgument);
+		functionArgument.setFunctionDefinition(null);
+
+		return functionArgument;
+	}
+
+	@Transient
+	@Override
+	public String toString() {
+		return "FunctionDefinition [id=" + id + ", argLb=" + argLb + ", argUb="
+				+ argUb + ", isBagReturn=" + isBagReturn + ", isHigherOrder="
+				+ isHigherOrder + ", datatypeBean=" + datatypeBean
+				+ ", shortname=" + shortname + ", xacmlid=" + xacmlid
+				+ ", higherOrderArg_LB=" + higherOrderArg_LB
+				+ ", higherOrderArg_UB=" + higherOrderArg_UB
+				+ ", higherOrderIsPrimitive=" + higherOrderIsPrimitive
+				+ ", functionArguments=" + functionArguments + "]";
+	}
+
+	@Transient
+	public boolean isBagReturn() {
+		return this.isBagReturn == 1;
+	}
+
+	@Transient
+	public boolean isHigherOrder() {
+		return this.isHigherOrder == 1;
+	}
+
+}
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/Obadvice.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/Obadvice.java
new file mode 100644
index 0000000..cda5802
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/Obadvice.java
@@ -0,0 +1,227 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ *
+ */
+
+package org.apache.openaz.xacml.admin.jpa;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.NamedQuery;
+import javax.persistence.OneToMany;
+import javax.persistence.PrePersist;
+import javax.persistence.PreUpdate;
+import javax.persistence.Table;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+import javax.persistence.Transient;
+
+import org.apache.openaz.xacml.api.Identifier;
+
+/**
+ * The persistent class for the Obadvice database table.
+ * 
+ */
+@Entity
+@Table(name="Obadvice")
+@NamedQuery(name="Obadvice.findAll", query="SELECT o FROM Obadvice o")
+public class Obadvice implements Serializable {
+	private static final long serialVersionUID = 1L;
+
+	public static final String OBLIGATION = "Obligation";
+	public static final String ADVICE = "Advice";
+	public static final String EFFECT_PERMIT = "Permit";
+	public static final String EFFECT_DENY = "Deny";
+	@Id
+	@GeneratedValue(strategy = GenerationType.AUTO)
+	@Column(name="id")
+	private int id;
+
+	@Column(name="type", nullable=false)
+	private String type;
+
+	@Column(name="xacml_id", nullable=false, length=255)
+	private String xacmlId;
+
+	@Column(name="fulfill_on", nullable=true, length=32)
+	private String fulfillOn;
+
+	@Column(name="description", nullable=true, length=2048)
+	private String description;
+
+	//bi-directional one-to-many association to Attribute Assignment
+	@OneToMany(mappedBy="obadvice", orphanRemoval=true, cascade=CascadeType.REMOVE)
+	private Set<ObadviceExpression> obadviceExpressions = new HashSet<ObadviceExpression>(2);
+
+	@Column(name="created_by", nullable=false, length=255)
+	private String createdBy;
+
+	@Temporal(TemporalType.TIMESTAMP)
+	@Column(name="created_date", nullable=false, updatable=false)
+	private Date createdDate; //NOPMD
+
+	@Column(name="modified_by", nullable=false, length=255)
+	private String modifiedBy;
+
+	@Temporal(TemporalType.TIMESTAMP)
+	@Column(name="modified_date", nullable=false)
+	private Date modifiedDate; //NOPMD
+
+	public Obadvice() {
+		this.type = Obadvice.OBLIGATION;
+		this.fulfillOn = Obadvice.EFFECT_PERMIT;
+	}
+	
+	public Obadvice(String domain, String userid) {
+		this.xacmlId = domain;
+		this.type = Obadvice.OBLIGATION;
+		this.fulfillOn = Obadvice.EFFECT_PERMIT;
+		this.createdBy = userid;
+		this.modifiedBy = userid;
+	}
+
+	public Obadvice(Identifier id, String userid) {
+		this(id.stringValue(), userid);
+	}
+
+	@PrePersist
+	public void	prePersist() {
+		Date date = new Date();
+		this.createdDate = date;
+		this.modifiedDate = date;
+	}
+	
+	@PreUpdate
+	public void preUpdate() {
+		this.modifiedDate = new Date();
+	}
+
+	public int getId() {
+		return this.id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+
+	public String getCreatedBy() {
+		return this.createdBy;
+	}
+
+	public void setCreatedBy(String createdBy) {
+		this.createdBy = createdBy;
+	}
+
+	public String getDescription() {
+		return this.description;
+	}
+
+	public void setDescription(String description) {
+		this.description = description;
+	}
+
+	public String getFulfillOn() {
+		return this.fulfillOn;
+	}
+
+	public void setFulfillOn(String fulfillOn) {
+		this.fulfillOn = fulfillOn;
+	}
+
+	public String getModifiedBy() {
+		return this.modifiedBy;
+	}
+
+	public void setModifiedBy(String modifiedBy) {
+		this.modifiedBy = modifiedBy;
+	}
+
+	public String getType() {
+		return this.type;
+	}
+
+	public void setType(String type) {
+		this.type = type;
+	}
+
+	public String getXacmlId() {
+		return this.xacmlId;
+	}
+
+	public void setXacmlId(String xacmlId) {
+		this.xacmlId = xacmlId;
+	}
+
+	public Set<ObadviceExpression> getObadviceExpressions() {
+		return this.obadviceExpressions;
+	}
+
+	public void setObadviceExpressions(Set<ObadviceExpression> obadviceExpressions) {
+		this.obadviceExpressions = obadviceExpressions;
+	}
+
+	public ObadviceExpression addObadviceExpression(ObadviceExpression obadviceExpression) {
+		this.obadviceExpressions.add(obadviceExpression);
+		obadviceExpression.setObadvice(this);
+
+		return obadviceExpression;
+	}
+
+	public ObadviceExpression removeObadviceExpression(ObadviceExpression obadviceExpression) {
+		this.obadviceExpressions.remove(obadviceExpression);
+		obadviceExpression.setObadvice(null);
+
+		return obadviceExpression;
+	}
+	
+	public void removeAllExpressions() {
+		if (this.obadviceExpressions == null) {
+			return;
+		}
+		for (ObadviceExpression expression : this.obadviceExpressions) {
+			expression.setObadvice(null);
+		}
+		this.obadviceExpressions.clear();
+	}
+
+	@Transient
+	public Obadvice clone() {
+		Obadvice obadvice = new Obadvice();
+		
+		obadvice.type = this.type;
+		obadvice.xacmlId = this.xacmlId;
+		obadvice.fulfillOn = this.fulfillOn;
+		obadvice.description = this.description;
+		obadvice.createdBy = this.createdBy;
+		obadvice.modifiedBy = this.modifiedBy;
+		for (ObadviceExpression exp: this.obadviceExpressions) {
+			obadvice.addObadviceExpression(exp.clone());
+		}
+
+		return obadvice;
+	}
+}
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/ObadviceExpression.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/ObadviceExpression.java
new file mode 100644
index 0000000..2a79639
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/ObadviceExpression.java
@@ -0,0 +1,124 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ *
+ */
+
+package org.apache.openaz.xacml.admin.jpa;
+
+import java.io.Serializable;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+// import javax.persistence.Lob;
+import javax.persistence.ManyToOne;
+import javax.persistence.NamedQuery;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+
+
+/**
+ * The persistent class for the ObadviceExpressions database table.
+ * 
+ */
+@Entity
+@Table(name="ObadviceExpressions")
+@NamedQuery(name="ObadviceExpression.findAll", query="SELECT o FROM ObadviceExpression o")
+public class ObadviceExpression implements Serializable {
+	private static final long serialVersionUID = 1L;
+
+	public static final String EXPRESSION_APPLY = "Apply";
+	public static final String EXPRESSION_SELECTOR = "Attribute Selector";
+	public static final String EXPRESSION_VALUE = "Attribute Value";
+	public static final String EXPRESSION_FUNCTION = "Function";
+	public static final String EXPRESSION_REFERENCE = "Varable Reference";
+	public static final String EXPRESSION_DESIGNATOR = "Attribute Designator";
+
+	@Id
+	@GeneratedValue(strategy = GenerationType.AUTO)
+	@Column(name="id")
+	private int id;
+
+	//unidirectional one-to-one association to Attribute
+	@OneToOne
+	@JoinColumn(name="attribute_id")
+	private Attribute attribute;
+
+	@Column(name="type", nullable=false)
+	private String type;
+	
+	/*
+	@Lob
+	@Column(name="expression", nullable=false)
+	private byte[] expression;
+	*/
+
+	//bi-directional many-to-one association to Obadvice
+	@ManyToOne
+	@JoinColumn(name="obadvice_id")
+	private Obadvice obadvice;
+
+	public ObadviceExpression() {
+		type = EXPRESSION_VALUE;
+	}
+
+	public int getId() {
+		return this.id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+
+	public Attribute getAttribute() {
+		return this.attribute;
+	}
+
+	public void setAttribute(Attribute attribute) {
+		this.attribute = attribute;
+	}
+
+	public String getType() {
+		return this.type;
+	}
+
+	public void setType(String type) {
+		this.type = type;
+	}
+
+	public Obadvice getObadvice() {
+		return this.obadvice;
+	}
+
+	public void setObadvice(Obadvice obadvice) {
+		this.obadvice = obadvice;
+	}
+
+	public ObadviceExpression clone() {
+		ObadviceExpression expression = new ObadviceExpression();
+		
+		expression.attribute = this.attribute;
+		expression.type = this.type;
+		expression.obadvice = this.obadvice;
+		
+		return expression;
+	}
+}
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/PIPConfigParam.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/PIPConfigParam.java
new file mode 100644
index 0000000..a4c4a16
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/PIPConfigParam.java
@@ -0,0 +1,147 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ *
+ */
+
+package org.apache.openaz.xacml.admin.jpa;
+
+import java.io.Serializable;
+
+import javax.persistence.*;
+
+
+/**
+ * The persistent class for the PIPConfigParams database table.
+ * 
+ */
+@Entity
+@Table(name="PIPConfigParams")
+@NamedQuery(name="PIPConfigParam.findAll", query="SELECT p FROM PIPConfigParam p")
+public class PIPConfigParam implements Serializable {
+	private static final long serialVersionUID = 1L;
+
+	@Id
+	@GeneratedValue(strategy=GenerationType.AUTO)
+	@Column(name="id")
+	private int id;
+
+	@Column(name="PARAM_NAME", nullable=false, length=1024)
+	private String paramName;
+
+	@Column(name="PARAM_VALUE", nullable=false, length=2048)
+	private String paramValue;
+
+	@Column(name="PARAM_DEFAULT", nullable=true, length=2048)
+	private String paramDefault = null;
+	
+	@Column(name="REQUIRED", nullable=false)
+	private char required = '0';
+
+	//bi-directional many-to-one association to PIPConfiguration
+	@ManyToOne
+	@JoinColumn(name="PIP_ID")
+	private PIPConfiguration pipconfiguration;
+
+	public PIPConfigParam() {
+	}
+
+	public PIPConfigParam(String param) {
+		this.paramName = param;
+	}
+
+	public PIPConfigParam(String param, String value) {
+		this(param);
+		this.paramValue = value;
+	}
+
+	public PIPConfigParam(PIPConfigParam param) {
+		this(param.getParamName(), param.getParamValue());
+		this.paramDefault = param.getParamDefault();
+		this.required = param.required;
+	}
+
+	public int getId() {
+		return this.id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+
+	public String getParamName() {
+		return this.paramName;
+	}
+
+	public void setParamName(String paramName) {
+		this.paramName = paramName;
+	}
+
+	public String getParamValue() {
+		return this.paramValue;
+	}
+
+	public void setParamValue(String paramValue) {
+		this.paramValue = paramValue;
+	}
+
+	public String getParamDefault() {
+		return paramDefault;
+	}
+
+	public void setParamDefault(String paramDefault) {
+		this.paramDefault = paramDefault;
+	}
+
+	public char getRequired() {
+		return required;
+	}
+
+	public void setRequired(char required) {
+		this.required = required;
+	}
+
+	public PIPConfiguration getPipconfiguration() {
+		return this.pipconfiguration;
+	}
+
+	public void setPipconfiguration(PIPConfiguration pipconfiguration) {
+		this.pipconfiguration = pipconfiguration;
+	}
+
+	@Transient
+	public boolean isRequired() {
+		return this.required == '1';
+	}
+	
+	@Transient
+	public void setRequired(boolean required) {
+		if (required) {
+			this.setRequired('1');
+		} else {
+			this.setRequired('0');
+		}
+	}
+
+	@Transient
+	@Override
+	public String toString() {
+		return "PIPConfigParam [id=" + id + ", paramName=" + paramName
+				+ ", paramValue=" + paramValue + ", required=" + required + "]";
+	}
+
+}
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/PIPConfiguration.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/PIPConfiguration.java
new file mode 100644
index 0000000..d540e2b
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/PIPConfiguration.java
@@ -0,0 +1,554 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ *
+ */
+
+package org.apache.openaz.xacml.admin.jpa;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.NamedQuery;
+import javax.persistence.OneToMany;
+import javax.persistence.PrePersist;
+import javax.persistence.PreUpdate;
+import javax.persistence.Table;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+import javax.persistence.Transient;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.openaz.xacml.admin.XacmlAdminUI;
+import org.apache.openaz.xacml.admin.util.JPAUtils;
+import org.apache.openaz.xacml.api.pip.PIPException;
+import org.apache.openaz.xacml.std.pip.engines.StdConfigurableEngine;
+import org.apache.openaz.xacml.std.pip.engines.csv.CSVEngine;
+import org.apache.openaz.xacml.std.pip.engines.csv.HyperCSVEngine;
+import org.apache.openaz.xacml.std.pip.engines.jdbc.JDBCEngine;
+import org.apache.openaz.xacml.std.pip.engines.ldap.LDAPEngine;
+import org.apache.openaz.xacml.util.XACMLProperties;
+import com.google.common.base.Joiner;
+import com.google.common.base.Splitter;
+import com.vaadin.ui.UI;
+
+
+/**
+ * The persistent class for the PIPConfiguration database table.
+ * 
+ */
+@Entity
+@Table(name="PIPConfiguration")
+@NamedQuery(name="PIPConfiguration.findAll", query="SELECT p FROM PIPConfiguration p")
+public class PIPConfiguration implements Serializable {
+	private static final long serialVersionUID = 1L;
+	private static final Log logger	= LogFactory.getLog(PIPConfiguration.class);
+
+	@Id
+	@GeneratedValue(strategy=GenerationType.AUTO)
+	@Column(name="id")
+	private int id;
+
+	@Column(name="DESCRIPTION", nullable=true, length=2048)
+	private String description;
+
+	@Column(name="NAME", nullable=false, length=255)
+	private String name;
+
+	@Column(name="CLASSNAME", nullable=false, length=2048)
+	private String classname;
+
+	@Column(name="ISSUER", nullable=true, length=1024)
+	private String issuer;
+
+	@Column(name="READ_ONLY", nullable=false)
+	private char readOnly = '0';
+
+	@Column(name="REQUIRES_RESOLVER", nullable=false)
+	private char requiresResolvers;
+
+	@Column(name="CREATED_BY", nullable=false, length=255)
+	private String createdBy = "guest";
+
+	@Temporal(TemporalType.TIMESTAMP)
+	@Column(name="CREATED_DATE", nullable=false, updatable=false)
+	private Date createdDate;
+
+	@Column(name="MODIFIED_BY", nullable=false, length=255)
+	private String modifiedBy = "guest";
+
+	@Temporal(TemporalType.TIMESTAMP)
+	@Column(name="MODIFIED_DATE", nullable=false)
+	private Date modifiedDate;
+
+	//bi-directional many-to-one association to PIPConfigParam
+	@OneToMany(mappedBy="pipconfiguration", orphanRemoval=true, cascade=CascadeType.REMOVE)
+	private Set<PIPConfigParam> pipconfigParams = new HashSet<PIPConfigParam>();
+
+	//bi-directional many-to-one association to PIPType
+	@ManyToOne
+	@JoinColumn(name="TYPE")
+	private PIPType piptype;
+
+	//bi-directional many-to-one association to PIPResolver
+	@OneToMany(mappedBy="pipconfiguration", orphanRemoval=true, cascade=CascadeType.REMOVE)
+	private Set<PIPResolver> pipresolvers = new HashSet<PIPResolver>();
+
+	public PIPConfiguration() {
+	}
+	
+	public PIPConfiguration(PIPConfiguration config, String user) { //NOPMD
+		this.description = config.description;
+		this.name = config.name;
+		this.classname = config.classname;
+		this.issuer = config.issuer;
+		this.requiresResolvers = config.requiresResolvers;
+		this.readOnly = config.readOnly;
+		this.piptype = config.piptype;
+		for (PIPConfigParam param : config.pipconfigParams) {
+			this.addPipconfigParam(new PIPConfigParam(param));
+		}
+		for (PIPResolver resolver : config.pipresolvers) {
+			this.addPipresolver(new PIPResolver(resolver));
+		}
+	}
+	
+	public PIPConfiguration(String id, Properties properties) throws PIPException {
+		this.readProperties(id, properties);
+	}
+	
+	public PIPConfiguration(String id, Properties properties, String user) throws PIPException {
+		this.createdBy = user;
+		this.modifiedBy = user;
+		this.readProperties(id, properties);
+	}
+
+	@PrePersist
+	public void	prePersist() {
+		Date date = new Date();
+		this.createdDate = date;
+		this.modifiedDate = date;
+	}
+	
+	@PreUpdate
+	public void preUpdate() {
+		this.modifiedDate = new Date();
+	}
+
+	public int getId() {
+		return this.id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+
+	public String getDescription() {
+		return this.description;
+	}
+
+	public void setDescription(String description) {
+		this.description = description;
+	}
+
+	public String getName() {
+		return this.name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public String getClassname() {
+		return classname;
+	}
+
+	public void setClassname(String classname) {
+		this.classname = classname;
+	}
+
+	public String getIssuer() {
+		return issuer;
+	}
+
+	public void setIssuer(String issuer) {
+		this.issuer = issuer;
+	}
+
+	public char getReadOnly() {
+		return readOnly;
+	}
+
+	public void setReadOnly(char readOnly) {
+		this.readOnly = readOnly;
+	}
+
+	public char getRequiresResolvers() {
+		return requiresResolvers;
+	}
+
+	public void setRequiresResolvers(char requireResolvers) {
+		this.requiresResolvers = requireResolvers;
+	}
+
+	public Set<PIPConfigParam> getPipconfigParams() {
+		return this.pipconfigParams;
+	}
+
+	public void setPipconfigParams(Set<PIPConfigParam> pipconfigParams) {
+		this.pipconfigParams = pipconfigParams;
+	}
+
+	public PIPConfigParam addPipconfigParam(PIPConfigParam pipconfigParam) {
+		getPipconfigParams().add(pipconfigParam);
+		pipconfigParam.setPipconfiguration(this);
+
+		return pipconfigParam;
+	}
+
+	public PIPConfigParam removePipconfigParam(PIPConfigParam pipconfigParam) {
+		if (pipconfigParam == null) {
+			return pipconfigParam;
+		}
+		getPipconfigParams().remove(pipconfigParam);
+		pipconfigParam.setPipconfiguration(null);
+
+		return pipconfigParam;
+	}
+	
+	@Transient
+	public void clearConfigParams() {
+		while (this.pipconfigParams.isEmpty() == false) {
+			this.removePipconfigParam(this.pipconfigParams.iterator().next());
+		}
+	}
+
+	public PIPType getPiptype() {
+		return this.piptype;
+	}
+
+	public void setPiptype(PIPType piptype) {
+		this.piptype = piptype;
+	}
+
+	public Set<PIPResolver> getPipresolvers() {
+		return this.pipresolvers;
+	}
+
+	public void setPipresolvers(Set<PIPResolver> pipresolvers) {
+		this.pipresolvers = pipresolvers;
+	}
+
+	public PIPResolver addPipresolver(PIPResolver pipresolver) {
+		getPipresolvers().add(pipresolver);
+		pipresolver.setPipconfiguration(this);
+
+		return pipresolver;
+	}
+
+	public PIPResolver removePipresolver(PIPResolver pipresolver) {
+		getPipresolvers().remove(pipresolver);
+		pipresolver.setPipconfiguration(null);
+
+		return pipresolver;
+	}
+
+	public String getCreatedBy() {
+		return createdBy;
+	}
+
+	public void setCreatedBy(String createdBy) {
+		this.createdBy = createdBy;
+	}
+
+	public Date getCreatedDate() {
+		return createdDate;
+	}
+
+	public void setCreatedDate(Date createdDate) {
+		this.createdDate = createdDate;
+	}
+
+	public String getModifiedBy() {
+		return modifiedBy;
+	}
+
+	public void setModifiedBy(String modifiedBy) {
+		this.modifiedBy = modifiedBy;
+	}
+
+	public Date getModifiedDate() {
+		return modifiedDate;
+	}
+
+	public void setModifiedDate(Date modifiedDate) {
+		this.modifiedDate = modifiedDate;
+	}
+
+	@Transient
+	public boolean isReadOnly() {
+		return this.readOnly == '1';
+	}
+	
+	@Transient
+	public void setReadOnly(boolean readOnly) {
+		if (readOnly) {
+			this.readOnly = '1';
+		} else {
+			this.readOnly = '0';
+		}
+	}
+	
+	@Transient
+	public boolean requiresResolvers() {
+		return this.requiresResolvers == '1';
+	}
+	
+	@Transient
+	public void	setRequiresResolvers(boolean requires) {
+		if (requires) {
+			this.requiresResolvers = '1';
+		} else {
+			this.requiresResolvers = '0';
+		}
+	}
+	
+	@Transient
+	public static Collection<PIPConfiguration>		importPIPConfigurations(Properties properties) {
+		Collection<PIPConfiguration> configurations = new ArrayList<PIPConfiguration>();
+		String engines = properties.getProperty(XACMLProperties.PROP_PIP_ENGINES);
+		if (engines == null || engines.isEmpty()) {
+			return configurations;
+		}
+		for (String id : Splitter.on(',').trimResults().omitEmptyStrings().split(engines)) {
+			PIPConfiguration configuration;
+			try {
+				String user = ((XacmlAdminUI)UI.getCurrent()).getUserid();
+				configuration = new PIPConfiguration(id, properties, user);
+				configuration.setCreatedBy(user);
+				configuration.setModifiedBy(user);
+				configurations.add(configuration);
+			} catch (PIPException e) {
+				logger.error("Import failed: " + e.getLocalizedMessage());
+			}
+		}
+		
+		return configurations;
+	}
+	
+	@Transient
+	protected	void		readProperties(String id, Properties properties) throws PIPException {
+		//
+		// Save the id if we don't have one already
+		//
+		if (this.id == 0) {
+			try {
+				this.id = Integer.parseInt(id);
+			} catch (NumberFormatException e) {
+				logger.error("Convert id to integer failed: " + id);
+			}
+		}
+		//
+		// Get its classname, this MUST exist.
+		//
+		this.classname = properties.getProperty(id + ".classname");
+		if (this.classname == null) {
+			throw new PIPException("PIP Engine defined without a classname");
+		}
+		//
+		// These classes we know for sure require resolvers.
+		//
+		if (this.classname.equals(JDBCEngine.class.getCanonicalName())) {
+			this.setRequiresResolvers(true);
+			this.setPiptype(JPAUtils.getPIPType(PIPType.TYPE_SQL));
+		} else if (this.classname.equals(LDAPEngine.class.getCanonicalName())) {
+			this.setRequiresResolvers(true);
+			this.setPiptype(JPAUtils.getPIPType(PIPType.TYPE_LDAP));
+		} else if (this.classname.equals(HyperCSVEngine.class.getCanonicalName())) {
+			this.setRequiresResolvers(true);
+			this.setPiptype(JPAUtils.getPIPType(PIPType.TYPE_HYPERCSV));
+		} else if (this.classname.equals(CSVEngine.class.getCanonicalName())) {
+			this.setRequiresResolvers(true);
+			this.setPiptype(JPAUtils.getPIPType(PIPType.TYPE_CSV));
+		} else {
+			//
+			// Assume it does not require resolvers for now, if we encounter
+			// one then we will change it. The user can always change it via the gui.
+			// 
+			this.setRequiresResolvers(false);
+			this.setPiptype(JPAUtils.getPIPType(PIPType.TYPE_CUSTOM));
+		}
+		//
+		// Go through each property
+		//
+		for (Object name : properties.keySet()) {
+			if (name.toString().startsWith(id) == false || name.equals(id + ".classname")) {
+				continue;
+			}
+			if (name.equals(id + "." + StdConfigurableEngine.PROP_NAME)) {
+				this.name = properties.getProperty(name.toString());
+			} else if (name.equals(id + "." + StdConfigurableEngine.PROP_DESCRIPTION)) {
+				this.description = properties.getProperty(name.toString());
+			} else if (name.equals(id + "." + StdConfigurableEngine.PROP_ISSUER)) {
+				this.issuer = properties.getProperty(name.toString());
+			} else if (name.equals(id + ".resolvers")) {
+				//
+				// It has resolvers, make sure this is set to true if
+				// it has been already.
+				//
+				this.setRequiresResolvers(true);
+				//
+				// Parse the resolvers
+				//
+				Collection<PIPResolver> resolvers = PIPResolver.importResolvers(id + ".resolver",
+																		properties.getProperty(name.toString()),
+																		properties,
+																		((XacmlAdminUI)UI.getCurrent()).getUserid());
+				for (PIPResolver resolver : resolvers) {
+					this.addPipresolver(resolver);
+				}
+			// Ignore {id}.resolver: the PIPResolver will parse these values
+			} else if (! name.toString().startsWith(id + ".resolver")) {
+				//
+				// Config Parameter
+				//
+				this.addPipconfigParam(new PIPConfigParam(name.toString().substring(id.length() + 1), 
+													properties.getProperty(name.toString())));
+			}
+		}
+		//
+		// Make sure we have a name at least
+		//
+		if (this.name == null) {
+			this.name = id;
+		}
+	}
+	
+
+	@Transient
+	public Map<String, String> getConfiguration(String name) {
+		String prefix;
+		if (name == null) {
+			prefix = Integer.toString(this.id);
+		} else {
+			prefix = name;
+		}
+		if (prefix.endsWith(".") == false) {
+			prefix = prefix + ".";
+		}
+		Map<String, String> map = new HashMap<String, String>();
+		map.put(prefix + "classname", this.classname);
+		map.put(prefix + "name", this.name);
+		if (this.description != null) {
+			map.put(prefix + "description", this.description);
+		}
+		if (this.issuer != null) {
+			map.put(prefix + "issuer", this.issuer);
+		}
+		
+		for (PIPConfigParam param : this.pipconfigParams) {
+			map.put(prefix + param.getParamName(), param.getParamValue());
+		}
+		
+		List<String> ids = new ArrayList<String>();
+		Iterator<PIPResolver> iter = this.pipresolvers.iterator();
+		while (iter.hasNext()) {
+			PIPResolver resolver = iter.next();
+			String id = Integer.toString(resolver.getId());
+			Map<String, String> resolverMap = resolver.getConfiguration(prefix + "resolver." + id);
+			map.putAll(resolverMap);
+			ids.add(id);
+		}
+		if (ids.size() > 0) {
+			map.put(prefix + "resolvers", Joiner.on(',').join(ids));
+		}
+		return map;
+	}
+	
+	@Transient
+	public Properties	generateProperties(String name) {
+		String prefix;
+		if (name == null) {
+			prefix = Integer.toString(this.id);
+		} else {
+			if (name.endsWith(".")) {
+				prefix = name;
+			} else {
+				prefix = name + ".";
+			}
+		}
+		Properties props = new Properties();
+		props.setProperty("xacml.pip.engines", name);
+		props.setProperty(prefix + "classname", this.classname);
+		props.setProperty(prefix + "name", this.name);
+		if (this.description != null) {
+			props.setProperty(prefix + "description", this.description);
+		}
+		if (this.issuer != null && this.issuer.isEmpty() == false) {
+			props.setProperty(prefix + "issuer", this.issuer);
+		}
+		
+		for (PIPConfigParam param : this.pipconfigParams) {
+			props.setProperty(prefix + param.getParamName(), param.getParamValue());
+		}
+		
+		List<String> ids = new ArrayList<String>();
+		Iterator<PIPResolver> iter = this.pipresolvers.iterator();
+		while (iter.hasNext()) {
+			PIPResolver resolver = iter.next();
+			String id = Integer.toString(resolver.getId());
+			resolver.generateProperties(props, prefix + "resolver." + id);
+			ids.add(id);
+		}
+		if (ids.size() > 0) {
+			props.setProperty(prefix + "resolvers", Joiner.on(',').join(ids));
+		}
+		return props;
+	}
+
+	@Transient
+	@Override
+	public String toString() {
+		return "PIPConfiguration [id=" + id + ", piptype=" + piptype
+				+ ", classname=" + classname + ", name=" + name
+				+ ", description=" + description + ", issuer=" + issuer
+				+ ", readOnly=" + readOnly + ", requiresResolvers="
+				+ requiresResolvers + ", createdBy=" + createdBy
+				+ ", createdDate=" + createdDate + ", modifiedBy=" + modifiedBy
+				+ ", modifiedDate=" + modifiedDate + ", pipconfigParams="
+				+ pipconfigParams + ", pipresolvers=" + pipresolvers + "]";
+	}
+}
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/PIPResolver.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/PIPResolver.java
new file mode 100644
index 0000000..59c9307
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/PIPResolver.java
@@ -0,0 +1,362 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ *
+ */
+
+package org.apache.openaz.xacml.admin.jpa;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.NamedQuery;
+import javax.persistence.OneToMany;
+import javax.persistence.PrePersist;
+import javax.persistence.PreUpdate;
+import javax.persistence.Table;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+import javax.persistence.Transient;
+
+import org.apache.openaz.xacml.api.pip.PIPException;
+import org.apache.openaz.xacml.std.pip.engines.StdConfigurableEngine;
+import com.google.common.base.Splitter;
+
+
+/**
+ * The persistent class for the PIPResolver database table.
+ * 
+ */
+@Entity
+@Table(name="PIPResolver")
+@NamedQuery(name="PIPResolver.findAll", query="SELECT p FROM PIPResolver p")
+public class PIPResolver implements Serializable {
+	private static final long serialVersionUID = 1L;
+
+	@Id
+	@GeneratedValue(strategy=GenerationType.AUTO)
+	@Column(name="id")
+	private int id;
+
+	@Column(name="DESCRIPTION", nullable=true, length=2048)
+	private String description;
+
+	@Column(name="NAME", nullable=false, length=255)
+	private String name;
+
+	@Column(name="ISSUER", nullable=true, length=1024)
+	private String issuer;
+
+	@Column(name="CLASSNAME", nullable=false, length=2048)
+	private String classname;
+
+	@Column(name="READ_ONLY", nullable=false)
+	private char readOnly = '0';
+
+	@Column(name="CREATED_BY", nullable=false, length=255)
+	private String createdBy = "guest";
+
+	@Temporal(TemporalType.TIMESTAMP)
+	@Column(name="CREATED_DATE", nullable=false, updatable=false)
+	private Date createdDate;
+
+	@Column(name="MODIFIED_BY", nullable=false, length=255)
+	private String modifiedBy = "guest";
+
+	@Temporal(TemporalType.TIMESTAMP)
+	@Column(name="MODIFIED_DATE", nullable=false)
+	private Date modifiedDate;
+
+	//bi-directional many-to-one association to PIPConfiguration
+	@ManyToOne
+	@JoinColumn(name="PIP_ID")
+	private PIPConfiguration pipconfiguration;
+
+	//bi-directional many-to-one association to PIPResolverParam
+	@OneToMany(mappedBy="pipresolver", orphanRemoval=true, cascade=CascadeType.REMOVE)
+	private Set<PIPResolverParam> pipresolverParams = new HashSet<PIPResolverParam>();
+
+	public PIPResolver() {
+	}
+	
+	public PIPResolver(String prefix, Properties properties, String user) throws PIPException {
+		this.createdBy = user;
+		this.modifiedBy = user;
+		this.readOnly = '0';
+		this.readProperties(prefix, properties);
+	}
+	
+	public PIPResolver(PIPResolver resolver) {
+		this.name = resolver.name;
+		this.description = resolver.description;
+		this.issuer = resolver.issuer;
+		this.classname = resolver.classname;
+		this.readOnly = resolver.readOnly;
+		for (PIPResolverParam param : this.pipresolverParams) {
+			this.addPipresolverParam(new PIPResolverParam(param));
+		}
+	}
+
+	@PrePersist
+	public void	prePersist() {
+		Date date = new Date();
+		this.createdDate = date;
+		this.modifiedDate = date;
+	}
+	
+	@PreUpdate
+	public void preUpdate() {
+		this.modifiedDate = new Date();
+	}
+
+	public int getId() {
+		return this.id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+
+	public String getDescription() {
+		return this.description;
+	}
+
+	public void setDescription(String description) {
+		this.description = description;
+	}
+
+	public String getName() {
+		return this.name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public String getIssuer() {
+		return issuer;
+	}
+
+	public void setIssuer(String issuer) {
+		this.issuer = issuer;
+	}
+
+	public String getClassname() {
+		return classname;
+	}
+
+	public void setClassname(String classname) {
+		this.classname = classname;
+	}
+
+	public char getReadOnly() {
+		return readOnly;
+	}
+
+	public void setReadOnly(char readOnly) {
+		this.readOnly = readOnly;
+	}
+
+	public String getCreatedBy() {
+		return createdBy;
+	}
+
+	public void setCreatedBy(String createdBy) {
+		this.createdBy = createdBy;
+	}
+
+	public Date getCreatedDate() {
+		return createdDate;
+	}
+
+	public void setCreatedDate(Date createdDate) {
+		this.createdDate = createdDate;
+	}
+
+	public String getModifiedBy() {
+		return modifiedBy;
+	}
+
+	public void setModifiedBy(String modifiedBy) {
+		this.modifiedBy = modifiedBy;
+	}
+
+	public Date getModifiedDate() {
+		return modifiedDate;
+	}
+
+	public void setModifiedDate(Date modifiedDate) {
+		this.modifiedDate = modifiedDate;
+	}
+
+	public PIPConfiguration getPipconfiguration() {
+		return this.pipconfiguration;
+	}
+
+	public void setPipconfiguration(PIPConfiguration pipconfiguration) {
+		this.pipconfiguration = pipconfiguration;
+	}
+
+	public Set<PIPResolverParam> getPipresolverParams() {
+		return this.pipresolverParams;
+	}
+
+	public void setPipresolverParams(Set<PIPResolverParam> pipresolverParams) {
+		this.pipresolverParams = pipresolverParams;
+	}
+
+	public PIPResolverParam addPipresolverParam(PIPResolverParam pipresolverParam) {
+		getPipresolverParams().add(pipresolverParam);
+		pipresolverParam.setPipresolver(this);
+
+		return pipresolverParam;
+	}
+
+	public PIPResolverParam removePipresolverParam(PIPResolverParam pipresolverParam) {
+		if (pipresolverParam == null) {
+			return pipresolverParam;
+		}
+		getPipresolverParams().remove(pipresolverParam);
+		pipresolverParam.setPipresolver(null);
+
+		return pipresolverParam;
+	}
+	
+	@Transient
+	public void clearParams() {
+		while (this.pipresolverParams.isEmpty() == false) {
+			this.removePipresolverParam(this.pipresolverParams.iterator().next());
+		}
+	}
+
+	@Transient
+	public boolean isReadOnly() {
+		return this.readOnly == '1';
+	}
+	
+	@Transient
+	public void setReadOnly(boolean readOnly) {
+		if (readOnly) {
+			this.readOnly = '1';
+		} else {
+			this.readOnly = '0';
+		}
+	}
+	
+	@Transient
+	public static Collection<PIPResolver>	importResolvers(String prefix, String list, Properties properties, String user) throws PIPException {
+		Collection<PIPResolver> resolvers = new ArrayList<PIPResolver>();
+		for (String id : Splitter.on(',').trimResults().omitEmptyStrings().split(list)) {
+			resolvers.add(new PIPResolver(prefix + "." + id, properties, user));
+		}		
+		return resolvers;
+	}
+
+	@Transient
+	protected void readProperties(String prefix, Properties properties) throws PIPException {
+		//
+		// Get its classname, this MUST exist.
+		//
+		this.classname = properties.getProperty(prefix + ".classname");
+		if (this.classname == null) {
+			throw new PIPException("PIP Engine defined without a classname");
+		}
+		//
+		// Go through each property
+		//
+		for (Object name : properties.keySet()) {
+			if (name.toString().startsWith(prefix) == false || name.equals(prefix + ".classname")) {
+				continue;
+			}
+
+			if (name.equals(prefix + "." + StdConfigurableEngine.PROP_NAME)) {
+				this.name = properties.getProperty(name.toString());
+			} else if (name.equals(prefix + "." + StdConfigurableEngine.PROP_DESCRIPTION)) {
+				this.description = properties.getProperty(name.toString());
+			} else if (name.equals(prefix + "." + StdConfigurableEngine.PROP_ISSUER)) {
+				this.issuer = properties.getProperty(name.toString());
+			} else {
+				this.addPipresolverParam(new PIPResolverParam(name.toString().substring(prefix.length() + 1),
+															properties.getProperty(name.toString())));
+			}
+		}
+	}
+
+	@Transient
+	public Map<String, String> getConfiguration(String prefix) {
+		Map<String, String> map = new HashMap<String, String>();
+		if (prefix.endsWith(".") == false) {
+			prefix = prefix + ".";
+		}
+		map.put(prefix + "classname", this.classname);
+		map.put(prefix + "name", this.name);
+		if (this.description != null) {
+			map.put(prefix + "description", this.description);
+		}
+		if (this.issuer != null && this.issuer.isEmpty() != false) {
+			map.put(prefix + "issuer", this.issuer);
+		}
+		for (PIPResolverParam param : this.pipresolverParams) {
+			map.put(prefix + param.getParamName(), param.getParamValue());
+		}
+		return map;
+	}
+
+	@Transient
+	public void	generateProperties(Properties props, String prefix) {
+		if (prefix.endsWith(".") == false) {
+			prefix = prefix + ".";
+		}
+		props.setProperty(prefix + "classname", this.classname);
+		props.setProperty(prefix + "name", this.name);
+		if (this.description != null) {
+			props.setProperty(prefix + "description", this.description);
+		}
+		if (this.issuer != null && this.issuer.isEmpty() != false) {
+			props.setProperty(prefix + "issuer", this.issuer);
+		}
+		for (PIPResolverParam param : this.pipresolverParams) {
+			props.setProperty(prefix + param.getParamName(), param.getParamValue());
+		}
+	}
+
+	@Transient
+	@Override
+	public String toString() {
+		return "PIPResolver [id=" + id + ", classname=" + classname + ", name="
+				+ name + ", description=" + description + ", issuer=" + issuer
+				+ ", readOnly=" + readOnly + ", createdBy=" + createdBy
+				+ ", createdDate=" + createdDate + ", modifiedBy=" + modifiedBy
+				+ ", modifiedDate=" + modifiedDate + ", pipresolverParams="
+				+ pipresolverParams + "]";
+	}
+}
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/PIPResolverParam.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/PIPResolverParam.java
new file mode 100644
index 0000000..917ce5b
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/PIPResolverParam.java
@@ -0,0 +1,147 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ *
+ */
+
+package org.apache.openaz.xacml.admin.jpa;
+
+import java.io.Serializable;
+
+import javax.persistence.*;
+
+
+/**
+ * The persistent class for the PIPResolverParams database table.
+ * 
+ */
+@Entity
+@Table(name="PIPResolverParams")
+@NamedQuery(name="PIPResolverParam.findAll", query="SELECT p FROM PIPResolverParam p")
+public class PIPResolverParam implements Serializable {
+	private static final long serialVersionUID = 1L;
+
+	@Id
+	@GeneratedValue(strategy=GenerationType.AUTO)
+	@Column(name="id")
+	private int id;
+
+	@Column(name="PARAM_NAME", nullable=false, length=1024)
+	private String paramName;
+
+	@Column(name="PARAM_VALUE", nullable=false, length=2048)
+	private String paramValue;
+
+	@Column(name="PARAM_DEFAULT", nullable=true, length=2048)
+	private String paramDefault;
+		
+	@Column(name="REQUIRED", nullable=false)
+	private char required = '0';
+
+	//bi-directional many-to-one association to PIPResolver
+	@ManyToOne
+	@JoinColumn(name="ID_RESOLVER")
+	private PIPResolver pipresolver;
+
+	public PIPResolverParam() {
+	}
+
+	public PIPResolverParam(String name) {
+		this.paramName = name;
+	}
+
+	public PIPResolverParam(String name, String value) {
+		this(name);
+		this.paramValue = value;
+	}
+
+	public PIPResolverParam(PIPResolverParam param) {
+		this(param.getParamName(), param.getParamValue());
+		this.paramDefault = param.getParamDefault();
+		this.required = param.required;
+	}
+
+	public int getId() {
+		return this.id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+
+	public String getParamName() {
+		return this.paramName;
+	}
+
+	public void setParamName(String paramName) {
+		this.paramName = paramName;
+	}
+
+	public String getParamValue() {
+		return this.paramValue;
+	}
+
+	public void setParamValue(String paramValue) {
+		this.paramValue = paramValue;
+	}
+
+	public String getParamDefault() {
+		return paramDefault;
+	}
+
+	public void setParamDefault(String paramDefault) {
+		this.paramDefault = paramDefault;
+	}
+
+	public char getRequired() {
+		return required;
+	}
+
+	public void setRequired(char required) {
+		this.required = required;
+	}
+
+	public PIPResolver getPipresolver() {
+		return this.pipresolver;
+	}
+
+	public void setPipresolver(PIPResolver pipresolver) {
+		this.pipresolver = pipresolver;
+	}
+
+	@Transient
+	public boolean isRequired() {
+		return this.required == '1';
+	}
+	
+	@Transient
+	public void setRequired(boolean required) {
+		if (required) {
+			this.required = '1';
+		} else {
+			this.required = '0';
+		}
+	}
+
+	@Transient
+	@Override
+	public String toString() {
+		return "PIPResolverParam [id=" + id + ", paramName=" + paramName
+				+ ", paramValue=" + paramValue + ", required=" + required + "]";
+	}
+
+}
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/PIPType.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/PIPType.java
new file mode 100644
index 0000000..7208b76
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/PIPType.java
@@ -0,0 +1,131 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ *
+ */
+
+package org.apache.openaz.xacml.admin.jpa;
+
+import java.io.Serializable;
+import java.util.Set;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.NamedQuery;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+
+
+/**
+ * The persistent class for the PIPType database table.
+ * 
+ */
+@Entity
+@Table(name="PIPType")
+@NamedQuery(name="PIPType.findAll", query="SELECT p FROM PIPType p")
+public class PIPType implements Serializable {
+	private static final long serialVersionUID = 1L;
+	
+	public static final String TYPE_SQL = "SQL";
+	public static final String TYPE_LDAP = "LDAP";
+	public static final String TYPE_CSV = "CSV";
+	public static final String TYPE_HYPERCSV = "Hyper-CSV";
+	public static final String TYPE_CUSTOM = "Custom";
+
+	@Id
+	@GeneratedValue(strategy=GenerationType.AUTO)
+	@Column(name="id")
+	private int id;
+
+	@Column(name="type", nullable=false, length=45)
+	private String type;
+
+	//bi-directional many-to-one association to PIPConfiguration
+	@OneToMany(mappedBy="piptype")
+	private Set<PIPConfiguration> pipconfigurations;
+
+	public PIPType() {
+	}
+
+	public int getId() {
+		return this.id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+
+	public String getType() {
+		return this.type;
+	}
+
+	public void setType(String type) {
+		this.type = type;
+	}
+
+	public Set<PIPConfiguration> getPipconfigurations() {
+		return this.pipconfigurations;
+	}
+
+	public void setPipconfigurations(Set<PIPConfiguration> pipconfigurations) {
+		this.pipconfigurations = pipconfigurations;
+	}
+
+	public PIPConfiguration addPipconfiguration(PIPConfiguration pipconfiguration) {
+		getPipconfigurations().add(pipconfiguration);
+		pipconfiguration.setPiptype(this);
+
+		return pipconfiguration;
+	}
+
+	public PIPConfiguration removePipconfiguration(PIPConfiguration pipconfiguration) {
+		getPipconfigurations().remove(pipconfiguration);
+		pipconfiguration.setPiptype(null);
+
+		return pipconfiguration;
+	}
+	
+	@Transient
+	public boolean	isSQL() {
+		return this.type.equals(TYPE_SQL);
+	}
+
+	@Transient
+	public boolean	isLDAP() {
+		return this.type.equals(TYPE_LDAP);
+	}
+
+	@Transient
+	public boolean	isCSV() {
+		return this.type.equals(TYPE_CSV);
+	}
+
+	@Transient
+	public boolean	isHyperCSV() {
+		return this.type.equals(TYPE_HYPERCSV);
+	}
+
+	@Transient
+	public boolean	isCustom() {
+		return this.type.equals(TYPE_CUSTOM);
+	}
+
+}
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/PolicyAlgorithms.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/PolicyAlgorithms.java
new file mode 100644
index 0000000..d91e221
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/PolicyAlgorithms.java
@@ -0,0 +1,116 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ *
+ */
+
+package org.apache.openaz.xacml.admin.jpa;
+
+import java.io.Serializable;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.NamedQuery;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+
+import org.apache.openaz.xacml.api.Identifier;
+
+@Entity
+@Table(name="PolicyAlgorithms")
+@NamedQuery(name="PolicyAlgorithms.findAll", query="SELECT d FROM PolicyAlgorithms d")
+public class PolicyAlgorithms implements Serializable {
+	private static final long serialVersionUID = 1L;
+	
+	public static final char STANDARD = 'S';
+	public static final char CUSTOM = 'C';
+
+	@Id
+	@GeneratedValue(strategy = GenerationType.AUTO)
+	@Column(name="id")
+	private int id;
+
+	@Column(name="is_standard", nullable=false)
+	private char isStandard;
+
+	@Column(name="xacml_id", nullable=false, unique=true, length=255)
+	private String xacmlId;
+	
+	@Column(name="short_name", nullable=false, length=64)
+	private String shortName;
+
+	public PolicyAlgorithms(Identifier identifier, char standard) {
+		this.isStandard = standard;
+		if (identifier != null) {
+			this.xacmlId = identifier.stringValue();
+		}
+	}
+	
+	public PolicyAlgorithms(Identifier identifier) {
+		this(identifier, PolicyAlgorithms.STANDARD);
+	}
+
+	public PolicyAlgorithms() {
+		this(null, PolicyAlgorithms.STANDARD);
+	}
+	
+	public int getId() {
+		return this.id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+
+	public char getIsStandard() {
+		return this.isStandard;
+	}
+
+	public void setIsStandard(char isStandard) {
+		this.isStandard = isStandard;
+	}
+
+	@Transient
+	public boolean isStandard() {
+		return this.isStandard == PolicyAlgorithms.STANDARD;
+	}
+	
+	@Transient
+	public boolean isCustom() {
+		return this.isStandard == PolicyAlgorithms.CUSTOM;
+	}
+
+	public String getXacmlId() {
+		return this.xacmlId;
+	}
+
+	public void setXacmlId(String xacmlId) {
+		this.xacmlId = xacmlId;
+	}
+
+	public String getShortName() {
+		return shortName;
+	}
+
+	public void setShortName(String shortName) {
+		this.shortName = shortName;
+	}
+
+}
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/RuleAlgorithms.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/RuleAlgorithms.java
new file mode 100644
index 0000000..961984e
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/RuleAlgorithms.java
@@ -0,0 +1,115 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ *
+ */
+
+package org.apache.openaz.xacml.admin.jpa;
+
+import java.io.Serializable;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.NamedQuery;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+
+import org.apache.openaz.xacml.api.Identifier;
+
+@Entity
+@Table(name="RuleAlgorithms")
+@NamedQuery(name="RuleAlgorithms.findAll", query="SELECT d FROM RuleAlgorithms d")
+public class RuleAlgorithms implements Serializable {
+	private static final long serialVersionUID = 1L;
+
+	public static final char STANDARD = 'S';
+	public static final char CUSTOM = 'C';
+
+	@Id
+	@GeneratedValue(strategy = GenerationType.AUTO)
+	@Column(name="id")
+	private int id;
+
+	@Column(name="is_standard", nullable=false)
+	private char isStandard;
+
+	@Column(name="xacml_id", nullable=false, unique=true, length=255)
+	private String xacmlId;
+	
+	@Column(name="short_name", nullable=false, length=64)
+	private String shortName;
+
+	public RuleAlgorithms(Identifier id, char standard) {
+		if (id != null) {
+			this.xacmlId = id.stringValue();
+		}
+		this.isStandard = standard;
+	}
+	public RuleAlgorithms(Identifier id) {
+		this(id, RuleAlgorithms.STANDARD);
+	}
+
+	public RuleAlgorithms() {
+		this(null, RuleAlgorithms.STANDARD);
+	}
+
+	public int getId() {
+		return this.id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+
+	public char getIsStandard() {
+		return this.isStandard;
+	}
+
+	public void setIsStandard(char isStandard) {
+		this.isStandard = isStandard;
+	}
+	
+	@Transient
+	public boolean isStandard() {
+		return this.isStandard == RuleAlgorithms.STANDARD;
+	}
+	
+	@Transient
+	public boolean isCustom() {
+		return this.isStandard == RuleAlgorithms.CUSTOM;
+	}
+
+	public String getXacmlId() {
+		return this.xacmlId;
+	}
+
+	public void setXacmlId(String xacmlId) {
+		this.xacmlId = xacmlId;
+	}
+
+	public String getShortName() {
+		return shortName;
+	}
+
+	public void setShortName(String shortName) {
+		this.shortName = shortName;
+	}
+
+}
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/package-info.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/package-info.java
new file mode 100644
index 0000000..85d06f5
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/package-info.java
@@ -0,0 +1,28 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ *
+ */
+
+/**
+ * 
+ */
+/**
+ * @author pameladragosh
+ *
+ */
+package org.apache.openaz.xacml.admin.jpa;
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/model/AttributeContainer.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/model/AttributeContainer.java
new file mode 100644
index 0000000..37d2fd4
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/model/AttributeContainer.java
@@ -0,0 +1,500 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ *
+ */
+
+package org.apache.openaz.xacml.admin.model;
+
+import java.lang.reflect.Method;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.openaz.xacml.admin.jpa.Category;
+import org.apache.openaz.xacml.admin.jpa.Datatype;
+import org.apache.openaz.xacml.admin.util.JPAUtils;
+import org.apache.openaz.xacml.api.AttributeValue;
+import org.apache.openaz.xacml.api.Identifier;
+import org.apache.openaz.xacml.util.XACMLPolicyAggregator;
+import org.apache.openaz.xacml.util.XACMLPolicyScanner;
+import com.vaadin.data.Container;
+import com.vaadin.data.Item;
+import com.vaadin.data.Property;
+import com.vaadin.data.util.MethodProperty;
+import com.vaadin.ui.Table;
+
+public class AttributeContainer extends ItemSetChangeNotifier implements Container.Hierarchical, Container.ItemSetChangeNotifier {
+	private static final long serialVersionUID = 1L;
+	private static Log logger	= LogFactory.getLog(AttributeContainer.class);
+	//private final AttributeContainer self = this;
+	private final Map<Category, Map<Datatype, Map<String, Set<ContainerAttribute>>>> mapAttributes = new HashMap<Category, Map<Datatype, Map<String, Set<ContainerAttribute>>>>();
+
+	class ContainerAttribute {
+		Path				policy;
+		boolean				isRoot;
+		AttributeValue<?>	value;
+		
+		public ContainerAttribute(Path policy, boolean isRoot, AttributeValue<?> value) {
+			this.policy = policy;
+			this.isRoot = isRoot;
+			this.value = value;
+		}
+
+		public Path getPolicy() {
+			return policy;
+		}
+
+		public boolean isRoot() {
+			return isRoot;
+		}
+
+		public AttributeValue<?> getValue() {
+			return value;
+		}
+		
+		public boolean isCustom() {
+			return this.policy == null;
+		}
+	}
+    /**
+     * String identifier of an object's "id" property.
+     */
+    public static String PROPERTY_ID = "Id";
+
+    /**
+     * String identifier of an object's "category" property.
+     */
+    public static String PROPERTY_CATEGORY = "Category";
+
+    /**
+     * String identifier of an object's "datatype" property.
+     */
+    public static String PROPERTY_DATATYPE = "Datatype";
+
+    /**
+     * String identifier of an object's "value" property.
+     */
+    public static String PROPERTY_VALUES = "Values";
+
+    /**
+     * List of the string identifiers for the available properties.
+     */
+    public static Collection<String> ATTRIBUTE_PROPERTIES;
+
+    private final static Method ATTRIBUTEITEM_ID;
+    private final static Method ATTRIBUTEITEM_CATEGORY;
+    private final static Method ATTRIBUTEITEM_DATATYPE;
+    private final static Method ATTRIBUTEITEM_VALUES;
+    static {
+    	ATTRIBUTE_PROPERTIES = new ArrayList<String>();
+    	ATTRIBUTE_PROPERTIES.add(PROPERTY_ID);
+    	ATTRIBUTE_PROPERTIES.add(PROPERTY_CATEGORY);
+    	ATTRIBUTE_PROPERTIES.add(PROPERTY_DATATYPE);
+    	ATTRIBUTE_PROPERTIES.add(PROPERTY_VALUES);
+    	ATTRIBUTE_PROPERTIES =  Collections.unmodifiableCollection(ATTRIBUTE_PROPERTIES);
+    	try {
+    		ATTRIBUTEITEM_ID = AttributeItem.class.getMethod("getId", new Class[]{});
+    		ATTRIBUTEITEM_CATEGORY = AttributeItem.class.getMethod("getCategory", new Class[]{});
+    		ATTRIBUTEITEM_DATATYPE = AttributeItem.class.getMethod("getDatatype", new Class[]{});
+    		ATTRIBUTEITEM_VALUES = AttributeItem.class.getMethod("getValues", new Class[]{});
+    	} catch (final NoSuchMethodException e) {
+            throw new RuntimeException("Internal error finding methods in AttributeContainer");
+        }
+    }
+    
+	public AttributeContainer(Path rootPolicy, Collection<Path> referencedPolicies) {
+		super();
+		this.setContainer(this);
+		this.initialize(rootPolicy, referencedPolicies);
+	}
+	
+	protected void initialize(Path rootPolicy, Collection<Path> referencedPolicies) {
+		XACMLPolicyAggregator aggregator = new XACMLPolicyAggregator();
+		//
+		// Scan the policy
+		//
+		new XACMLPolicyScanner(rootPolicy, aggregator).scan();
+		this.addAttributes(aggregator, rootPolicy, true);
+		aggregator = new XACMLPolicyAggregator();
+		//
+		// Scan the referenced policies
+		//
+		for (Path policy : referencedPolicies) {
+			new XACMLPolicyScanner(policy, aggregator).scan();
+			this.addAttributes(aggregator, policy, false);
+			aggregator = new XACMLPolicyAggregator();
+		}
+	}
+	
+	protected void addAttributes(XACMLPolicyAggregator aggregator, Path policy, boolean isRoot) {
+		for (Identifier cat : aggregator.getAttributeMap().keySet()) {
+			Category category = JPAUtils.findCategory(cat);
+			if (category == null) {
+				logger.warn("Could not find category: " + cat);
+				continue;
+			}
+			if (this.mapAttributes.containsKey(category) == false) {
+				this.mapAttributes.put(category, new HashMap<Datatype, Map<String, Set<ContainerAttribute>>>());
+			}
+			Map<Datatype, Map<String, Set<ContainerAttribute>>> datatypeMap = this.mapAttributes.get(category);
+			for (Identifier dt : aggregator.getAttributeMap().get(cat).keySet()) {
+				Datatype datatype = JPAUtils.findDatatype(dt);
+				if (datatype == null) {
+					logger.warn("Could not find datatype: " + dt);
+				}
+				//
+				// Need a unique datatype object
+				//
+				datatype = new Datatype((int) System.currentTimeMillis(), datatype);
+				if (datatypeMap.containsKey(datatype) == false) {
+					datatypeMap.put(datatype, new HashMap<String, Set<ContainerAttribute>>());
+				}
+				Map<String, Set<ContainerAttribute>> attributeMap = datatypeMap.get(datatype);
+				for (Identifier id : aggregator.getAttributeMap().get(cat).get(dt).keySet()) {
+					if (attributeMap.containsKey(id.stringValue()) == false) {
+						attributeMap.put(id.stringValue(), new HashSet<ContainerAttribute>());
+					}
+					for (AttributeValue<?> attribute : aggregator.getAttributeMap().get(cat).get(dt).get(id)) {
+						attributeMap.get(id.stringValue()).add(new ContainerAttribute(policy, isRoot, attribute));
+					}
+				}
+			}
+		}
+	}
+	
+	protected boolean isObjectSupported(Object itemId) {
+		if (itemId instanceof Category ||
+			itemId instanceof Datatype ||
+			itemId instanceof String ||
+			itemId instanceof ContainerAttribute) {
+			return true;
+		}
+		return false;
+	}
+
+	@Override
+	public Item getItem(Object itemId) {
+		if (this.isObjectSupported(itemId)) {
+			return new AttributeItem(itemId);
+		}
+		return null;
+	}
+
+	@Override
+	public Collection<?> getContainerPropertyIds() {
+		return ATTRIBUTE_PROPERTIES;
+	}
+
+	@Override
+	public Collection<?> getItemIds() {
+		final Collection<Object> items = new ArrayList<Object>();
+		for (Category category : this.mapAttributes.keySet()) {
+			items.add(category);
+			for (Datatype datatype : this.mapAttributes.get(category).keySet()) {
+				items.add(datatype);
+				for (String id : this.mapAttributes.get(category).get(datatype).keySet()) {
+					items.add(id);
+					for (ContainerAttribute attribute : this.mapAttributes.get(category).get(datatype).get(id)) {
+						items.add(attribute);
+					}
+				}
+			}
+		}
+		return Collections.unmodifiableCollection(items);
+	}
+
+	@Override
+	public Property<?> getContainerProperty(Object itemId, Object propertyId) {
+		if (this.isObjectSupported(itemId) == false) {
+			return null;
+		}
+        if (propertyId.equals(PROPERTY_ID)) {
+            return new MethodProperty<Object>(getType(propertyId), 
+            						new AttributeItem(itemId), ATTRIBUTEITEM_ID, null);
+        }
+        if (propertyId.equals(PROPERTY_CATEGORY)) {
+            return new MethodProperty<Object>(getType(propertyId), 
+            						new AttributeItem(itemId), ATTRIBUTEITEM_CATEGORY, null);
+        }
+        if (propertyId.equals(PROPERTY_DATATYPE)) {
+            return new MethodProperty<Object>(getType(propertyId), 
+            						new AttributeItem(itemId), ATTRIBUTEITEM_DATATYPE, null);
+        }
+        if (propertyId.equals(PROPERTY_VALUES)) {
+            return new MethodProperty<Object>(getType(propertyId), 
+            						new AttributeItem(itemId), ATTRIBUTEITEM_VALUES, null);
+        }
+		return null;
+	}
+
+	@Override
+	public Class<?> getType(Object propertyId) {
+        if (propertyId.equals(PROPERTY_ID)) {
+            return String.class;
+        }
+        if (propertyId.equals(PROPERTY_CATEGORY)) {
+            return Category.class;
+        }
+        if (propertyId.equals(PROPERTY_DATATYPE)) {
+            return Datatype.class;
+        }
+        if (propertyId.equals(PROPERTY_VALUES)) {
+            return Table.class;
+        }
+		return null;
+	}
+
+	@Override
+	public int size() {
+		return this.mapAttributes.size();
+	}
+
+	@Override
+	public boolean containsId(Object itemId) {
+		if (this.isObjectSupported(itemId) == false) {
+			return false;
+		}
+		if (itemId instanceof Category) {
+			return this.mapAttributes.containsKey(itemId);
+		}
+		for (Category category : this.mapAttributes.keySet()) {
+			if (itemId instanceof Datatype) {
+				return this.mapAttributes.get(category).containsKey(itemId);
+			}
+			for (Datatype datatype : this.mapAttributes.get(category).keySet()) {
+				if (itemId instanceof String) {
+					return this.mapAttributes.get(category).get(datatype).containsKey(itemId);
+				}
+				for (String id : this.mapAttributes.get(category).get(datatype).keySet()) {
+					if (itemId instanceof ContainerAttribute) {
+						return this.mapAttributes.get(category).get(datatype).get(id).contains(itemId);
+					}
+				}
+			}
+		}
+		return false;
+	}
+
+	@Override
+	public Item addItem(Object itemId) throws UnsupportedOperationException {
+		throw new UnsupportedOperationException("Use addItem(Category, Datatype, AttributeValue<?>) instead.");
+	}
+
+	@Override
+	public Object addItem() throws UnsupportedOperationException {
+		throw new UnsupportedOperationException("Use addItem(Category, Datatype, AttributeValue<?>) instead.");
+	}
+
+	@Override
+	public boolean addContainerProperty(Object propertyId, Class<?> type,
+			Object defaultValue) throws UnsupportedOperationException {
+		return false;
+	}
+
+	@Override
+	public boolean removeContainerProperty(Object propertyId)
+			throws UnsupportedOperationException {
+		return false;
+	}
+
+	@Override
+	public boolean removeAllItems() throws UnsupportedOperationException {
+		throw new UnsupportedOperationException("Can't remove all the items. You can remove custom user attributes.");
+	}
+
+	@Override
+	public Collection<?> getChildren(Object itemId) {
+		//
+		// PLD TODO - this may not work for Datatype
+		//
+		final Collection<Object> items = new ArrayList<Object>();
+		for (Category category : this.mapAttributes.keySet()) {
+			for (Datatype datatype : this.mapAttributes.get(category).keySet()) {
+				if (itemId instanceof Category) {
+					items.add(datatype);
+				}
+				for (String id : this.mapAttributes.get(category).get(datatype).keySet()) {
+					if (itemId instanceof Category ||
+						itemId instanceof Datatype) {
+						items.add(id);
+						items.addAll(this.mapAttributes.get(category).get(datatype).get(id));
+					} else if (itemId instanceof String) {
+						items.addAll(this.mapAttributes.get(category).get(datatype).get(id));
+					}
+				}
+			}
+		}
+		return Collections.unmodifiableCollection(items);
+	}
+
+	@Override
+	public Object getParent(Object itemId) {
+		if (this.isObjectSupported(itemId) == false) {
+			return null;
+		}
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public Collection<?> rootItemIds() {
+		final Collection<Object> items = new ArrayList<Object>();
+		items.add(this.mapAttributes.keySet());
+		return Collections.unmodifiableCollection(items);
+	}
+
+	@Override
+	public boolean setParent(Object itemId, Object newParentId) throws UnsupportedOperationException {
+		throw new UnsupportedOperationException("Can't move attributes around. Use addItem(Category, Datatype, Attribute).");
+	}
+
+	@Override
+	public boolean areChildrenAllowed(Object itemId) {
+		if (itemId instanceof Category ||
+			itemId instanceof Datatype ||
+			itemId instanceof String) {
+			return true;
+		}
+		return false;
+	}
+
+	@Override
+	public boolean setChildrenAllowed(Object itemId, boolean areChildrenAllowed)
+			throws UnsupportedOperationException {
+		if (itemId instanceof Category ||
+			itemId instanceof Datatype ||
+			itemId instanceof String) {
+			if (areChildrenAllowed) {
+				return true;
+			}
+			return false;
+		}
+		if (areChildrenAllowed == false) {
+			return true;
+		}
+		return false;
+	}
+
+	@Override
+	public boolean isRoot(Object itemId) {
+		return this.mapAttributes.containsKey(itemId);
+	}
+
+	@Override
+	public boolean hasChildren(Object itemId) {
+		if (itemId instanceof ContainerAttribute) {
+			return false;
+		}
+		if (itemId instanceof Category) {
+			if (this.mapAttributes.containsKey(itemId)) {
+				return this.mapAttributes.get(itemId).size() > 0;
+			}
+			return false;
+		}
+		//
+		// PLD TODO - this may not work. Datatype may prove difficult
+		// to distinguish which category it is in.
+		//
+		for (Category category : this.mapAttributes.keySet()) {
+			if (itemId instanceof Datatype) {
+				if (this.mapAttributes.get(category).containsKey(itemId)) {
+					return this.mapAttributes.get(category).get(itemId).size() > 0;
+				}
+				continue;
+			}
+			for (Datatype datatype : this.mapAttributes.get(category).keySet()) {
+				if (itemId instanceof String) {
+					if (this.mapAttributes.get(category).get(datatype).containsKey(itemId)) {
+						return this.mapAttributes.get(category).get(datatype).get(itemId).size() > 0;
+					}
+					continue;
+				}
+			}
+		}
+		return false;
+	}
+
+	@Override
+	public boolean removeItem(Object itemId) throws UnsupportedOperationException {
+		if (! (itemId instanceof ContainerAttribute)) {
+			return false;
+		}
+		for (Category category : this.mapAttributes.keySet()) {
+			for (Datatype datatype : this.mapAttributes.get(category).keySet()) {
+				for (String id : this.mapAttributes.get(category).get(datatype).keySet()) {
+					if (this.mapAttributes.get(category).get(datatype).get(id).contains(itemId)) {
+						return this.mapAttributes.get(category).get(datatype).get(id).remove(itemId);
+					}
+				}
+			}
+		}
+		return false;
+	}
+	
+	public class AttributeItem implements Item {
+		private static final long serialVersionUID = 1L;
+		private final Object data;
+		
+		public AttributeItem(Object data) {
+			this.data = data;
+		}
+		
+		public String getId() {
+			return null;
+		}
+		
+		public Category getCategory() {
+			return null;
+		}
+		
+		public Datatype getDatatype() {
+			return null;
+		}
+		
+		public Table	getValues() {
+			return null;
+		}
+
+		@Override
+		public Property<?> getItemProperty(Object id) {
+            return getContainerProperty(this.data, id);
+		}
+
+		@Override
+		public Collection<?> getItemPropertyIds() {
+	          return getContainerPropertyIds();
+		}
+
+		@Override
+		public boolean addItemProperty(Object id, @SuppressWarnings("rawtypes") Property property) throws UnsupportedOperationException {
+            throw new UnsupportedOperationException("Attribute container does not support adding new properties");
+		}
+		@Override
+		public boolean removeItemProperty(Object id) throws UnsupportedOperationException {
+            throw new UnsupportedOperationException("Attribute container does not support removing properties");
+		}
+	}
+}
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/model/AttributeValueContainer.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/model/AttributeValueContainer.java
new file mode 100644
index 0000000..1074936
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/model/AttributeValueContainer.java
@@ -0,0 +1,300 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ *
+ */
+
+package org.apache.openaz.xacml.admin.model;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.openaz.xacml.admin.jpa.Datatype;
+import org.apache.openaz.xacml.admin.model.AttributeContainer.ContainerAttribute;
+import com.vaadin.data.Container;
+import com.vaadin.data.Item;
+import com.vaadin.data.Property;
+import com.vaadin.data.util.MethodProperty;
+
+public class AttributeValueContainer extends ItemSetChangeNotifier implements Container.Ordered, Container.ItemSetChangeNotifier {
+	private static final long serialVersionUID = 1L;
+	private final Datatype datatype; //NOPMD
+	private final List<ContainerAttribute> attributes;
+
+    /**
+     * String identifier of an object's "Value" property.
+     */
+    public static String PROPERTY_VALUE = "Value";
+
+    /**
+     * String identifier of an object's "Source" property.
+     */
+    public static String PROPERTY_SOURCE = "Source";
+
+    /**
+     * List of the string identifiers for the available properties.
+     */
+    public static Collection<String> ATTRIBUTEVALUE_PROPERTIES;
+
+    private final static Method ATTRIBUTEVALUEITEM_VALUE;
+    private final static Method ATTRIBUTEVALUEITEM_SOURCE;
+    static {
+    	ATTRIBUTEVALUE_PROPERTIES = new ArrayList<String>();
+    	ATTRIBUTEVALUE_PROPERTIES.add(PROPERTY_VALUE);
+    	ATTRIBUTEVALUE_PROPERTIES.add(PROPERTY_SOURCE);
+    	ATTRIBUTEVALUE_PROPERTIES =  Collections.unmodifiableCollection(ATTRIBUTEVALUE_PROPERTIES);
+    	try {
+    		ATTRIBUTEVALUEITEM_VALUE = AttributeValueItem.class.getMethod("getValue", new Class[]{});
+    		ATTRIBUTEVALUEITEM_SOURCE = AttributeValueItem.class.getMethod("getSource", new Class[]{});
+    	} catch (final NoSuchMethodException e) {
+            throw new RuntimeException("Internal error finding methods in AttributeValueContainer");
+        }
+    }
+    
+    public AttributeValueContainer(Datatype datatype, List<ContainerAttribute> attributes) {
+		this.datatype = datatype;
+		this.attributes = attributes;
+	}
+    
+    public boolean isObjectSupported(Object itemId) {
+    	return itemId instanceof ContainerAttribute;
+    }
+
+	@Override
+	public Item getItem(Object itemId) {
+		if (itemId instanceof ContainerAttribute) {
+			return new AttributeValueItem((ContainerAttribute) itemId);
+		}
+		return null;
+	}
+
+	@Override
+	public Collection<?> getContainerPropertyIds() {
+		return ATTRIBUTEVALUE_PROPERTIES;
+	}
+
+	@Override
+	public Collection<?> getItemIds() {
+		return Collections.unmodifiableList(this.attributes);
+	}
+
+	@Override
+	public Property<?> getContainerProperty(Object itemId, Object propertyId) {
+		if (this.isObjectSupported(itemId) == false) {
+			return null;
+		}
+        if (propertyId.equals(PROPERTY_VALUE)) {
+            return new MethodProperty<Object>(getType(propertyId),
+                    new AttributeValueItem((ContainerAttribute) itemId), ATTRIBUTEVALUEITEM_VALUE, null);
+        }
+
+        if (propertyId.equals(PROPERTY_SOURCE)) {
+            return new MethodProperty<Object>(getType(propertyId),
+                    new AttributeValueItem((ContainerAttribute) itemId), ATTRIBUTEVALUEITEM_SOURCE, null);
+        }
+		return null;
+	}
+
+	@Override
+	public Class<?> getType(Object propertyId) {
+        if (propertyId.equals(PROPERTY_VALUE)) {
+            return String.class;
+        }
+        if (propertyId.equals(PROPERTY_SOURCE)) {
+            return String.class;
+        }
+		return null;
+	}
+
+	@Override
+	public int size() {
+		return this.attributes.size();
+	}
+
+	@Override
+	public boolean containsId(Object itemId) {
+		return this.attributes.contains(itemId);
+	}
+
+	@Override
+	public Item addItem(Object itemId) throws UnsupportedOperationException {
+		if (this.isObjectSupported(itemId) == false) {
+			return null;
+		}
+		return new AttributeValueItem((ContainerAttribute) itemId);
+	}
+
+	@Override
+	public Object addItem() throws UnsupportedOperationException {
+		throw new UnsupportedOperationException("Please use addItem(Object itemId) - setup the container attribute first.");
+	}
+
+	@Override
+	public boolean removeItem(Object itemId) throws UnsupportedOperationException {
+		if (this.isObjectSupported(itemId) == false) {
+			return false;
+		}
+		throw new UnsupportedOperationException("TODO");
+//		return this.attributes.remove(itemId);
+	}
+
+	@Override
+	public boolean addContainerProperty(Object propertyId, Class<?> type,
+			Object defaultValue) throws UnsupportedOperationException {
+		return false;
+	}
+
+	@Override
+	public boolean removeContainerProperty(Object propertyId)
+			throws UnsupportedOperationException {
+		return false;
+	}
+
+	@Override
+	public boolean removeAllItems() throws UnsupportedOperationException {
+		throw new UnsupportedOperationException("TODO");
+//		this.attributes.clear();
+//		return true;
+	}
+
+	@Override
+	public Object nextItemId(Object itemId) {
+		if (this.isObjectSupported(itemId) == false) {
+			return null;
+		}
+		int index = this.getItemIndex((ContainerAttribute) itemId);
+		if (index == -1 || index >= this.attributes.size()) {
+			return null;
+		}
+		return this.attributes.get(index + 1);
+	}
+
+	@Override
+	public Object prevItemId(Object itemId) {
+		if (this.isObjectSupported(itemId) == false) {
+			return null;
+		}
+		int index = this.getItemIndex((ContainerAttribute) itemId);
+		if (index == -1 || index == 0) {
+			return null;
+		}
+		return this.attributes.get(index - 1);
+	}
+
+	@Override
+	public Object firstItemId() {
+		if (this.attributes.size() > 0) {
+			return this.attributes.get(0);
+		}
+		return null;
+	}
+
+	@Override
+	public Object lastItemId() {
+		if (this.attributes.size() > 0) {
+			return this.attributes.get(this.attributes.size() - 1);
+		}
+		return null;
+	}
+
+	@Override
+	public boolean isFirstId(Object itemId) {
+		if (this.attributes.size() > 0) {
+			return this.attributes.get(0).equals(itemId);
+		}
+		return false;
+	}
+
+	@Override
+	public boolean isLastId(Object itemId) {
+		if (this.attributes.size() > 0) {
+			return this.attributes.get(this.attributes.size() - 1).equals(itemId);
+		}
+		return false;
+	}
+
+	@Override
+	public Object addItemAfter(Object previousItemId) throws UnsupportedOperationException {
+		throw new UnsupportedOperationException("Use addItemAfter(Object previousItemId, Object newItemId) - please create the object yourself.");
+	}
+
+	@Override
+	public Item addItemAfter(Object previousItemId, Object newItemId) throws UnsupportedOperationException {
+		if (this.isObjectSupported(previousItemId) == false || this.isObjectSupported(newItemId) == false) {
+			return null;
+		}
+		int index = this.getItemIndex((ContainerAttribute) previousItemId);
+		if (index >= 0) {
+			this.attributes.add(index, (ContainerAttribute) newItemId);
+		}
+		return null;
+	}
+	
+	protected int	getItemIndex(ContainerAttribute itemId) {
+		int index;
+		for (index = 0; index < this.attributes.size(); index++) {
+			if (this.attributes.get(index).equals(itemId)) {
+				return index;
+			}
+		}
+		return -1;
+	}
+	
+	public class AttributeValueItem implements Item {
+		private static final long serialVersionUID = 1L;
+		private final ContainerAttribute attribute;
+		
+		public AttributeValueItem(ContainerAttribute attribute) {
+			this.attribute = attribute;
+		}
+
+		public String getValue() {
+			if (this.attribute == null) {
+				return null;
+			}
+			return this.attribute.value.toString();
+		}
+
+		public String getSource() {
+			if (this.attribute == null) {
+				return null;
+			}
+			return this.attribute.value.toString();
+		}
+
+		@Override
+		public Property<?> getItemProperty(Object id) {
+            return getContainerProperty(this.attribute, id);
+		}
+		@Override
+		public Collection<?> getItemPropertyIds() {
+           return getContainerPropertyIds();
+		}
+		@Override
+		public boolean addItemProperty(Object id, @SuppressWarnings("rawtypes") Property property) throws UnsupportedOperationException {
+            throw new UnsupportedOperationException("Attribute Value container does not support adding new properties");
+		}
+		@Override
+		public boolean removeItemProperty(Object id) throws UnsupportedOperationException {
+            throw new UnsupportedOperationException("Attribute Value container does not support removing properties");
+		}
+	}
+
+}
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/model/ExpressionContainer.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/model/ExpressionContainer.java
new file mode 100644
index 0000000..30c8670
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/model/ExpressionContainer.java
@@ -0,0 +1,1215 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ *
+ */
+
+package org.apache.openaz.xacml.admin.model;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.bind.JAXBElement;
+
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.ApplyType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeAssignmentExpressionType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeSelectorType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeValueType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.ConditionType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.ExpressionType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.FunctionType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObjectFactory;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.VariableDefinitionType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.VariableReferenceType;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.openaz.xacml.admin.jpa.FunctionArgument;
+import org.apache.openaz.xacml.admin.jpa.FunctionDefinition;
+import org.apache.openaz.xacml.admin.util.JPAUtils;
+import org.apache.openaz.xacml.admin.util.XACMLFunctionValidator;
+import com.vaadin.data.Container;
+import com.vaadin.data.Item;
+import com.vaadin.data.Property;
+import com.vaadin.data.util.MethodProperty;
+
+public class ExpressionContainer extends ItemSetChangeNotifier implements Container.Hierarchical, Container.ItemSetChangeNotifier {
+	private static final long serialVersionUID = 1L;
+	private static Log logger	= LogFactory.getLog(ExpressionContainer.class);
+	
+	/**
+     * String identifier of a file's "name" property.
+     */
+    public static String PROPERTY_NAME = "Name";
+
+    /**
+     * String identifier of an object's "id" property.
+     */
+    public static String PROPERTY_ID = "Id";
+
+    /**
+     * String identifier of an object's "datatype" property.
+     */
+    public static String PROPERTY_DATATYPE_SHORT = "shortDatatype";
+
+    /**
+     * String identifier of an object's "id" property.
+     */
+    public static String PROPERTY_ID_SHORT = "shortId";
+
+    /**
+     * String identifier of an object's "datatype" property.
+     */
+    public static String PROPERTY_DATATYPE = "Datatype";
+
+    /**
+     * List of the string identifiers for the available properties.
+     */
+    public static Collection<String> EXPRESSION_PROPERTIES;
+
+    private final static Method EXPRESSIONITEM_NAME;
+    
+    private final static Method EXPRESSIONITEM_ID;
+
+    private final static Method EXPRESSIONITEM_DATATYPE;
+
+    private final static Method EXPRESSIONITEM_ID_SHORT;
+
+    private final static Method EXPRESSIONITEM_DATATYPE_SHORT;
+
+    static {
+    	EXPRESSION_PROPERTIES = new ArrayList<String>();
+    	EXPRESSION_PROPERTIES.add(PROPERTY_NAME);
+    	EXPRESSION_PROPERTIES.add(PROPERTY_ID);
+    	EXPRESSION_PROPERTIES.add(PROPERTY_DATATYPE);
+    	EXPRESSION_PROPERTIES.add(PROPERTY_ID_SHORT);
+    	EXPRESSION_PROPERTIES.add(PROPERTY_DATATYPE_SHORT);
+    	EXPRESSION_PROPERTIES = Collections.unmodifiableCollection(EXPRESSION_PROPERTIES);
+    	try {
+    		EXPRESSIONITEM_NAME = ExpressionItem.class.getMethod("getName", new Class[]{});
+    		EXPRESSIONITEM_ID = ExpressionItem.class.getMethod("getId", new Class[]{});
+    		EXPRESSIONITEM_DATATYPE = ExpressionItem.class.getMethod("getDatatype", new Class[]{});
+    		EXPRESSIONITEM_ID_SHORT = ExpressionItem.class.getMethod("getIdShort", new Class[]{});
+    		EXPRESSIONITEM_DATATYPE_SHORT = ExpressionItem.class.getMethod("getDatatypeShort", new Class[]{});
+        } catch (final NoSuchMethodException e) {
+            throw new RuntimeException(
+                    "Internal error finding methods in PolicyContainer");
+        }
+    }
+    
+    protected class ApplyParent {
+    	ApplyType apply;
+    	FunctionArgument argument;
+    	
+    	public ApplyParent(ApplyType apply, FunctionArgument argument) {
+    		this.apply = apply;
+    		this.argument = argument;
+    	}
+
+		public ApplyType getApply() {
+			return apply;
+		}
+
+		public void setApply(ApplyType apply) {
+			this.apply = apply;
+		}
+
+		public FunctionArgument getArgument() {
+			return argument;
+		}
+
+		public void setArgument(FunctionArgument argument) {
+			this.argument = argument;
+		}
+    }
+    //
+    // Our parent object information and which argument we are
+    // from our parent (relevant to the Apply).
+    //
+    private final Object parent;
+    private final FunctionArgument argument;
+    //
+    // The root object of the expression
+    //
+    private Object root;
+    //
+    // Our helper tables for organization purposes and to
+    // make sure the correct functions/datatypes are being
+    // setup.
+    //
+    private Map<ApplyType, ApplyParent>					applys = new HashMap<ApplyType, ApplyParent>();
+    private Map<FunctionType, ApplyParent>				functions = new HashMap<FunctionType, ApplyParent>();
+    private Map<AttributeValueType, ApplyParent>		values = new HashMap<AttributeValueType, ApplyParent>();
+    private Map<AttributeDesignatorType, ApplyParent>	designators = new HashMap<AttributeDesignatorType, ApplyParent>();
+    private Map<AttributeSelectorType, ApplyParent>		selectors = new HashMap<AttributeSelectorType, ApplyParent>();
+    private Map<VariableReferenceType, ApplyParent>		variables = new HashMap<VariableReferenceType, ApplyParent>();
+    private Map<ExpressionType, ApplyParent>			expressions = new HashMap<ExpressionType, ApplyParent>();
+    	
+    public ExpressionContainer(Object parent, Object root, FunctionArgument argument) {
+		super();
+		this.setContainer(this);
+		this.parent = parent;
+		this.root = root;
+		this.argument = argument;
+		this.initialize();
+	}
+    
+    private void initialize() {
+    	if (logger.isTraceEnabled()) {
+    		logger.trace("Initializing: " + this.parent + " " + this.argument + " " + this.root);
+    	}
+    	//
+    	// Make sure we support the parent object
+    	//
+    	@SuppressWarnings("unused")
+		JAXBElement<?> rootElement = null;
+    	if (this.parent instanceof ConditionType) {
+    		rootElement = ((ConditionType) this.parent).getExpression();
+    	} else if (this.parent instanceof VariableDefinitionType) {
+    		rootElement = ((VariableDefinitionType) this.parent).getExpression();
+    	} else if (this.parent instanceof AttributeAssignmentExpressionType) {
+    		rootElement = ((AttributeAssignmentExpressionType) this.parent).getExpression();
+    	} else if (this.parent instanceof ApplyType) {
+    		//
+    		// They must tell us which argument we are
+    		//
+    		if (this.argument == null) {
+        		throw new IllegalArgumentException("Must supply Argument object when editing a parent ApplyType's child node");
+    		}
+    		//
+    		// Finish the initialization
+    		//
+    		this.initializeRoot();
+    	} else {
+    		throw new IllegalArgumentException("Unsupported Parent Object: " + this.parent.getClass().getCanonicalName());
+    	}
+    	/*
+    	//
+    	// Check if there actually is a root
+    	//
+    	if (rootElement == null || rootElement.getValue() == null) {
+    		//
+    		// Creating a new one
+    		//
+    		return;
+    	}
+		//
+		// Save the root
+		//
+		this.root = rootElement.getValue();
+		*/
+		//
+		// Finish initializing
+		//
+		this.initializeRoot();
+   }
+
+    private void initializeRoot() {
+    	//
+    	// Sanity check
+    	//
+    	if (this.root == null) {
+    		return;
+    	}
+		//
+		// Figure out the expression type
+		//
+		if (this.root instanceof ApplyType) {
+		   	if (logger.isTraceEnabled()) {
+		   		logger.trace("Root Is Apply");
+		   	}
+		   	//
+			// Save it
+			//
+			this.applys.put((ApplyType) this.root, null);
+			//
+			// Determine the function for this Apply
+			//
+			Map<String, FunctionDefinition> functions = JPAUtils.getFunctionIDMap();
+			FunctionDefinition function  = functions.get(((ApplyType) this.root).getFunctionId());
+			if (function == null) {
+				logger.warn("root apply does not have a function defined");
+				return;
+			}
+			//
+			// Bring in its children
+			//
+			this.initializeChildren((ApplyType) this.root, function);
+		} else if (this.root instanceof AttributeValueType) {
+		   	if (logger.isTraceEnabled()) {
+		   		logger.trace("Root Is Attribute Value");
+		   	}
+			//
+			// Save it
+			//
+			this.values.put((AttributeValueType) this.root, null);
+		} else if (this.root instanceof AttributeDesignatorType) {
+		   	if (logger.isTraceEnabled()) {
+		   		logger.trace("Root Is Attribute Designator");
+		   	}
+			//
+			// Save it
+			//
+			this.designators.put((AttributeDesignatorType) this.root, null);
+		} else if (this.root instanceof AttributeSelectorType) {
+		   	if (logger.isTraceEnabled()) {
+		   		logger.trace("Root Is Attribute Selector");
+		   	}
+			//
+			// Save it
+			//
+			this.selectors.put((AttributeSelectorType) this.root, null);
+		} else if (this.root instanceof VariableReferenceType) {
+		   	if (logger.isTraceEnabled()) {
+		   		logger.trace("Root Is Variable Reference");
+		   	}
+			//
+			// Save it
+			//
+			this.variables.put((VariableReferenceType) this.root, null);
+		} else if (this.root instanceof FunctionType) {
+		   	if (logger.isTraceEnabled()) {
+		   		logger.trace("Root Is Function");
+		   	}
+			//
+			// Save it - Really? I don't think the root would ever be a function.
+			//
+			this.functions.put((FunctionType) this.root, null);
+		} else {
+			throw new IllegalArgumentException("Unsupported Expression Root Item: " + this.root.getClass().getCanonicalName());
+		}
+    }
+    
+    private void initializeChildren(ApplyType apply, FunctionDefinition function) {
+    	int index = 1;
+    	for (JAXBElement<?> child : apply.getExpression()) {
+    		//
+    		// Validate the child
+    		//
+    		if (child.getValue() == null) {
+    			logger.warn("child element " + index + "has a null object.");
+    			index++;
+    			continue;
+    		}
+		   	if (logger.isTraceEnabled()) {
+		   		logger.trace("Child " + index + " is " + child.getValue());
+		   	}
+    		//
+    		// Get the argument for this child
+    		//
+    		if (function == null) {
+    			throw new IllegalArgumentException("Apply has children but no function defined.");
+    		}
+    		FunctionArgument argument = XACMLFunctionValidator.getFunctionArgument(index, function);
+		   	if (logger.isTraceEnabled()) {
+		   		logger.trace("Child's argument is: " + argument);
+		   	}
+    		if (argument == null) {
+    			//throw new Exception("Unable to find function argument: " + index + " " + function.getId() + " " + function.getShortname());
+    			return;
+    		}
+			//
+			// See if its another apply type
+			//
+    		if (child.getValue() instanceof ApplyType) {
+    			//
+    			// Save it
+    			//
+    			this.applys.put((ApplyType) child.getValue(), new ApplyParent(apply, argument));
+    			//
+    			// Get its function information
+    			//
+    			Map<String, FunctionDefinition> functions = JPAUtils.getFunctionIDMap();
+    			FunctionDefinition childFunction  = functions.get(((ApplyType) child.getValue()).getFunctionId());
+    			if (childFunction == null) {
+    				logger.warn("Apply object " + index + " does not have a function defined");
+    			} else {
+	    			//
+	    			// Bring in its children
+	    			//
+	    			this.initializeChildren((ApplyType) child.getValue(), childFunction);
+    			}
+    		} else if (child.getValue() instanceof AttributeValueType) {
+    			//
+    			// Save it
+    			//
+    			this.values.put((AttributeValueType) child.getValue(), new ApplyParent(apply, argument));
+    		} else if (child.getValue() instanceof AttributeDesignatorType) {
+    			//
+    			// Save it
+    			//
+    			this.designators.put((AttributeDesignatorType) child.getValue(), new ApplyParent(apply, argument));
+    		} else if (child.getValue() instanceof AttributeSelectorType) {
+    			//
+    			// Save it
+    			//
+    			this.selectors.put((AttributeSelectorType) child.getValue(), new ApplyParent(apply, argument));
+    		} else if (child.getValue() instanceof VariableReferenceType) {
+    			//
+    			// Save it
+    			//
+    			this.variables.put((VariableReferenceType) child.getValue(), new ApplyParent(apply, argument));
+    		} else if (child.getValue() instanceof FunctionType) {
+    			//
+    			// Save it
+    			//
+    			this.functions.put((FunctionType) child.getValue(), new ApplyParent(apply, argument));
+    		} else if (child.getValue() instanceof ExpressionType) {
+    			//
+    			// Save it
+    			//
+    			this.expressions.put((ExpressionType) child.getValue(), new ApplyParent(apply, argument));
+    		} else {
+    			logger.error("Unknown child type: " + child.getClass().getCanonicalName());
+    		}
+    		index++;
+    	}
+    }
+    
+    protected boolean	isObjectSupported(Object itemId) {
+		if (itemId instanceof ApplyType ||
+			itemId instanceof AttributeValueType ||
+			itemId instanceof AttributeDesignatorType ||
+			itemId instanceof AttributeSelectorType ||
+			itemId instanceof VariableReferenceType ||
+			itemId instanceof FunctionType ||
+			itemId instanceof ExpressionType) {
+			return true;
+		}
+		return false;
+    }
+    
+    protected boolean isParentObjectSupport(Object parent) {
+		if (parent instanceof ApplyType ||
+			parent instanceof ConditionType ||
+			parent instanceof VariableDefinitionType ||
+			parent instanceof AttributeAssignmentExpressionType) {
+			return true;
+		}
+		return false;
+    }
+    
+	public void updateItem(Object itemId) {
+		//
+		// Sanity check
+		//
+		if (this.isObjectSupported(itemId) == false) {
+			return;// null;
+		}
+		//
+		// Notify - the real reason for this function
+		//
+		this.fireItemSetChange();
+		//
+		// Return the item
+		//
+		//return new ExpressionItem(itemId);
+	}
+
+	@Override
+	public Item getItem(Object itemId) {
+		if (this.isObjectSupported(itemId) == false) {
+			return null;
+		}
+		return new ExpressionItem(itemId);
+	}
+
+	@Override
+	public Collection<?> getContainerPropertyIds() {
+		return EXPRESSION_PROPERTIES;
+	}
+
+	@Override
+	public Collection<?> getItemIds() {
+		final Collection<Object> items = new ArrayList<Object>();
+		if (this.root != null) {
+			//
+			// Add the root object
+			//
+			items.add(this.root);
+			//
+			// If its an apply, it could have children
+			//
+			if (this.root instanceof ApplyType) {
+				items.add(this.getChildrenIds((ApplyType) this.root, true));
+			}
+		}
+		if (logger.isTraceEnabled()) {
+			logger.trace("getItemIds (" + items.size() + "):" + items);
+		}
+		return Collections.unmodifiableCollection(items);
+	}
+	
+	protected Collection<?> getChildrenIds(ApplyType apply, boolean recursive) {
+		Collection<Object> items = new ArrayList<Object>();
+    	for (JAXBElement<?> child : apply.getExpression()) {
+    		//
+    		// Make sure there's a value
+    		//
+    		if (child.getValue() == null) {
+    			continue;
+    		}
+    		//
+    		// What kind is it?
+    		//
+    		if (child.getValue() instanceof ApplyType) {
+    			items.add(child.getValue());
+    			//
+    			// Do we add its children?
+    			//
+    			if (recursive) {
+        			items.addAll(this.getChildrenIds((ApplyType) child.getValue(), true));
+    			}
+    		} else if (child.getValue() instanceof AttributeValueType) {
+    			items.add(child.getValue());
+    		} else if (child.getValue() instanceof AttributeDesignatorType) {
+    			items.add(child.getValue());
+    		} else if (child.getValue() instanceof AttributeSelectorType) {
+    			items.add(child.getValue());
+    		} else if (child.getValue() instanceof VariableReferenceType) {
+    			items.add(child.getValue());
+    		} else if (child.getValue() instanceof FunctionType) {