You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openaz.apache.org by pd...@apache.org on 2016/03/17 02:06:45 UTC

[06/23] incubator-openaz git commit: Ported original att source to openaz

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/a1d93100/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/ColumnSelectionWindow.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/ColumnSelectionWindow.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/ColumnSelectionWindow.java
new file mode 100644
index 0000000..b961a78
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/ColumnSelectionWindow.java
@@ -0,0 +1,192 @@
+/*
+ *  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.view.windows;
+
+import com.vaadin.annotations.AutoGenerated;
+import com.vaadin.data.Buffered.SourceException;
+import com.vaadin.data.Validator.InvalidValueException;
+import com.vaadin.data.validator.IntegerRangeValidator;
+import com.vaadin.event.FieldEvents.TextChangeEvent;
+import com.vaadin.event.FieldEvents.TextChangeListener;
+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.CustomComponent;
+import com.vaadin.ui.TextField;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.Window;
+
+public class ColumnSelectionWindow extends Window {
+
+	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */
+
+	@AutoGenerated
+	private VerticalLayout mainLayout;
+	@AutoGenerated
+	private Button buttonSave;
+	@AutoGenerated
+	private TextField textFieldColumn;
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+	private boolean isSaved = false;
+	private ColumnSelectionWindow self = this;
+	
+	/**
+	 * 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 ColumnSelectionWindow(Integer value) {
+		buildMainLayout();
+		//setCompositionRoot(mainLayout);
+		setContent(mainLayout);
+		//
+		// Initialize
+		//
+		this.initialize();
+		//
+		// Set the value
+		//
+		if (value != null) {
+			this.textFieldColumn.setValue(value.toString());
+		} else {
+			this.textFieldColumn.setValue(Integer.toString(0));
+		}
+		//
+		// Shortcuts
+		//
+		this.setCloseShortcut(KeyCode.ESCAPE);
+		this.buttonSave.setClickShortcut(KeyCode.ENTER);
+		//
+		// Focus
+		//
+		this.textFieldColumn.focus();
+	}
+	
+	protected void initialize() {
+		this.initializeText();
+		this.initializeButton();
+	}
+
+	protected void initializeText() {
+		//
+		// Add a validator
+		//
+		this.textFieldColumn.addValidator(new IntegerRangeValidator("Please enter an integer greater than or equal to 0.", 0, null));
+		//
+		// Respond to text changing to setup the button
+		//
+		this.textFieldColumn.addTextChangeListener(new TextChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void textChange(TextChangeEvent event) {
+				if (event.getText() != null && event.getText().isEmpty() == false) {
+					self.buttonSave.setEnabled(true);
+				} else {
+					self.buttonSave.setEnabled(false);
+				}
+			}
+		});
+	}
+	
+	protected void initializeButton() {
+		self.buttonSave.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				try {
+					//
+					// Commit
+					//
+					self.textFieldColumn.commit();
+					//
+					// If we get here, the value is valid.
+					// Mark ourselves as saved and close the window
+					//
+					self.isSaved = true;
+					self.close();
+				} catch (SourceException | InvalidValueException e) { //NOPMD
+					//
+					// Vaadin will display error
+					//
+				}
+			}
+		});
+	}
+	
+	public boolean isSaved() {
+		return this.isSaved;
+	}
+	
+	public Integer getColumn() {
+		try {
+			return Integer.parseInt(this.textFieldColumn.getValue());
+		} catch (NumberFormatException e) {
+			return null;
+		}
+	}
+	
+	@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");
+		
+		// textFieldColumn
+		textFieldColumn = new TextField();
+		textFieldColumn.setCaption("Column");
+		textFieldColumn.setImmediate(false);
+		textFieldColumn.setDescription("0-based index into CSV line");
+		textFieldColumn.setWidth("-1px");
+		textFieldColumn.setHeight("-1px");
+		textFieldColumn.setRequired(true);
+		textFieldColumn.setInputPrompt("Eg. ‘0'");
+		mainLayout.addComponent(textFieldColumn);
+		
+		// buttonSave
+		buttonSave = new Button();
+		buttonSave.setCaption("Save");
+		buttonSave.setImmediate(false);
+		buttonSave.setWidth("-1px");
+		buttonSave.setHeight("-1px");
+		mainLayout.addComponent(buttonSave);
+		mainLayout.setComponentAlignment(buttonSave, new Alignment(48));
+		
+		return mainLayout;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/a1d93100/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/EditPDPGroupWindow.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/EditPDPGroupWindow.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/EditPDPGroupWindow.java
new file mode 100644
index 0000000..468634c
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/EditPDPGroupWindow.java
@@ -0,0 +1,521 @@
+/*
+ *  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.view.windows;
+
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+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.api.pap.PAPEngine;
+import org.apache.openaz.xacml.api.pap.PAPException;
+import org.apache.openaz.xacml.api.pap.PDPGroup;
+import org.apache.openaz.xacml.api.pap.PDPPIPConfig;
+import org.apache.openaz.xacml.api.pap.PDPPolicy;
+import org.apache.openaz.xacml.std.pap.StdPDPGroup;
+import org.apache.openaz.xacml.std.pap.StdPDPPolicy;
+import com.vaadin.annotations.AutoGenerated;
+import com.vaadin.data.Validator;
+import com.vaadin.data.Validator.InvalidValueException;
+import com.vaadin.event.Action;
+import com.vaadin.event.Action.Handler;
+import com.vaadin.event.FieldEvents.TextChangeEvent;
+import com.vaadin.event.FieldEvents.TextChangeListener;
+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.Table;
+import com.vaadin.ui.TextArea;
+import com.vaadin.ui.TextField;
+import com.vaadin.ui.UI;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.Window;
+
+public class EditPDPGroupWindow extends Window {
+
+	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */
+
+	@AutoGenerated
+	private VerticalLayout mainLayout;
+	@AutoGenerated
+	private Button buttonSave;
+	@AutoGenerated
+	private Table tablePIP;
+	@AutoGenerated
+	private Table tablePolicies;
+	@AutoGenerated
+	private TextArea textDescription;
+	@AutoGenerated
+	private TextField textName;
+	
+	
+	private static final Action ADD_POLICY = 		new Action ("Add New Policy");
+	private static final Action REMOVE_POLICY = 	new Action ("Remove Policy");
+	private static final Action MAKE_ROOT = 		new Action ("Make Root");
+	private static final Action MAKE_REFERENCED = 	new Action ("Make Referenced");
+	
+	private static final Action EDIT_CONFIG = 		new Action("Edit Configurations");
+
+	//
+	// ?? Why is this static?
+	//
+	private static PDPPolicyContainer policyContainer;
+	private PDPPIPContainer pipContainer;
+	
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+	private final EditPDPGroupWindow self = this;
+	private final StdPDPGroup group;
+	private boolean isSaved = false;
+	
+	// this is the version that contains all of the edits made by the user.
+	// it may be a copy of the original object (edited) or a new one.
+	private StdPDPGroup updatedObject;
+	
+	private PAPEngine papEngine;
+	private List<PDPGroup> groups;
+	
+	/**
+	 * 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 EditPDPGroupWindow(StdPDPGroup group, List<PDPGroup> list, PAPEngine engine) {
+		buildMainLayout();
+		//setCompositionRoot(mainLayout);
+		setContent(mainLayout);
+		//
+		// Save pointers
+		//
+		this.group = group;
+		this.groups = list;
+		this.papEngine = engine;
+		//
+		// Initialize
+		//
+		this.initialize();
+		//
+		// Shortcuts
+		//
+		this.setCloseShortcut(KeyCode.ESCAPE);
+		this.buttonSave.setClickShortcut(KeyCode.ENTER);
+		//
+		// Focus
+		//
+		this.textName.focus();
+	}
+	
+	protected void initialize() {
+		this.initializeText();
+		this.initializeButton();
+		this.initializeTables();
+	}
+	
+	protected void initializeText() {
+		this.textName.setNullRepresentation("");
+		this.textDescription.setNullRepresentation("");
+		if (this.group != null) {
+			this.textName.setValue(this.group.getName());
+			this.textDescription.setValue(this.group.getDescription());
+		}
+		//
+		// Validation
+		//
+		this.textName.addValidator(new Validator() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void validate(Object value) throws InvalidValueException {
+				assert value instanceof String;
+				if (value == null) {
+					throw new InvalidValueException("The name cannot be blank.");
+				}
+				// Group names must be unique so that user can distinguish between them (and we can create unique IDs from them)
+				for (PDPGroup g : self.groups) {
+					if (group != null && g.getId().equals(group.getId())) {
+						// ignore this group - we may or may not be changing the name
+						continue;
+					}
+					if (g.getName().equals(value.toString())) {
+						throw new InvalidValueException("Name must be unique");
+					}
+				}
+			}
+		});
+		this.textName.addTextChangeListener(new TextChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void textChange(TextChangeEvent event) {
+				if (event.getText() == null || event.getText().isEmpty()) {
+					self.buttonSave.setEnabled(false);
+				} else {
+					self.buttonSave.setEnabled(true);
+				}
+			}
+		});
+	}
+	
+	protected void initializeTables() {
+		this.initializePolicyTable();
+		this.initializePIPTable();
+	}
+	
+	protected void initializePolicyTable() {
+		if (this.group == null) {
+			this.tablePolicies.setVisible(false);
+			return;
+		}
+		//
+		// GUI properties
+		//
+		EditPDPGroupWindow.policyContainer = new PDPPolicyContainer(group);
+		this.tablePolicies.setContainerDataSource(EditPDPGroupWindow.policyContainer);
+		this.tablePolicies.setVisibleColumns("Root", "Name", "Version", "Id");//, "Description");
+		this.tablePolicies.setPageLength(EditPDPGroupWindow.policyContainer.size() + 1);
+		this.tablePolicies.setSelectable(true);
+		this.tablePolicies.setSizeFull();
+		/*
+		 * Not in this release.
+		 * 
+		this.tablePolicies.setColumnCollapsingAllowed(true);
+		this.tablePolicies.setColumnCollapsed("Description", true);
+		//
+		// Generated columns
+		//
+		this.tablePolicies.addGeneratedColumn("Description", new ColumnGenerator() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public Object generateCell(Table source, Object itemId, Object columnId) {
+				TextArea area = new TextArea();
+				if (itemId != null && itemId instanceof PDPPolicy) {
+					area.setValue(((PDPPolicy)itemId).getDescription());
+				}
+				area.setNullRepresentation("");
+				area.setWidth("100.0%");
+				return area;
+			}
+		});
+		*/
+		//
+		// Actions
+		//
+		this.tablePolicies.addActionHandler(new Handler() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public Action[] getActions(Object target, Object sender) {
+				if (target == null) {
+					return new Action[] {ADD_POLICY};
+				}
+				return new Action[] {ADD_POLICY, REMOVE_POLICY, MAKE_ROOT, MAKE_REFERENCED};
+			}
+
+			@Override
+			public void handleAction(Action action, Object sender, Object target) {
+				if (action == ADD_POLICY) {
+
+					final SelectWorkspacePoliciesWindow policiesWindow = new SelectWorkspacePoliciesWindow();
+					policiesWindow.setCaption("Select Policy to Add");
+					policiesWindow.setModal(true);
+					policiesWindow.addCloseListener(new CloseListener() {
+						private static final long serialVersionUID = 1L;
+					
+						@Override
+						public void windowClose(CloseEvent event) {
+							//
+							// Did the user hit save?
+							//
+							if (policiesWindow.isSaved() == false) {
+								return;
+							}
+							//
+							// Get the selected policy
+							//
+							StdPDPPolicy selectedPolicy = policiesWindow.getSelectedPolicy();
+							if (selectedPolicy != null) {
+
+								// do not allow multiple copies of same policy
+								for (Object existingPolicy : EditPDPGroupWindow.policyContainer.getItemIds()) {
+									if (selectedPolicy.getId().equals(((PDPPolicy)existingPolicy).getId())) {
+										AdminNotification.warn("Cannot re-add Policy with the same ID (i.e. same Name, source Sub-Domain and Version)");
+										return;
+									}
+								}
+								// copy policy to PAP
+								try {
+									papEngine.copyPolicy(selectedPolicy, self.group);
+								} catch (PAPException e) {
+									AdminNotification.warn("Unable to copy Policy '" + selectedPolicy.getPolicyId() + "' to PAP: " + e.getMessage());
+									return;
+								}
+								
+								// add Policy to group
+								EditPDPGroupWindow.policyContainer.addItem(selectedPolicy);
+								self.markAsDirtyRecursive();								
+							}
+						}
+					});
+					policiesWindow.center();
+					UI.getCurrent().addWindow(policiesWindow);
+					return;
+				}
+				if (action == REMOVE_POLICY) {
+					assert target != null;
+					PDPPolicy policy = (PDPPolicy)target;
+					EditPDPGroupWindow.policyContainer.removeItem(policy);
+					self.markAsDirtyRecursive();
+					return;
+				}
+				if (action == MAKE_ROOT) {
+					assert target != null;
+					assert target instanceof StdPDPPolicy;
+					StdPDPPolicy policy = (StdPDPPolicy)target;
+					EditPDPGroupWindow.policyContainer.getItem(policy).getItemProperty("Root").setValue(true);
+					self.markAsDirtyRecursive();
+					return;
+				}
+				if (action == MAKE_REFERENCED) {
+					assert target != null;
+					assert target instanceof StdPDPPolicy;
+					StdPDPPolicy policy = (StdPDPPolicy)target;
+					EditPDPGroupWindow.policyContainer.getItem(policy).getItemProperty("Root").setValue(false);
+					self.markAsDirtyRecursive();
+					return;
+				}
+				
+				AdminNotification.error("Unrecognized action '" + action + "' on target '" + target + "'");
+			}
+		});
+	}
+	
+	protected void initializePIPTable() {
+		if (this.group == null) {
+			this.tablePIP.setVisible(false);
+			return;
+		}
+		//
+		// Setup data source and GUI properties
+		//
+		this.pipContainer = new PDPPIPContainer(group);
+		this.tablePIP.setContainerDataSource(this.pipContainer);
+		this.tablePIP.setPageLength(this.pipContainer.size() + 2);
+		this.tablePIP.setSelectable(true);
+		this.tablePIP.setSizeFull();
+		//
+		// Add the action handler
+		//
+		this.tablePIP.addActionHandler(new Handler() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public Action[] getActions(Object target, Object sender) {
+				return new Action[] {EDIT_CONFIG};
+			}
+
+			@Override
+			public void handleAction(Action action, Object sender, Object target) {
+				if (action == EDIT_CONFIG) {
+					self.editPIPConfiguration();
+					return;
+				}
+			}
+		});
+	}
+
+	protected void editPIPConfiguration() {
+		final SelectPIPConfigurationWindow window = new SelectPIPConfigurationWindow(this.group);
+		window.setCaption("Select PIP Configurations");
+		window.setModal(true);
+		window.addCloseListener(new CloseListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void windowClose(CloseEvent e) {
+				//
+				// Did the user click save button?
+				//
+				if (window.isSaved() == false) {
+					return;
+				}
+				//
+				// Yes - save the PIP configuration
+				//
+				Set<PDPPIPConfig> configs = window.getSelectedConfigs();
+				assert configs != null;
+				self.group.setPipConfigs(configs);
+				//
+				// Update the container
+				//
+				self.pipContainer.refresh();
+			}
+		});
+		window.center();
+		UI.getCurrent().addWindow(window);
+	}
+
+	protected void initializeButton() {
+		this.buttonSave.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				try {
+					//
+					// Validate
+					//
+					self.textName.commit();
+					//
+					// All good save everything
+					//
+					self.doSave();
+					//
+					// mark ourselves as saved
+					//
+					self.isSaved = true;
+					//
+					// Close the window
+					//
+					self.close();
+				} catch (InvalidValueException e) { //NOPMD
+					//
+					// Ignore, Vaadin will display our message
+					//
+				}
+			}
+		});
+	}
+	
+	protected void doSave() {
+		if (this.group == null) {
+			return;
+		}
+		StdPDPGroup updatedGroupObject = new StdPDPGroup(
+				this.group.getId(), 
+				this.group.isDefaultGroup(), 
+				this.textName.getValue(), 
+				this.textDescription.getValue(), 
+				null);
+		// replace the original set of Policies with the set from the container (possibly modified by the user)
+		Set<PDPPolicy> changedPolicies = new HashSet<PDPPolicy>();
+		changedPolicies.addAll((Collection<PDPPolicy>) EditPDPGroupWindow.policyContainer.getItemIds());
+		updatedGroupObject.setPolicies(changedPolicies);
+		updatedGroupObject.setPdps(this.group.getPdps());
+		// replace the original set of PIP Configs with the set from the container
+//TODO - get PIP Configs from a container used to support editing
+//			selfPDPObject.getPipConfigs().clear();
+//			selfPDPObject.getPipConfigs().addAll(containerGroup.getPipConfigs());
+		updatedGroupObject.setPipConfigs(this.group.getPipConfigs());
+		// copy those things that the user cannot change from the original to the new object
+		updatedGroupObject.setStatus(this.group.getStatus());
+		this.updatedObject = updatedGroupObject;			
+	}
+	
+	public boolean isSaved() {
+		return this.isSaved;
+	}
+	
+	public String getGroupName() {
+		return this.textName.getValue();
+	}
+	
+	public String getGroupDescription() {
+		return this.textDescription.getValue();
+	}
+	
+	public PDPGroup getUpdatedObject() {
+		return this.updatedObject;
+	}
+
+	@AutoGenerated
+	private VerticalLayout buildMainLayout() {
+		// common part: create layout
+		mainLayout = new VerticalLayout();
+		mainLayout.setImmediate(false);
+		mainLayout.setWidth("100.0%");
+		mainLayout.setHeight("-1px");
+		mainLayout.setMargin(true);
+		mainLayout.setSpacing(true);
+		
+		// top-level component properties
+		setWidth("-1px");
+		setHeight("-1px");
+		
+		// textName
+		textName = new TextField();
+		textName.setCaption("Group Name");
+		textName.setImmediate(false);
+		textName.setWidth("-1px");
+		textName.setHeight("-1px");
+		textName.setRequired(true);
+		mainLayout.addComponent(textName);
+		
+		// textDescription
+		textDescription = new TextArea();
+		textDescription.setCaption("Group Description");
+		textDescription.setImmediate(false);
+		textDescription.setWidth("100.0%");
+		textDescription.setHeight("-1px");
+		textDescription.setNullSettingAllowed(true);
+		mainLayout.addComponent(textDescription);
+		mainLayout.setExpandRatio(textDescription, 1.0f);
+		
+		// tablePolicies
+		tablePolicies = new Table();
+		tablePolicies.setCaption("Policies");
+		tablePolicies.setImmediate(false);
+		tablePolicies.setWidth("-1px");
+		tablePolicies.setHeight("-1px");
+		mainLayout.addComponent(tablePolicies);
+		mainLayout.setExpandRatio(tablePolicies, 1.0f);
+		
+		// tablePIP
+		tablePIP = new Table();
+		tablePIP.setCaption("PIP Configurations");
+		tablePIP.setImmediate(false);
+		tablePIP.setWidth("-1px");
+		tablePIP.setHeight("-1px");
+		mainLayout.addComponent(tablePIP);
+		mainLayout.setExpandRatio(tablePIP, 1.0f);
+		
+		// buttonSave
+		buttonSave = new Button();
+		buttonSave.setCaption("Save");
+		buttonSave.setImmediate(true);
+		buttonSave.setWidth("-1px");
+		buttonSave.setHeight("-1px");
+		mainLayout.addComponent(buttonSave);
+		mainLayout.setComponentAlignment(buttonSave, new Alignment(48));
+		
+		return mainLayout;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/a1d93100/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/EditPDPWindow.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/EditPDPWindow.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/EditPDPWindow.java
new file mode 100644
index 0000000..d2c40e9
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/EditPDPWindow.java
@@ -0,0 +1,309 @@
+/*
+ *  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.view.windows;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.List;
+
+import org.apache.openaz.xacml.admin.util.AdminNotification;
+import org.apache.openaz.xacml.api.pap.PDP;
+import org.apache.openaz.xacml.api.pap.PDPGroup;
+import com.vaadin.annotations.AutoGenerated;
+import com.vaadin.data.Buffered.SourceException;
+import com.vaadin.data.Validator;
+import com.vaadin.data.Validator.InvalidValueException;
+import com.vaadin.data.validator.RegexpValidator;
+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.TextArea;
+import com.vaadin.ui.TextField;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.Window;
+
+import elemental.events.KeyboardEvent.KeyCode;
+
+public class EditPDPWindow extends Window {
+
+	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */
+
+	@AutoGenerated
+	private VerticalLayout mainLayout;
+	@AutoGenerated
+	private Button buttonSave;
+	@AutoGenerated
+	private TextArea textDescription;
+	@AutoGenerated
+	private TextField textName;
+	@AutoGenerated
+	private TextField textId;
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+	private final EditPDPWindow self = this;
+	private final PDP pdp;
+	private final List<PDPGroup> groups;
+	private boolean isSaved = false;
+	/**
+	 * 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 pdp 
+	 */
+	public EditPDPWindow(PDP pdp, List<PDPGroup> list) {
+		buildMainLayout();
+		//setCompositionRoot(mainLayout);
+		setContent(mainLayout);
+		//
+		// Save data
+		//
+		this.pdp = pdp;
+		this.groups = list;
+		//
+		// Initialize
+		//
+		this.initializeText();
+		this.initializeButton();
+		//
+		// Keyboard short
+		//
+		this.setCloseShortcut(KeyCode.ESC);
+		this.buttonSave.setClickShortcut(KeyCode.ENTER);
+		//
+		//  Focus
+		//
+		this.textId.focus();
+	}
+	
+	protected void initializeText() {
+		//
+		// Initialize values
+		//
+		if (this.pdp != null) {
+			this.textId.setValue(this.pdp.getId());
+			this.textName.setValue(this.pdp.getName());
+			this.textDescription.setValue(this.pdp.getDescription());
+		}
+		//
+		//
+		//
+		this.textId.setRequiredError("You must enter a valid id for the PDP.");
+		this.textId.setNullRepresentation("");
+		this.textId.addValidator(new RegexpValidator("[\\w=,]", false, "Please enter a valid URL with no whitespace or \"=\" or \",\" characters."));
+		this.textId.addValidator(new Validator() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void validate(Object value) throws InvalidValueException {
+				//
+				// Cannot be null
+				//
+				if (value == null || value.toString().length() == 0) {
+					throw new InvalidValueException("ID cannot be null.");
+				}
+				//
+				// Make sure its a valid URL
+				//
+				try {
+					new URL(value.toString());
+				} catch (MalformedURLException e) {
+					throw new InvalidValueException("The PDP URL '" + value.toString() + "' is not a valid URL: '" + e.getMessage() +"'");
+				}
+			}
+		});
+		//
+		//
+		//
+		this.textName.setNullRepresentation("");
+		this.textName.addValidator(new Validator() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void validate(Object value) throws InvalidValueException {
+				//
+				// If the value is null, set it to the id
+				//
+				if (value == null || value.toString().length() == 0) {
+					return;
+				}
+			}
+		});
+		//
+		//
+		//
+		this.textDescription.setNullRepresentation("");
+	}
+	
+	protected void initializeButton() {
+		this.buttonSave.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				try {
+					//
+					// Do a commit
+					//
+					self.textName.commit();
+					self.textId.commit();
+					self.textDescription.commit();
+					//
+					// Should be a string, but to be safe
+					//
+					String id = self.textId.getValue();
+					String name = self.textName.getValue();
+					if (name == null || name.isEmpty()) {
+						self.textName.setValue(id);
+						name = id;
+					}
+					//
+					// ID must be unique.
+					// Also the Name must be unique AND not match any existing IDs
+					// because user uses the NAME to identify this PDP on the browser window, not the ID.
+					//
+					for (PDPGroup g : self.groups) {
+						for (PDP p : g.getPdps()) {
+							if (p.getId().equals(id)) {
+								if (self.pdp != null) {
+									//
+									// we are editing this pdp
+									//
+									continue;
+								}
+								throw new InvalidValueException("URL must be unique - the PDP '" + id + "' already exists in group '" + g.getName() + "'");
+							}
+							if (id.equals(p.getName())) {
+								throw new InvalidValueException("A previous PDP with URL '" + p.getId() + "' has been given the name '" + id + 
+										"'.  Please edit that PDP to change the name before creating a nwe PDP with this URL.");
+							}
+							if (name != null && name.length() > 0 && self.pdp == null && (p.getId().equals(name) || name.equals(p.getName()))) {
+								throw new InvalidValueException("Name must not be the same as another PDP's name OR another PDP's URL.");
+							}
+						}
+					}
+					//
+					// make sure name is NOT a URL, unless it is identical to the ID.
+					// (If it is a URL, then a later PDP might be created with that URL as it's ID, which would be confusing.)
+					//
+					if ( ! id.equals(name)) {
+						try {
+							new URL(name);
+							// if we get here the name is a URL but not identical to the id, which is not good
+							AdminNotification.warn("The Name must not be a URL unless it is the same as the PDP URL");
+							return;
+						} catch (Exception e) { //NOPMD
+							// ignore - we want to get here
+						}
+					}
+					//
+					// If we get here the inputs are ok
+					//
+					self.isSaved = true;
+					//
+					//
+					//
+					self.close();
+				} catch (SourceException | InvalidValueException e1) { //NOPMD
+					//
+					// Vaadin will display error
+					//
+				}
+			}
+		});
+	}
+	
+	public boolean isSaved() {
+		return this.isSaved;
+	}
+	
+	public String getPDPId() {
+		return this.textId.getValue();
+	}
+	
+	public String getPDPName() {
+		return this.textName.getValue();
+	}
+	
+	public String getPDPDescription() {
+		return this.textDescription.getValue();
+	}
+	
+	@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");
+		
+		// textId
+		textId = new TextField();
+		textId.setCaption("PDP URL");
+		textId.setImmediate(false);
+		textId.setDescription("The URL is the ID of the PDP");
+		textId.setWidth("-1px");
+		textId.setHeight("-1px");
+		textId.setRequired(true);
+		textId.setInputPrompt("Eg. http://localhost:8080/pdp");
+		mainLayout.addComponent(textId);
+		
+		// textName
+		textName = new TextField();
+		textName.setCaption("PDP Name");
+		textName.setImmediate(false);
+		textName.setWidth("-1px");
+		textName.setHeight("-1px");
+		mainLayout.addComponent(textName);
+		
+		// textDescription
+		textDescription = new TextArea();
+		textDescription.setCaption("PDP Description");
+		textDescription.setImmediate(false);
+		textDescription.setWidth("100.0%");
+		textDescription.setHeight("-1px");
+		textDescription.setNullSettingAllowed(true);
+		mainLayout.addComponent(textDescription);
+		mainLayout.setExpandRatio(textDescription, 1.0f);
+		
+		// buttonSave
+		buttonSave = new Button();
+		buttonSave.setCaption("Save");
+		buttonSave.setImmediate(true);
+		buttonSave.setWidth("-1px");
+		buttonSave.setHeight("-1px");
+		mainLayout.addComponent(buttonSave);
+		mainLayout.setComponentAlignment(buttonSave, new Alignment(48));
+		
+		return mainLayout;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/a1d93100/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/ExpressionBuilderComponent.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/ExpressionBuilderComponent.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/ExpressionBuilderComponent.java
new file mode 100644
index 0000000..b231d70
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/ExpressionBuilderComponent.java
@@ -0,0 +1,1078 @@
+/*
+ *  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.view.windows;
+
+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.FunctionType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObjectFactory;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
+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.Attribute;
+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.model.ExpressionContainer;
+import org.apache.openaz.xacml.admin.util.AdminNotification;
+import org.apache.openaz.xacml.admin.util.JPAUtils;
+import org.apache.openaz.xacml.admin.util.XACMLFunctionValidator;
+import org.apache.openaz.xacml.admin.view.events.ApplyParametersChangedListener;
+import org.apache.openaz.xacml.util.XACMLObjectCopy;
+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.ItemClickEvent;
+import com.vaadin.event.ItemClickEvent.ItemClickListener;
+import com.vaadin.event.ShortcutAction.KeyCode;
+import com.vaadin.ui.AbstractSelect.ItemCaptionMode;
+import com.vaadin.ui.AbstractSelect.ItemDescriptionGenerator;
+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.CheckBox;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.TreeTable;
+import com.vaadin.ui.UI;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.Window;
+
+public class ExpressionBuilderComponent extends Window implements ApplyParametersChangedListener {
+	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */
+
+	@AutoGenerated
+	private VerticalLayout mainLayout;
+	@AutoGenerated
+	private Button buttonSave;
+	@AutoGenerated
+	private TreeTable treeExpressions;
+	@AutoGenerated
+	private HorizontalLayout horizontalLayout_1;
+	@AutoGenerated
+	private CheckBox checkBoxShortName;
+	@AutoGenerated
+	private Button buttonClearAll;
+	@AutoGenerated
+	private Button buttonDeleteExpression;
+	@AutoGenerated
+	private Button buttonAddExpression;
+	/*
+	 * 
+	 * 
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+	private static Log logger	= LogFactory.getLog(ExpressionBuilderComponent.class);
+	
+	private static final Action ADD_EXPRESSION = 	new Action ("Add Expression");
+	private static final Action EDIT_EXPRESSION = 	new Action ("Edit Expression");
+	private static final Action DELETE_EXPRESSION = new Action ("Delete Expression");
+	private static final Action ADD_ARGUMENT = 	new Action ("Add Argument");
+	private static final Action EDIT_ARGUMENT = 	new Action ("Edit Argument");
+	private static final Action DELETE_ARGUMENT = new Action ("Delete Argument");
+	
+	private final Object[] visibleColumns = new Object[] {ExpressionContainer.PROPERTY_NAME, ExpressionContainer.PROPERTY_ID, ExpressionContainer.PROPERTY_ID_SHORT, ExpressionContainer.PROPERTY_DATATYPE, ExpressionContainer.PROPERTY_DATATYPE_SHORT};
+	private final String[] columnHeaders = new String[] {"Name", "XCAML ID or Value", "XCAML ID or Value", "Data Type ID", "Data Type ID"};
+	
+	private final ExpressionBuilderComponent self = this;
+	private final Object parent;
+	private final Map<VariableDefinitionType, PolicyType> variables;
+	private final ExpressionContainer container;
+	private boolean isSaved = false;
+	/**
+	 * 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 ExpressionBuilderComponent(Object parent, Object root, FunctionArgument argument, Map<VariableDefinitionType, PolicyType> variables) {
+		buildMainLayout();
+//		setCompositionRoot(mainLayout);
+		setContent(mainLayout);
+		//
+		// Save our data
+		//
+		this.parent = parent;
+		this.variables = variables;
+		this.container = new ExpressionContainer(parent, root, argument);
+		//
+		// Make sure we support the parent object
+		//
+		if (this.isSupported() == false) {
+			throw new IllegalArgumentException("Unsupported object type");
+		}
+		//
+		// Set our shortcuts
+		//
+		this.setCloseShortcut(KeyCode.ESCAPE);
+		//
+		// Finish our GUI initialization
+		//
+		this.initializeTree();
+		this.initializeButtons();
+		this.initializeCheckbox();
+		//
+		// Setup the buttons
+		//
+		this.setupButtons();
+	}
+	
+	private boolean isSupported() {
+		return this.isParentACondition() ||
+					this.isParentAVariable() ||
+					this.isParentAAssignment();
+	}
+	
+	private boolean	isParentACondition() {
+		return this.parent instanceof ConditionType;
+	}
+	
+	private boolean isParentAVariable() {
+		return this.parent instanceof VariableDefinitionType;
+	}
+	
+	private boolean isParentAAssignment() {
+		return this.parent instanceof AttributeAssignmentExpressionType;
+	}
+	
+	private void initializeTree() {
+		//
+		// Initialize GUI properties
+		//
+		this.treeExpressions.setImmediate(true);
+		this.treeExpressions.setSelectable(true);
+		//
+		// Initialize the data source
+		//
+		this.treeExpressions.setContainerDataSource(this.container);
+		this.treeExpressions.setItemCaptionMode(ItemCaptionMode.PROPERTY);
+		this.treeExpressions.setVisibleColumns(this.visibleColumns);
+		this.treeExpressions.setColumnHeaders(this.columnHeaders);
+		this.treeExpressions.setColumnCollapsingAllowed(true);
+		this.treeExpressions.setColumnCollapsed(ExpressionContainer.PROPERTY_ID, true);
+		this.treeExpressions.setColumnCollapsed(ExpressionContainer.PROPERTY_DATATYPE, true);
+		//
+		// Add our action handler
+		//
+		this.treeExpressions.addActionHandler(new Handler() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public Action[] getActions(Object target, Object sender) {
+				if (target == null) {
+					if (self.container.size() == 0) {
+						return new Action[] {ADD_EXPRESSION};
+					}
+					return null;
+				}
+				if (target instanceof ApplyType && XACMLFunctionValidator.canHaveMoreArguments((ApplyType) target)) {
+					return new Action[] {ADD_ARGUMENT, EDIT_EXPRESSION, DELETE_EXPRESSION};
+				}
+				return new Action[] {EDIT_ARGUMENT, DELETE_ARGUMENT};
+			}
+
+			@Override
+			public void handleAction(Action action, Object sender, Object target) {
+				if (action == ADD_EXPRESSION && target == null) {
+					self.addExpression(null, null);
+				}
+				if (action == EDIT_EXPRESSION && target != null) {
+					self.editExpression(target, (ApplyType) self.container.getParent(target), (FunctionArgument) self.container.getArgument(target));
+				}
+				if (action == DELETE_EXPRESSION && target != null) {
+					self.deleteExpression(target);
+				}
+				if (action == ADD_ARGUMENT && target != null && target instanceof ApplyType) {
+					self.addArgument((ApplyType) target);
+				}
+				if (action == EDIT_ARGUMENT && target != null) {
+					self.editExpression(target, (ApplyType) self.container.getParent(target), (FunctionArgument) self.container.getArgument(target));
+				}
+				if (action == DELETE_ARGUMENT && target != null) {
+					self.deleteExpression(target);
+				}
+			}
+		});
+		//
+		// Listen to double-click item selections
+		//
+		this.treeExpressions.addItemClickListener(new ItemClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void itemClick(ItemClickEvent event) {
+				if (event.isDoubleClick()) {
+					Object target = event.getItemId();//self.treeExpressions.getValue();
+					if (target == null) {
+						return;
+					}
+					self.editExpression(target, (ApplyType) self.container.getParent(target), (FunctionArgument) self.container.getArgument(target));
+				}
+			}
+		});
+		//
+		// Listen when the user selects a row
+		//
+		this.treeExpressions.addValueChangeListener(new ValueChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void valueChange(ValueChangeEvent event) {
+				self.setupButtons();
+			}			
+		});
+		//
+		// Listen to when the table contents change
+		//
+		this.treeExpressions.addItemSetChangeListener(new ItemSetChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void containerItemSetChange(ItemSetChangeEvent event) {
+				self.validateExpression();
+			}
+		});
+		//
+		// Expand columns automatically
+		//
+		this.treeExpressions.setColumnExpandRatio(ExpressionContainer.PROPERTY_NAME, 1.0f);
+		this.treeExpressions.setColumnExpandRatio(ExpressionContainer.PROPERTY_ID, 1.0f);
+		this.treeExpressions.setColumnExpandRatio(ExpressionContainer.PROPERTY_DATATYPE, 1.0f);
+		//
+		// Expand all the children
+		//
+		for (Object id : this.treeExpressions.getItemIds()) {
+			this.treeExpressions.setCollapsed(id, false);
+		}
+		//
+		// Have a description generator
+		//
+		this.treeExpressions.setItemDescriptionGenerator(new ItemDescriptionGenerator() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public String generateDescription(Component source, Object itemId, Object propertyId) {
+				if (propertyId != null && propertyId.equals(ExpressionContainer.PROPERTY_NAME) && itemId instanceof ApplyType) {
+					return ((ApplyType) itemId).getDescription();
+				}
+				return null;
+			}
+		});
+	}
+	
+	private void initializeButtons() {
+		this.buttonClearAll.setImmediate(true);
+		this.buttonClearAll.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				self.clearAllExpressions();
+			}
+			
+		});
+		
+		this.buttonAddExpression.setImmediate(true);
+		this.buttonAddExpression.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				Object selected = self.treeExpressions.getValue();
+				if (selected == null) {
+					//
+					// Adding a root expression
+					//
+					self.addExpression(null, null);
+				} else {
+					//
+					// Adding an argument
+					//
+					if (selected instanceof ApplyType) {
+						//
+						// Get the function
+						//
+						self.addArgument((ApplyType) selected);
+					}
+				}
+			}			
+		});
+		
+		this.buttonDeleteExpression.setImmediate(true);
+		this.buttonDeleteExpression.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				Object id = self.treeExpressions.getValue();
+				if (id == null) {
+					logger.error("Delete button clicked on null selection");
+					return;
+				}
+				self.deleteExpression(id);
+			}
+			
+		});
+		
+		this.buttonSave.setImmediate(true);
+		this.buttonSave.setClickShortcut(KeyCode.ENTER);
+		this.buttonSave.setEnabled(false);
+		this.buttonSave.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				//
+				// TODO validate
+				//
+				//
+				// Mark that we are saved
+				//
+				self.isSaved = true;
+				//
+				// Close the window
+				//
+				self.close();
+			}
+		});		
+	}
+	
+	protected void initializeCheckbox() {
+		this.checkBoxShortName.setValue(true);
+		this.checkBoxShortName.setImmediate(true);
+		this.checkBoxShortName.addValueChangeListener(new ValueChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void valueChange(ValueChangeEvent event) {
+				self.treeExpressions.setColumnCollapsed(ExpressionContainer.PROPERTY_ID, self.checkBoxShortName.getValue());
+				self.treeExpressions.setColumnCollapsed(ExpressionContainer.PROPERTY_DATATYPE, self.checkBoxShortName.getValue());
+				self.treeExpressions.setColumnCollapsed(ExpressionContainer.PROPERTY_ID_SHORT, ! self.checkBoxShortName.getValue());
+				self.treeExpressions.setColumnCollapsed(ExpressionContainer.PROPERTY_DATATYPE_SHORT, ! self.checkBoxShortName.getValue());
+			}
+		});
+	}
+	
+	protected void setupButtons() {
+		if (this.treeExpressions.size() == 0) {
+			this.buttonAddExpression.setEnabled(true);
+			this.buttonClearAll.setEnabled(false);
+			this.buttonSave.setEnabled(false);
+		} else {
+			this.validateExpression();
+			this.buttonAddExpression.setEnabled(false);
+			this.buttonClearAll.setEnabled(true);
+		}
+		Object value = this.treeExpressions.getValue();
+		if (value == null) {
+			this.buttonDeleteExpression.setEnabled(false);
+		} else {
+			this.buttonDeleteExpression.setEnabled(true);
+		}
+	}
+	
+	protected void validateExpression() {
+		boolean valid = false;
+		boolean canHaveMore = false;
+		if (this.isParentACondition()) {
+			valid = XACMLFunctionValidator.validateCondition((ConditionType) this.parent);
+			canHaveMore = XACMLFunctionValidator.canHaveMoreArguments((ConditionType) this.parent);
+		} else if (this.isParentAVariable()) {
+			valid = XACMLFunctionValidator.validateVariable((VariableDefinitionType) this.parent);
+			canHaveMore = XACMLFunctionValidator.canHaveMoreArguments((VariableDefinitionType) this.parent);
+		} else if (this.isParentAAssignment()) {
+			valid = XACMLFunctionValidator.validateAssignment((AttributeAssignmentExpressionType)this.parent);
+			canHaveMore = XACMLFunctionValidator.canHaveMoreArguments((AttributeAssignmentExpressionType) this.parent);
+		}
+		if (logger.isDebugEnabled()) {
+			logger.debug("valid: " + valid + " canHaveMore: " + canHaveMore);
+		}
+//		this.buttonAddExpression.setEnabled(canHaveMore);
+		this.buttonSave.setEnabled(valid);
+	}
+	
+	protected void addArgument(final ApplyType parentApply) {
+		//
+		// Get the function
+		//
+		FunctionDefinition function = JPAUtils.findFunction(parentApply.getFunctionId());
+		if (function != null) {
+			FunctionArgument argument = XACMLFunctionValidator.getFunctionArgument(parentApply.getExpression().size() + 1, function);
+			if (logger.isDebugEnabled()) {
+				logger.debug("Add Argument: " + argument);
+			}
+			assert argument != null;
+			//
+			// Is this a high order bag function? And it's data type not defined? (most likely)
+			//
+			if (function.isHigherOrder() && argument.getDatatypeBean() == null) {
+				if (logger.isDebugEnabled()) {
+					logger.debug("isHighOrder and a null datatype bean");
+				}
+				//
+				// Get what the data type restriction should be
+				//
+				try {
+					assert parentApply.getExpression().size() > 0;
+					JAXBElement<?> element = parentApply.getExpression().get(0);
+					assert element != null && element.getValue() != null;
+					Object declaredFunction = element.getValue();
+					assert declaredFunction instanceof FunctionType;
+					FunctionDefinition declaredFunctionDefinition = JPAUtils.findFunction(((FunctionType) declaredFunction).getFunctionId());
+					assert declaredFunctionDefinition != null;
+					if (logger.isDebugEnabled()) {
+						logger.debug("declaredFunction is: " + declaredFunctionDefinition);
+					}
+					FunctionArgument declaredFunctionArgument = XACMLFunctionValidator.getFunctionArgument(parentApply.getExpression().size(), declaredFunctionDefinition);
+					assert declaredFunctionArgument != null;
+					if (logger.isDebugEnabled()) {
+						logger.debug("declaredFunctionArgument is: " + declaredFunctionArgument);
+					}
+					//
+					// Copy the argument
+					//
+					argument = new FunctionArgument(argument);
+					argument.setDatatypeBean(declaredFunctionArgument.getDatatypeBean());
+				} catch (Exception e) {
+					logger.error("Exception while determining parent apply's FunctionType argument datatype.");
+				}
+				
+			}
+			self.addExpression(parentApply, argument);
+		} else {
+			AdminNotification.error("ApplyType does not have a function defined. Please define that first.");
+		}
+
+	}
+
+	protected void addExpression(final ApplyType parentApply, final FunctionArgument argument) {
+		if (logger.isDebugEnabled()) {
+			logger.debug("Adding Expression: " + parentApply + " arg: " + argument);
+		}
+		//
+		// First we need to select what Expression They want
+		//
+		final ExpressionSelectionWindow selector = new ExpressionSelectionWindow(parentApply,
+																		this.isParentAAssignment(),
+																		(argument != null ? argument.isBag() : false),
+																		(argument != null ? ! argument.isBag() : false));
+		selector.setCaption("Select the Expression Type");
+		selector.setModal(true);
+		selector.addCloseListener(new CloseListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void windowClose(CloseEvent e) {
+				//
+				// Was something selected?
+				//
+				String selection = selector.getSelection();
+				if (selection == null) {
+					return;
+				}
+				//
+				// What did the user select?
+				//
+				if (selection.equals(ExpressionSelectionWindow.OPTION_APPLY)) {
+					//
+					self.editApply(new ApplyType(), parentApply, argument);
+					//
+				} else if (selection.equals(ExpressionSelectionWindow.OPTION_DESIGNATOR)) {
+					//
+					self.editAttribute(new AttributeDesignatorType(), parentApply, argument);
+					//
+				} else if (selection.equals(ExpressionSelectionWindow.OPTION_SELECTOR) ) {
+					//
+					self.editAttribute(new AttributeSelectorType(), parentApply, argument);
+					//
+				} else if (selection.equals(ExpressionSelectionWindow.OPTION_VALUE)) {
+					//
+					self.editValue(new AttributeValueType(), parentApply, argument);
+					//
+				} else if (selection.equals(ExpressionSelectionWindow.OPTION_VARIABLE)) {
+					//
+					self.editVariable(new VariableReferenceType(), parentApply, argument);
+					//
+				}
+			}
+		});
+		selector.center();
+		UI.getCurrent().addWindow(selector);
+	}
+
+	protected void editApply(final ApplyType apply, final ApplyType parent, final FunctionArgument argument) {
+		if (logger.isDebugEnabled()) {
+			logger.debug("editApply: " + apply + " parent: " + parent + " :" + argument);
+		}
+		//
+		// Copy the apply and create its window
+		//
+		final ApplyType copyApply = XACMLObjectCopy.copy(apply);
+		final ApplyEditorWindow window = new ApplyEditorWindow(copyApply, parent, argument, self.parent);
+		window.setCaption("Edit The Apply Expression");
+		window.setModal(true);
+		//
+		// Set ourselves as an ApplyParametersChanged listener
+		//
+		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;
+				}
+				//
+				// Copy back the apply
+				//
+				apply.setDescription(copyApply.getDescription());
+				apply.setFunctionId(copyApply.getFunctionId());
+				//
+				// Get the function information
+				//
+				FunctionDefinition function = JPAUtils.findFunction(apply.getFunctionId());
+				assert function != null;
+				//
+				// Is this a new Apply?
+				//
+				if (self.container.containsId(apply)) {
+					//
+					// No - we are updating
+					//
+					self.container.updateItem(apply);
+				} else {
+					//
+					// Is this a higher-order bag function?
+					//
+					if (function.isHigherOrder()) {
+						//
+						// Have the user select a function for it
+						//
+						final FunctionSelectionWindow functionSelection = new FunctionSelectionWindow(null);
+						functionSelection.setCaption("Select Function");
+						functionSelection.setModal(true);
+						functionSelection.addCloseListener(new CloseListener() {
+							private static final long serialVersionUID = 1L;
+
+							@Override
+							public void windowClose(CloseEvent e) {
+								//
+								// Did the user save?
+								//
+								if (functionSelection.isSaved() == false) {
+									return;
+								}
+								//
+								// Get the function
+								//
+								String function = functionSelection.getSelectedFunction();
+								if (function == null || function.isEmpty()) {
+									logger.error("Function window said it was saved, but there was no function.");
+									return;
+								}
+								//
+								// Create the function object
+								//
+								FunctionType hoFunction = new FunctionType();
+								hoFunction.setFunctionId(function);
+								//
+								// Add it into the apply
+								//
+								apply.getExpression().add(new ObjectFactory().createFunction(hoFunction));
+								//
+								// New Item
+								//
+								Item item = self.container.addItem(apply, parent, argument);
+								assert item != null;
+								self.treeExpressions.setCollapsed(apply, false);
+								self.treeExpressions.select(apply);
+							}
+						});
+						functionSelection.center();
+						UI.getCurrent().addWindow(functionSelection);
+					} else {
+						//
+						// New Item
+						//
+						Item item = self.container.addItem(apply, parent, argument);
+						assert item != null;
+						self.treeExpressions.setCollapsed(apply, false);
+						self.treeExpressions.select(apply);
+					}
+				}
+			}
+		});
+		window.center();
+		UI.getCurrent().addWindow(window);
+	}
+	
+	protected void editAttribute(final Object target, final ApplyType parent, final FunctionArgument argument) {
+		if (logger.isDebugEnabled()) {
+			logger.debug("editAttribute: " + target + " parent: " + parent + " :" + argument);
+		}
+		//
+		// Determine what the data type needs to be
+		//
+		Datatype datatype = null;
+		if (parent == null && this.isParentACondition()) {
+			datatype = JPAUtils.getBooleanDatatype();
+		} else {
+			if (argument != null) {
+				datatype = argument.getDatatypeBean();
+			}
+		}
+		//
+		// Copy the attribute
+		//
+		final Object copyAttribute = XACMLObjectCopy.deepCopy(target);
+		//
+		// Create the window
+		//
+		final AttributeSelectionWindow window = new AttributeSelectionWindow(datatype, copyAttribute);
+		if (target instanceof AttributeDesignatorType) {
+			window.setCaption("Edit Designator " + (((AttributeDesignatorType) target).getAttributeId() != null ? ((AttributeDesignatorType) target).getAttributeId() : ""));
+		} else {
+			window.setCaption("Edit Selector " + (((AttributeSelectorType) target).getContextSelectorId() != null ? ((AttributeSelectorType) target).getContextSelectorId() : ""));
+		}
+		window.setModal(true);
+		window.addCloseListener(new CloseListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void windowClose(CloseEvent e) {
+				//
+				// Did the user hit save?
+				//
+				if (window.isSaved() == false) {
+					return;
+				}
+				//
+				// Grab the attribute
+				//
+				Attribute attribute = window.getAttribute();
+				if (attribute == null) {
+					return;
+				}
+				//
+				// Save it back into the original
+				//
+				if (target instanceof AttributeDesignatorType) {
+					((AttributeDesignatorType)target).setAttributeId(attribute.getXacmlId());
+					((AttributeDesignatorType)target).setCategory(attribute.getCategoryBean().getXacmlId());
+					((AttributeDesignatorType)target).setDataType(attribute.getDatatypeBean().getXacmlId());
+					((AttributeDesignatorType)target).setIssuer(attribute.getIssuer());
+					((AttributeDesignatorType)target).setMustBePresent(attribute.isMustBePresent());
+				} else {
+					((AttributeSelectorType)target).setContextSelectorId(attribute.getXacmlId());
+					((AttributeSelectorType)target).setCategory(attribute.getCategoryBean().getXacmlId());
+					((AttributeSelectorType)target).setDataType(attribute.getDatatypeBean().getXacmlId());
+					((AttributeSelectorType)target).setPath(attribute.getSelectorPath());
+					((AttributeSelectorType)target).setMustBePresent(attribute.isMustBePresent());
+				}
+				//
+				// Is this a new item?
+				//
+				if (self.container.containsId(target)) {
+					//
+					// No, just update the container
+					//
+					self.container.updateItem(target);
+				} else {
+					//
+					// Yes a new item, add it in
+					//
+					//assert(self.container.addItem(JPAUtils.createDesignator(attribute), parent, argument) != null);
+					Item item = self.container.addItem(target, parent, argument);
+					assert item != null;
+					self.treeExpressions.select(target);
+				}
+			}
+		});
+		window.center();
+		UI.getCurrent().addWindow(window);
+	}
+
+	protected void editValue(final AttributeValueType value, final ApplyType parent, final FunctionArgument argument) {
+		if (logger.isDebugEnabled()) {
+			logger.debug("editvalue: " + value + " parent: " + parent + " :" + argument);
+		}
+		//
+		// Copy the attribute value
+		//
+		final AttributeValueType copyValue = XACMLObjectCopy.copy(value);
+		//
+		// Get what the datatype should be
+		//
+		Datatype datatypeRestriction = null;
+		//
+		// Is this a root?
+		//
+		if (parent == null) {
+			//
+			// Check if our parent container is a condition
+			//
+			if (self.isParentACondition()) {
+				//
+				// We are only allowed to return boolean's
+				//
+				datatypeRestriction = JPAUtils.getBooleanDatatype();
+			}
+		} else {
+			//
+			// Are we an argument?
+			//
+			if (argument != null) {
+				//
+				// Yes - we are restricted to that argument's datatype
+				//
+				datatypeRestriction = argument.getDatatypeBean();
+			}
+		}
+		//
+		// Create the window
+		//
+		final AttributeValueEditorWindow window = new AttributeValueEditorWindow(copyValue, datatypeRestriction);
+		window.setCaption("Edit Attribute Value");
+		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;
+				}
+				//
+				// Yes - get the value
+				//
+				value.getContent().clear();
+				for (Object o : copyValue.getContent()) {
+					value.getContent().add(o);
+				}
+				value.setDataType(copyValue.getDataType());
+				//
+				// Was this a new value?
+				//
+				if (self.container.containsId(value)) {
+					//
+					// No - update it
+					//
+					self.container.updateItem(value);
+				} else {
+					//
+					// Yes - add it in
+					//
+					Item item = self.container.addItem(value, parent, argument);
+					assert item != null;
+				}
+			}
+		});
+		window.center();
+		UI.getCurrent().addWindow(window);
+	}
+
+	protected void editVariable(final VariableReferenceType variable, final ApplyType parent, final FunctionArgument argument) {
+		if (logger.isDebugEnabled()) {
+			logger.debug("editVariable: " + variable + " parent: " + parent + " :" + argument);
+		}
+		//
+		// Copy the variable
+		//
+		final VariableReferenceType copyVariable = XACMLObjectCopy.copy(variable);
+		//
+		// Create the window
+		//
+		final VariableReferenceEditorWindow window = new VariableReferenceEditorWindow(copyVariable, this.variables);
+		window.setCaption("Edit Variable Reference");
+		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;
+				}
+				//
+				// Copy the variable changes back
+				//
+				variable.setVariableId(copyVariable.getVariableId());
+				//
+				// Is this a new one?
+				//
+				if (self.container.containsId(variable)) {
+					//
+					// No - update it
+					//
+					self.container.updateItem(variable);
+				} else {
+					//
+					// Yes - add it
+					//
+					Item item = self.container.addItem(variable, parent, argument);
+					assert item != null;
+				}
+			}
+		});
+		window.center();
+		UI.getCurrent().addWindow(window);
+	}
+	
+	protected void editFunction(final FunctionType func, final ApplyType parent, final FunctionArgument argument) {
+		if (logger.isDebugEnabled()) {
+			logger.debug("editFunction: " + func + " parent: " + parent + " :" + argument);
+		}
+
+		final FunctionSelectionWindow functionSelection = new FunctionSelectionWindow((func != null ? func.getFunctionId() : null));
+		functionSelection.setCaption("Edit Function");
+		functionSelection.setModal(true);
+		functionSelection.addCloseListener(new CloseListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void windowClose(CloseEvent e) {
+				//
+				// Did the user save?
+				//
+				if (functionSelection.isSaved() == false) {
+					return;
+				}
+				//
+				// Get the function
+				//
+				String function = functionSelection.getSelectedFunction();
+				if (function == null || function.isEmpty()) {
+					logger.error("Function window said it was saved, but there was no function.");
+					return;
+				}
+				//
+				// New one?
+				//
+				if (func == null) {
+					//
+					// Create the function object
+					//
+					FunctionType hoFunction = new FunctionType();
+					hoFunction.setFunctionId(function);
+					//
+					// Add it into the apply
+					//
+					assert parent.getExpression().size() == 0;
+					parent.getExpression().add(new ObjectFactory().createFunction(hoFunction));
+					//
+					// New Item
+					//
+					Item item = self.container.addItem(func, parent, argument);
+					assert item != null;
+					self.treeExpressions.setCollapsed(parent, false);
+					self.treeExpressions.select(func);
+				} else {
+					//
+					// Editing an existing
+					//
+					func.setFunctionId(function);
+					self.container.updateItem(func);
+					//
+					// Warn user
+					//
+					if (parent.getExpression().size() > 1) {
+						AdminNotification.warn("You have updated the function ID. The rest of the arguments may be invalid for the function. Please verify the other arguments.");
+					}
+				}
+			}
+		});
+		functionSelection.center();
+		UI.getCurrent().addWindow(functionSelection);
+	}
+	
+	protected void editExpression(final Object target, final ApplyType parent, final FunctionArgument argument) {
+		if (target instanceof ApplyType) {
+			//
+			this.editApply((ApplyType) target, parent, argument);
+			//
+		} else if (target instanceof AttributeValueType) {
+			//
+			this.editValue((AttributeValueType) target,parent, argument);
+			//
+		} else if (target instanceof AttributeDesignatorType || target instanceof AttributeSelectorType) {
+			//
+			this.editAttribute(target, parent, argument);
+			//
+		} else if (target instanceof VariableReferenceType) {
+			//
+			this.editVariable((VariableReferenceType) target, parent, argument);
+			//
+		} else if (target instanceof FunctionType) {
+			//
+			this.editFunction((FunctionType) target, parent, argument);
+			//
+		}
+	}
+
+	protected void deleteExpression(Object target) {
+		if (this.container.isRoot(target)) {
+			if (this.treeExpressions.removeAllItems() == false) {
+				logger.error("Failed to remove everything.");
+			}
+		} else {
+			if (this.treeExpressions.removeItem(target) == false) {
+				logger.error("Failed to remove " + target);
+			}
+		}
+		this.setupButtons();
+	}
+	
+	protected void clearAllExpressions() {
+		if (this.treeExpressions.removeAllItems() == false) {
+			logger.error("Failed to remove everything.");
+		}
+		this.setupButtons();
+	}
+		
+	@Override
+	public void applyParameterChanged(ApplyType apply, ApplyType parent, FunctionArgument argument, Object container) {
+		logger.info("applyParameterChanged: " + apply + " " + parent + " " + argument + " " + container);
+		//
+		// TODO - figure out if this something being edited, or a new one
+		//
+	}
+	
+	public boolean isSaved() {
+		return this.isSaved;
+	}
+
+	@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("-1px");
+		setHeight("-1px");
+		
+		// horizontalLayout_1
+		horizontalLayout_1 = buildHorizontalLayout_1();
+		mainLayout.addComponent(horizontalLayout_1);
+		mainLayout.setExpandRatio(horizontalLayout_1, 1.0f);
+		
+		// treeExpressions
+		treeExpressions = new TreeTable();
+		treeExpressions.setImmediate(false);
+		treeExpressions.setWidth("100.0%");
+		treeExpressions.setHeight("-1px");
+		mainLayout.addComponent(treeExpressions);
+		mainLayout.setExpandRatio(treeExpressions, 1.0f);
+		
+		// buttonSave
+		buttonSave = new Button();
+		buttonSave.setCaption("Save");
+		buttonSave.setImmediate(true);
+		buttonSave.setWidth("-1px");
+		buttonSave.setHeight("-1px");
+		mainLayout.addComponent(buttonSave);
+		mainLayout.setComponentAlignment(buttonSave, 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("-1px");
+		horizontalLayout_1.setHeight("-1px");
+		horizontalLayout_1.setMargin(false);
+		horizontalLayout_1.setSpacing(true);
+		
+		// buttonAddExpression
+		buttonAddExpression = new Button();
+		buttonAddExpression.setCaption("Add Expression");
+		buttonAddExpression.setImmediate(true);
+		buttonAddExpression.setWidth("-1px");
+		buttonAddExpression.setHeight("-1px");
+		horizontalLayout_1.addComponent(buttonAddExpression);
+		
+		// buttonDeleteExpression
+		buttonDeleteExpression = new Button();
+		buttonDeleteExpression.setCaption("Delete Expression");
+		buttonDeleteExpression.setImmediate(true);
+		buttonDeleteExpression.setWidth("-1px");
+		buttonDeleteExpression.setHeight("-1px");
+		horizontalLayout_1.addComponent(buttonDeleteExpression);
+		
+		// buttonClearAll
+		buttonClearAll = new Button();
+		buttonClearAll.setCaption("Clear All");
+		buttonClearAll.setImmediate(true);
+		buttonClearAll.setDescription("Clears all the expressions.");
+		buttonClearAll.setWidth("-1px");
+		buttonClearAll.setHeight("-1px");
+		horizontalLayout_1.addComponent(buttonClearAll);
+		
+		// checkBoxShortName
+		checkBoxShortName = new CheckBox();
+		checkBoxShortName.setCaption("Display Short XACML ID's");
+		checkBoxShortName.setImmediate(false);
+		checkBoxShortName
+				.setDescription("If checked, the right-most string of the function and datatype URI's will only be displayed.");
+		checkBoxShortName.setWidth("-1px");
+		checkBoxShortName.setHeight("-1px");
+		horizontalLayout_1.addComponent(checkBoxShortName);
+		
+		return horizontalLayout_1;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/a1d93100/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/ExpressionEditorWindow.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/ExpressionEditorWindow.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/ExpressionEditorWindow.java
new file mode 100644
index 0000000..0ee6eea
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/ExpressionEditorWindow.java
@@ -0,0 +1,90 @@
+/*
+ *  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.view.windows;
+
+import com.vaadin.annotations.AutoGenerated;
+import com.vaadin.ui.ComboBox;
+import com.vaadin.ui.Tree;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.Window;
+
+public class ExpressionEditorWindow extends Window {
+
+	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */
+
+	@AutoGenerated
+	private VerticalLayout mainLayout;
+	@AutoGenerated
+	private Tree treeExpression;
+	@AutoGenerated
+	private ComboBox comboBox;
+	/**
+	 * 
+	 */
+	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 ExpressionEditorWindow() {
+		buildMainLayout();
+		//setCompositionRoot(mainLayout);
+		setContent(mainLayout);
+
+		// TODO add user code here
+	}
+
+	@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");
+		
+		// comboBox
+		comboBox = new ComboBox();
+		comboBox.setImmediate(false);
+		comboBox.setWidth("-1px");
+		comboBox.setHeight("-1px");
+		mainLayout.addComponent(comboBox);
+		
+		// treeExpression
+		treeExpression = new Tree();
+		treeExpression.setImmediate(false);
+		treeExpression.setWidth("100.0%");
+		treeExpression.setHeight("-1px");
+		mainLayout.addComponent(treeExpression);
+		mainLayout.setExpandRatio(treeExpression, 1.0f);
+		
+		return mainLayout;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/a1d93100/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/ExpressionSelectionWindow.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/ExpressionSelectionWindow.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/ExpressionSelectionWindow.java
new file mode 100644
index 0000000..d7bfeb0
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/ExpressionSelectionWindow.java
@@ -0,0 +1,170 @@
+/*
+ *  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.view.windows;
+
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.ApplyType;
+
+import com.vaadin.annotations.AutoGenerated;
+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.OptionGroup;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.Window;
+
+public class ExpressionSelectionWindow extends Window {
+
+	public static String	OPTION_APPLY = "Apply";
+	public static String	OPTION_VALUE = "Attribute Value";
+	public static String	OPTION_DESIGNATOR = "Attribute Designator";
+	public static String	OPTION_SELECTOR = "Attribute Selector";
+	public static String	OPTION_VARIABLE = "Variable Reference";
+	
+	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */
+
+	@AutoGenerated
+	private VerticalLayout mainLayout;
+	@AutoGenerated
+	private Button buttonSave;
+	@AutoGenerated
+	private OptionGroup optionGroupExpression;
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+	private final ExpressionSelectionWindow self = this;
+	boolean isSaved = false;
+	String selection = 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.
+	 * @param parentApply 
+	 */
+	// TODO - Refactor.  Unused formal parameter parentApply.  Either determine
+	// whether this is unnecessary and remove it (including removing it from all 
+	// constructor consumers), or use it.
+	// NOTE: parentApply was originally used by passing to private initializeOption method.
+	//       However, the parameter was unused by that method also.
+	//       Setting to NOPMD for now.
+	public ExpressionSelectionWindow(ApplyType parentApply, boolean isAttributeAssignment, boolean mustBeBag, boolean mustBeValue) { //NOPMD
+		buildMainLayout();
+		//setCompositionRoot(mainLayout);
+		setContent(mainLayout);
+		//
+		// Set our shortcuts
+		//
+		this.setCloseShortcut(KeyCode.ESCAPE);
+		//
+		// Finish GUI initialization
+		//
+		// this.initializeOption(parentApply, isAttributeAssignment, mustBeBag, mustBeValue);
+		this.initializeOption(isAttributeAssignment, mustBeBag, mustBeValue);
+		this.initializeButtons();
+	}
+	
+	// private void initializeOption(ApplyType parentApply, boolean isAttributeAssignment, boolean mustBeBag, boolean mustBeValue) {
+	private void initializeOption(boolean isAttributeAssignment, boolean mustBeBag, boolean mustBeValue) {
+//		if (!isAttributeAssignment) {
+			this.optionGroupExpression.addItem(OPTION_APPLY);
+//		}
+		if (!mustBeBag || mustBeValue) {
+			this.optionGroupExpression.addItem(OPTION_VALUE);
+		}
+		if (mustBeBag || !mustBeValue) {
+			this.optionGroupExpression.addItem(OPTION_DESIGNATOR);
+			this.optionGroupExpression.addItem(OPTION_SELECTOR);
+		}
+		this.optionGroupExpression.addItem(OPTION_VARIABLE);
+		//
+		// Default Selection
+		//
+		if (!isAttributeAssignment) {
+			this.optionGroupExpression.select(OPTION_APPLY);
+		} else {
+			if (!mustBeBag || mustBeValue) {
+				this.optionGroupExpression.select(OPTION_VALUE);
+			} else {
+				this.optionGroupExpression.select(OPTION_DESIGNATOR);
+			}
+		}
+	}
+	
+	private void initializeButtons() {
+		this.buttonSave.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				self.isSaved = true;
+				self.selection = self.optionGroupExpression.getValue().toString();
+				self.close();
+			}			
+		});
+	}
+	
+	public String	getSelection() {
+		if (this.isSaved == false) {
+			return null;
+		}
+		return this.selection;
+	}
+
+	@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");
+		
+		// optionGroupExpression
+		optionGroupExpression = new OptionGroup();
+		optionGroupExpression
+				.setCaption("Select One Of The Following Types of Expressions");
+		optionGroupExpression.setImmediate(false);
+		optionGroupExpression.setWidth("-1px");
+		optionGroupExpression.setHeight("-1px");
+		mainLayout.addComponent(optionGroupExpression);
+		
+		// buttonSave
+		buttonSave = new Button();
+		buttonSave.setCaption("Select");
+		buttonSave.setImmediate(false);
+		buttonSave.setWidth("-1px");
+		buttonSave.setHeight("-1px");
+		mainLayout.addComponent(buttonSave);
+		mainLayout.setComponentAlignment(buttonSave, new Alignment(24));
+		
+		return mainLayout;
+	}
+
+}