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:42 UTC

[03/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/PolicyNameEditorWindow.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/PolicyNameEditorWindow.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/PolicyNameEditorWindow.java
new file mode 100644
index 0000000..73149cc
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/PolicyNameEditorWindow.java
@@ -0,0 +1,369 @@
+/*
+ *  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.PolicySetType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.TargetType;
+
+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.jpa.PolicyAlgorithms;
+import org.apache.openaz.xacml.admin.jpa.RuleAlgorithms;
+import org.apache.openaz.xacml.api.XACML3;
+import com.vaadin.addon.jpacontainer.JPAContainer;
+import com.vaadin.addon.jpacontainer.JPAContainerItem;
+import com.vaadin.annotations.AutoGenerated;
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.data.Property.ValueChangeListener;
+import com.vaadin.data.Validator;
+import com.vaadin.event.ShortcutAction.KeyCode;
+import com.vaadin.ui.AbstractSelect.ItemCaptionMode;
+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.FormLayout;
+import com.vaadin.ui.OptionGroup;
+import com.vaadin.ui.TextArea;
+import com.vaadin.ui.TextField;
+import com.vaadin.ui.Window;
+
+public class PolicyNameEditorWindow extends Window {
+
+	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */
+
+	private static final long serialVersionUID = 1L;
+	private static final Log logger	= LogFactory.getLog(PolicyNameEditorWindow.class);
+	private final PolicyNameEditorWindow self = this;
+	private Object data = null;
+	private String filename = null;
+	private boolean isSaved = false;
+	
+	@AutoGenerated
+	private FormLayout mainLayout;
+	@AutoGenerated
+	private ComboBox comboAlgorithms;
+	@AutoGenerated
+	private OptionGroup optionPolicySet;
+	@AutoGenerated
+	private TextArea textAreaDescription;
+	@AutoGenerated
+	private TextField textFieldPolicyName;
+	@AutoGenerated
+	private Button buttonSave;
+	
+	JPAContainer<PolicyAlgorithms> policyAlgorithms;
+	JPAContainer<RuleAlgorithms> ruleAlgorithms;
+	
+	/**
+	 * 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 PolicyNameEditorWindow(String filename, Object policyData, JPAContainer<PolicyAlgorithms> policyAlgs, JPAContainer<RuleAlgorithms> ruleAlgs) {
+		buildMainLayout();
+		setContent(mainLayout);
+		
+		this.mainLayout.setMargin(true);
+
+		this.filename = filename;
+		this.data = policyData;
+		this.policyAlgorithms = policyAlgs;
+		this.ruleAlgorithms = ruleAlgs;
+		
+		this.optionPolicySet.addItem("Policy Set");
+		this.optionPolicySet.addItem("Policy");
+
+		this.comboAlgorithms.setNewItemsAllowed(false);
+		this.comboAlgorithms.setNullSelectionAllowed(false);
+		this.comboAlgorithms.setItemCaptionMode(ItemCaptionMode.PROPERTY);
+		this.comboAlgorithms.setItemCaptionPropertyId("xacmlId");
+		//
+		// Setup the policy filename
+		//
+		this.textFieldPolicyName.setImmediate(true);
+		this.textFieldPolicyName.setNullRepresentation("");
+		if (filename != null) {
+			this.textFieldPolicyName.setValue(filename);
+		}
+		this.textFieldPolicyName.addValidator(new Validator() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void validate(Object value) throws InvalidValueException {
+				if (value instanceof String) {
+					String filename = (String) value;
+					if (filename.endsWith(".xml")) {
+						filename = filename.substring(0, filename.length() - 4);
+					}
+					if (filename.length() == 0) {
+						throw new InvalidValueException("Invalid filename.");
+					}
+					if (filename.indexOf('.') != -1) {
+						throw new InvalidValueException("Please do not use a \'.\' in the filename.");
+					}
+				}
+			}
+			
+		});
+		this.textFieldPolicyName.setValidationVisible(true);
+		//
+		// Are we editing or creating?
+		//
+		if (this.data != null) {
+			//
+			// We are editing
+			//
+			if (this.data instanceof PolicySetType) {
+				this.optionPolicySet.setValue("Policy Set");
+				this.optionPolicySet.setVisible(false);
+				this.textAreaDescription.setValue(((PolicySetType)this.data).getDescription());
+				this.comboAlgorithms.setContainerDataSource(policyAlgs);
+				for (Object object : this.policyAlgorithms.getItemIds()) {
+					PolicyAlgorithms a = (PolicyAlgorithms) this.policyAlgorithms.getItem(object).getEntity();
+					if (a.getXacmlId().equals(((PolicySetType)this.data).getPolicyCombiningAlgId())) {
+						this.comboAlgorithms.select(object);
+						break;
+					}
+				}
+			}
+			if (this.data instanceof PolicyType) {
+				this.optionPolicySet.setValue("Policy");
+				this.optionPolicySet.setVisible(false);
+				this.textAreaDescription.setValue(((PolicyType)this.data).getDescription());
+				this.comboAlgorithms.setContainerDataSource(ruleAlgs);
+				for (Object object : this.ruleAlgorithms.getItemIds()) {
+					RuleAlgorithms a = (RuleAlgorithms) this.ruleAlgorithms.getItem(object).getEntity();
+					if (a.getXacmlId().equals(((PolicyType)this.data).getRuleCombiningAlgId())) {
+						this.comboAlgorithms.select(object);
+						break;
+					}
+				}
+			}
+		} else {
+			//
+			// Creating a new policy
+			//
+			this.optionPolicySet.setValue("Policy Set");
+			this.comboAlgorithms.setContainerDataSource(policyAlgs);
+			this.comboAlgorithms.setItemCaptionMode(ItemCaptionMode.PROPERTY);
+			this.comboAlgorithms.setItemCaptionPropertyId("xacmlId");
+			for (Object object : this.policyAlgorithms.getItemIds()) {
+				PolicyAlgorithms a = (PolicyAlgorithms) this.policyAlgorithms.getItem(object).getEntity();
+				if (a.getXacmlId().equals(XACML3.ID_POLICY_FIRST_APPLICABLE.stringValue())) {
+					this.comboAlgorithms.select(object);
+					break;
+				}
+			}
+			
+			this.optionPolicySet.addValueChangeListener(new ValueChangeListener() {
+				private static final long serialVersionUID = 1L;
+
+				@Override
+				public void valueChange(ValueChangeEvent event) {
+					if (self.optionPolicySet.getValue().toString().equals("Policy Set")) {
+						self.comboAlgorithms.setContainerDataSource(self.policyAlgorithms);
+						for (Object object : self.policyAlgorithms.getItemIds()) {
+							PolicyAlgorithms a = (PolicyAlgorithms) self.policyAlgorithms.getItem(object).getEntity();
+							if (a.getXacmlId().equals(XACML3.ID_POLICY_FIRST_APPLICABLE.stringValue())) {
+								self.comboAlgorithms.select(object);
+								break;
+							}
+						}
+					} else if (self.optionPolicySet.getValue().toString().equals("Policy")) {
+						self.comboAlgorithms.setContainerDataSource(self.ruleAlgorithms);
+						for (Object object : self.ruleAlgorithms.getItemIds()) {
+							RuleAlgorithms a = (RuleAlgorithms) self.ruleAlgorithms.getItem(object).getEntity();
+							if (a.getXacmlId().equals(XACML3.ID_RULE_FIRST_APPLICABLE.stringValue())) {
+								self.comboAlgorithms.select(object);
+								break;
+							}
+						}
+					}					
+				}
+				
+			});
+		}
+
+		this.buttonSave.setClickShortcut(KeyCode.ENTER);
+		
+		this.buttonSave.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				//
+				// Make sure the policy filename was valid
+				//
+				if (self.textFieldPolicyName.isValid() == false) {
+					return;
+				}
+				//
+				// Grab the filename (NOTE: The user may or may not
+				// have changed the name).
+				//
+				self.filename = self.textFieldPolicyName.getValue();
+				//
+				// Make sure the filename ends with an extension
+				//
+				if (self.filename.endsWith(".xml") == false) {
+					self.filename = self.filename + ".xml";
+				}
+				//
+				// Set ourselves as saved
+				//
+				self.isSaved = true;
+				//
+				// Now grab the policy file's data
+				//
+				if (self.data == null) {
+					//
+					// This is a brand new Policy
+					//
+					if (self.optionPolicySet.getValue().toString().equals("Policy Set")) {
+						PolicySetType policySet = new PolicySetType();
+						policySet.setVersion("1");
+						policySet.setPolicySetId(((XacmlAdminUI)getUI()).newPolicyID());
+						policySet.setTarget(new TargetType());
+						self.data = policySet;
+					} else if (self.optionPolicySet.getValue().toString().equals("Policy")) {
+						PolicyType policy = new PolicyType();
+						policy.setVersion("1");
+						policy.setPolicyId(((XacmlAdminUI)getUI()).newPolicyID());
+						policy.setTarget(new TargetType());
+						self.data = policy;
+					} else {
+						logger.error("Policy option NOT setup correctly.");
+					}
+				}
+				if (self.data != null) {
+					//
+					// Save off everything
+					//
+					if (self.data instanceof PolicySetType) {
+						((PolicySetType)self.data).setDescription(self.textAreaDescription.getValue());
+						Object a = self.comboAlgorithms.getValue();
+						PolicyAlgorithms alg = (PolicyAlgorithms) ((JPAContainerItem<?>)self.comboAlgorithms.getItem(a)).getEntity();
+						((PolicySetType)self.data).setPolicyCombiningAlgId(alg.getXacmlId());
+					} else if (self.data instanceof PolicyType) {
+						((PolicyType)self.data).setDescription(self.textAreaDescription.getValue());
+						Object a = self.comboAlgorithms.getValue();
+						RuleAlgorithms alg = (RuleAlgorithms) ((JPAContainerItem<?>)self.comboAlgorithms.getItem(a)).getEntity();
+						((PolicyType)self.data).setRuleCombiningAlgId(alg.getXacmlId());
+					} else {
+						logger.error("Unsupported data object." + self.data.getClass().getCanonicalName());
+					}
+				}
+				//
+				// Now we can close the window
+				//
+				self.close();
+			}
+		});
+		
+		this.textFieldPolicyName.focus();
+	}
+	
+	public boolean isSaved() {
+		return this.isSaved;
+	}
+	
+	public Object getPolicyData() {
+		if (this.isSaved) {
+			return this.data;
+		}
+		return null;
+	}
+	
+	public String getPolicyFilename() {
+		if (this.isSaved) {
+			return this.filename;
+		}
+		return null;
+	}
+
+	@AutoGenerated
+	private FormLayout buildMainLayout() {
+		// common part: create layout
+		mainLayout = new FormLayout();
+		mainLayout.setImmediate(false);
+		
+		// textFieldPolicyName
+		textFieldPolicyName = new TextField();
+		textFieldPolicyName.setCaption("Policy File Name");
+		textFieldPolicyName.setImmediate(true);
+		textFieldPolicyName.setWidth("-1px");
+		textFieldPolicyName.setHeight("-1px");
+		textFieldPolicyName.setInputPrompt("Enter filename eg. foobar.xml");
+		textFieldPolicyName.setRequired(true);
+		mainLayout.addComponent(textFieldPolicyName);
+		
+		// textAreaDescription
+		textAreaDescription = new TextArea();
+		textAreaDescription.setCaption("Description");
+		textAreaDescription.setImmediate(false);
+		textAreaDescription.setWidth("100%");
+		textAreaDescription.setHeight("-1px");
+		textAreaDescription
+				.setInputPrompt("Enter a description for the Policy/PolicySet.");
+		textAreaDescription.setNullSettingAllowed(true);
+		mainLayout.addComponent(textAreaDescription);
+		
+		// optionPolicySet
+		optionPolicySet = new OptionGroup();
+		optionPolicySet.setCaption("Policy or PolicySet?");
+		optionPolicySet.setImmediate(true);
+		optionPolicySet
+				.setDescription("Is the root level a Policy or Policy Set.");
+		optionPolicySet.setWidth("-1px");
+		optionPolicySet.setHeight("-1px");
+		optionPolicySet.setRequired(true);
+		mainLayout.addComponent(optionPolicySet);
+		
+		// comboAlgorithms
+		comboAlgorithms = new ComboBox();
+		comboAlgorithms.setCaption("Combining Algorithm");
+		comboAlgorithms.setImmediate(false);
+		comboAlgorithms.setDescription("Select the combining algorithm.");
+		comboAlgorithms.setWidth("-1px");
+		comboAlgorithms.setHeight("-1px");
+		comboAlgorithms.setRequired(true);
+		mainLayout.addComponent(comboAlgorithms);
+		
+		// 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/PolicySetEditorWindow.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/PolicySetEditorWindow.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/PolicySetEditorWindow.java
new file mode 100644
index 0000000..af2ae20
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/PolicySetEditorWindow.java
@@ -0,0 +1,252 @@
+/*
+ *  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.PolicySetType;
+
+import org.apache.openaz.xacml.admin.XacmlAdminUI;
+import org.apache.openaz.xacml.admin.jpa.PolicyAlgorithms;
+import org.apache.openaz.xacml.admin.util.JPAUtils;
+import org.apache.openaz.xacml.api.XACML3;
+import com.vaadin.addon.jpacontainer.JPAContainer;
+import com.vaadin.annotations.AutoGenerated;
+import com.vaadin.data.Buffered.SourceException;
+import com.vaadin.data.Validator.InvalidValueException;
+import com.vaadin.data.validator.RegexpValidator;
+import com.vaadin.event.ShortcutAction.KeyCode;
+import com.vaadin.ui.AbstractSelect.ItemCaptionMode;
+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.Label;
+import com.vaadin.ui.ListSelect;
+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 PolicySetEditorWindow 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 textAreaDescription;
+	@AutoGenerated
+	private ListSelect listSelectAlgorithm;
+	@AutoGenerated
+	private TextField textFieldVersion;
+	@AutoGenerated
+	private Label labelID;
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+	private final PolicySetEditorWindow self = this;
+	private final PolicySetType policySet;
+	private JPAContainer<PolicyAlgorithms> algorithms = ((XacmlAdminUI)UI.getCurrent()).getPolicyAlgorithms();
+	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 PolicySetEditorWindow(PolicySetType policySet) {
+		buildMainLayout();
+		//setCompositionRoot(mainLayout);
+		setContent(mainLayout);
+		//
+		// Save
+		//
+		this.policySet = policySet;
+		//
+		// Close shortcut
+		//
+		this.setCloseShortcut(KeyCode.ESCAPE);
+		//
+		// Initialize GUI
+		//
+		this.initializeLabel();
+		this.initializeText();
+		this.initializeSelect();
+		this.initializeButton();
+		//
+		// Focus
+		//
+		this.textAreaDescription.focus();
+	}
+	
+	protected void initializeLabel() {
+		if (this.policySet.getPolicySetId() == null) {
+			this.policySet.setPolicySetId(((XacmlAdminUI)UI.getCurrent()).newPolicyID());
+		}
+		this.labelID.setValue(this.policySet.getPolicySetId());
+	}
+	
+	protected void initializeText() {
+		//
+		//
+		//
+		this.textAreaDescription.setNullRepresentation("");
+		this.textAreaDescription.setValue(this.policySet.getDescription());
+		//
+		//
+		//
+		if (this.policySet.getVersion() == null) {
+			this.policySet.setVersion("1");
+		}
+		this.textFieldVersion.setRequiredError("The exact format is: ((\\d+|\\*)\\.)*(\\d+|\\*|\\+)");
+		this.textFieldVersion.addValidator(new RegexpValidator("((\\d+|\\*)\\.)*(\\d+|\\*|\\+)", true, "The version MUST a number optionally separated by '.' eg. 1 or 1.0 or 1.1.1 etc."));
+		this.textFieldVersion.setValue(this.policySet.getVersion());
+	}
+	
+	protected void initializeSelect() {
+		this.listSelectAlgorithm.setContainerDataSource(this.algorithms);
+		this.listSelectAlgorithm.setItemCaptionMode(ItemCaptionMode.PROPERTY);
+		this.listSelectAlgorithm.setItemCaptionPropertyId("xacmlId");
+		this.listSelectAlgorithm.setNullSelectionAllowed(false);
+		
+		if (this.policySet.getPolicyCombiningAlgId() == null) {
+			this.policySet.setPolicyCombiningAlgId(XACML3.ID_POLICY_FIRST_APPLICABLE.stringValue());
+		}
+		this.listSelectAlgorithm.setValue(JPAUtils.findPolicyAlgorithm(this.policySet.getPolicyCombiningAlgId()).getId());
+	}
+	
+	protected void initializeButton() {
+		this.buttonSave.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				try {
+					//
+					// Commit
+					//
+					self.listSelectAlgorithm.commit();
+					self.textFieldVersion.commit();
+					self.textAreaDescription.commit();
+					//
+					// Save everything
+					//
+					self.policySet.setDescription(self.textAreaDescription.getValue());
+					self.policySet.setVersion(self.textFieldVersion.getValue());
+					Object id = self.listSelectAlgorithm.getValue();
+					self.policySet.setPolicyCombiningAlgId(algorithms.getItem(id).getEntity().getXacmlId());
+					//
+					// Mark ourselves as saved
+					//
+					self.isSaved = true;
+					//
+					// Close window
+					//
+					self.close();
+				} catch (SourceException | InvalidValueException e) { //NOPMD
+					//
+					// VAADIN will show the required error message to the user
+					//
+				}
+			}
+		});
+	}
+	
+	public boolean isSaved() {
+		return this.isSaved;
+	}
+	
+	public PolicySetType getPolicySet() {
+		return this.policySet;
+	}
+
+	@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");
+		
+		// labelID
+		labelID = new Label();
+		labelID.setCaption("Policy Set ID");
+		labelID.setImmediate(false);
+		labelID.setWidth("100.0%");
+		labelID.setHeight("-1px");
+		labelID.setValue("Label");
+		mainLayout.addComponent(labelID);
+		
+		// textFieldVersion
+		textFieldVersion = new TextField();
+		textFieldVersion.setCaption("Version");
+		textFieldVersion.setImmediate(false);
+		textFieldVersion
+				.setDescription("The format is numbers only separated by decimal point.");
+		textFieldVersion.setWidth("-1px");
+		textFieldVersion.setHeight("-1px");
+		textFieldVersion.setInvalidAllowed(false);
+		textFieldVersion.setRequired(true);
+		textFieldVersion.setInputPrompt("Eg. 1 or 1.0 or 1.0.0 etc.");
+		mainLayout.addComponent(textFieldVersion);
+		
+		// listSelectAlgorithm
+		listSelectAlgorithm = new ListSelect();
+		listSelectAlgorithm.setCaption("Policy Combining Algorithm");
+		listSelectAlgorithm.setImmediate(false);
+		listSelectAlgorithm.setWidth("100.0%");
+		listSelectAlgorithm.setHeight("-1px");
+		listSelectAlgorithm.setInvalidAllowed(false);
+		listSelectAlgorithm.setRequired(true);
+		mainLayout.addComponent(listSelectAlgorithm);
+		
+		// textAreaDescription
+		textAreaDescription = new TextArea();
+		textAreaDescription.setCaption("Description");
+		textAreaDescription.setImmediate(false);
+		textAreaDescription.setWidth("100.0%");
+		textAreaDescription.setHeight("-1px");
+		mainLayout.addComponent(textAreaDescription);
+		mainLayout.setExpandRatio(textAreaDescription, 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/PolicyUploadWindow.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/PolicyUploadWindow.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/PolicyUploadWindow.java
new file mode 100644
index 0000000..06afe28
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/PolicyUploadWindow.java
@@ -0,0 +1,238 @@
+/*
+ *  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.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.vaadin.annotations.AutoGenerated;
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.data.Property.ValueChangeListener;
+import com.vaadin.ui.Alignment;
+import com.vaadin.ui.CheckBox;
+import com.vaadin.ui.Upload;
+import com.vaadin.ui.Upload.Receiver;
+import com.vaadin.ui.Upload.SucceededEvent;
+import com.vaadin.ui.Upload.SucceededListener;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.Window;
+
+public class PolicyUploadWindow extends Window implements Receiver, SucceededListener {
+
+	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */
+
+	@AutoGenerated
+	private VerticalLayout mainLayout;
+	@AutoGenerated
+	private CheckBox checkBoxImportAdvice;
+	@AutoGenerated
+	private CheckBox checkBoxImportObligations;
+	@AutoGenerated
+	private CheckBox checkBoxIgnoreStandard;
+	@AutoGenerated
+	private CheckBox checkBoxImportAttributes;
+	@AutoGenerated
+	private Upload upload;
+	private static final long serialVersionUID = 1L;
+	private final PolicyUploadWindow self = this;
+	private static final Log logger	= LogFactory.getLog(PolicyUploadWindow.class);
+	private Path directory = null;
+	private Path newfile = null;
+	private boolean succeeded = 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 PolicyUploadWindow(Path directory) {
+		buildMainLayout();
+		//
+		// Create our main layout
+		//
+		this.setContent(mainLayout);
+		//
+		// Finish setting up the main layout
+		//
+		this.mainLayout.setSpacing(true);
+		this.mainLayout.setMargin(true);
+		
+		this.checkBoxImportAdvice.setValue(true);
+		this.checkBoxIgnoreStandard.setValue(true);
+		this.checkBoxImportAttributes.setValue(true);
+		this.checkBoxImportObligations.setValue(true);
+		
+		this.directory = directory;
+
+		this.upload.addSucceededListener(this);
+		this.upload.setReceiver(this);
+		
+		this.checkBoxImportAttributes.addValueChangeListener(new ValueChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void valueChange(ValueChangeEvent event) {
+				if (self.checkBoxImportAttributes.getValue()) {
+					self.checkBoxIgnoreStandard.setEnabled(true);
+				} else {
+					self.checkBoxIgnoreStandard.setEnabled(false);
+				}
+			}
+			
+		});
+	}
+	
+	@Override
+	public OutputStream receiveUpload(String filename, String mimeType) {
+		//
+		// Validate the mime type
+		//
+		if (! mimeType.equalsIgnoreCase("text/xml")) {
+			return null;
+		}
+		//
+		// Create its new full path
+		//
+		this.newfile = Paths.get(self.directory.toString(), filename);
+		//
+		// Does it already exist?
+		//
+		if (Files.exists(this.newfile)) {
+			//
+			// TODO Prompt them to overwrite and/or bump the version???
+			//
+			return null;
+		}
+		//
+		// Try to create the output stream
+		//
+		try {
+			return new FileOutputStream(this.newfile.toFile());
+		} catch (FileNotFoundException e) {
+			logger.error("Failed to create uploaded file", e);
+		}
+		return null;
+	}
+	
+	@Override
+	public void uploadSucceeded(SucceededEvent event) {
+		if (logger.isDebugEnabled()) {
+			logger.debug("upload succeeded");
+		}
+		this.succeeded = true;
+		this.close();
+	}
+
+	public Path	getUploadedFile() {
+		if (this.succeeded) {
+			return this.newfile;
+		}
+		return null;
+	}
+	
+	public boolean importAttributes() {
+		return this.checkBoxImportAttributes.getValue();
+	}
+	
+	public boolean importObligations() {
+		return this.checkBoxImportObligations.getValue();
+	}
+	
+	public boolean importAdvice() {
+		return this.checkBoxImportAdvice.getValue();
+	}
+	
+	public boolean ignoreStandard() {
+		return this.checkBoxIgnoreStandard.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");
+		
+		// upload
+		upload = new Upload();
+		upload.setCaption("Upload Xacml Policy File");
+		upload.setImmediate(false);
+		upload.setWidth("-1px");
+		upload.setHeight("-1px");
+		mainLayout.addComponent(upload);
+		
+		// checkBoxImportAttributes
+		checkBoxImportAttributes = new CheckBox();
+		checkBoxImportAttributes
+				.setCaption("Import attributes into attribute dictionary.");
+		checkBoxImportAttributes.setImmediate(false);
+		checkBoxImportAttributes.setWidth("-1px");
+		checkBoxImportAttributes.setHeight("-1px");
+		mainLayout.addComponent(checkBoxImportAttributes);
+		
+		// checkBoxIgnoreStandard
+		checkBoxIgnoreStandard = new CheckBox();
+		checkBoxIgnoreStandard.setCaption("Ignore Standard Attributes");
+		checkBoxIgnoreStandard.setImmediate(false);
+		checkBoxIgnoreStandard.setWidth("-1px");
+		checkBoxIgnoreStandard.setHeight("-1px");
+		mainLayout.addComponent(checkBoxIgnoreStandard);
+		mainLayout.setComponentAlignment(checkBoxIgnoreStandard, new Alignment(
+				20));
+		
+		// checkBoxImportObligations
+		checkBoxImportObligations = new CheckBox();
+		checkBoxImportObligations
+				.setCaption("Import obligations into obligation dictionary.");
+		checkBoxImportObligations.setImmediate(false);
+		checkBoxImportObligations.setWidth("-1px");
+		checkBoxImportObligations.setHeight("-1px");
+		mainLayout.addComponent(checkBoxImportObligations);
+		
+		// checkBoxImportAdvice
+		checkBoxImportAdvice = new CheckBox();
+		checkBoxImportAdvice
+				.setCaption("Import advice into advice dictionary.");
+		checkBoxImportAdvice.setImmediate(false);
+		checkBoxImportAdvice.setWidth("-1px");
+		checkBoxImportAdvice.setHeight("-1px");
+		mainLayout.addComponent(checkBoxImportAdvice);
+		
+		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/RenamePolicyFileWindow.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/RenamePolicyFileWindow.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/RenamePolicyFileWindow.java
new file mode 100644
index 0000000..3b9ade9
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/RenamePolicyFileWindow.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.view.windows;
+
+import com.vaadin.annotations.AutoGenerated;
+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 RenamePolicyFileWindow 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 textFieldFilename;
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+	private RenamePolicyFileWindow self = this;
+	private String newFilename = 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.
+	 */
+	public RenamePolicyFileWindow(String currentFilename) {
+		buildMainLayout();
+		//setCompositionRoot(mainLayout);
+		setContent(mainLayout);
+		this.setCloseShortcut(KeyCode.ESCAPE);
+		//
+		// Initialize the text field
+		//
+		this.textFieldFilename.setValue(currentFilename);
+		this.textFieldFilename.setImmediate(true);
+		this.textFieldFilename.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);
+				}
+			}
+		});
+		//
+		// Initialize the button
+		//
+		this.buttonSave.setClickShortcut(KeyCode.ENTER);
+		this.buttonSave.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				//
+				// Save the value
+				//
+				self.newFilename = self.textFieldFilename.getValue();
+				//
+				// Make sure it ends with .xml
+				//
+				if (self.newFilename.endsWith(".xml") == false) {
+					self.newFilename = self.newFilename + ".xml";
+				}
+				//
+				// Close the window
+				//
+				self.close();
+			}
+		});
+		this.textFieldFilename.focus();
+	}
+	
+	public String getNewFilename() {
+		return this.newFilename;
+	}
+
+	@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");
+		
+		// textFieldFilename
+		textFieldFilename = new TextField();
+		textFieldFilename.setCaption("Policy File Name");
+		textFieldFilename.setImmediate(false);
+		textFieldFilename.setWidth("-1px");
+		textFieldFilename.setHeight("-1px");
+		mainLayout.addComponent(textFieldFilename);
+		
+		// buttonSave
+		buttonSave = new Button();
+		buttonSave.setCaption("Save");
+		buttonSave.setImmediate(false);
+		buttonSave.setWidth("-1px");
+		buttonSave.setHeight("-1px");
+		mainLayout.addComponent(buttonSave);
+		mainLayout.setComponentAlignment(buttonSave, new Alignment(24));
+		
+		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/RuleEditorWindow.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/RuleEditorWindow.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/RuleEditorWindow.java
new file mode 100644
index 0000000..e6baf44
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/RuleEditorWindow.java
@@ -0,0 +1,219 @@
+/*
+ *  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.EffectType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.RuleType;
+
+import org.apache.openaz.xacml.admin.XacmlAdminUI;
+import com.vaadin.annotations.AutoGenerated;
+import com.vaadin.data.Buffered.SourceException;
+import com.vaadin.data.Validator.InvalidValueException;
+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.Label;
+import com.vaadin.ui.OptionGroup;
+import com.vaadin.ui.TextArea;
+import com.vaadin.ui.UI;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.Window;
+
+public class RuleEditorWindow 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 textAreaDescription;
+	@AutoGenerated
+	private OptionGroup optionGroupEffect;
+	@AutoGenerated
+	private Label labelRuleID;
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+	private final RuleEditorWindow self = this;
+	private final RuleType rule;
+	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 RuleEditorWindow(RuleType rule) {
+		buildMainLayout();
+		//setCompositionRoot(mainLayout);
+		setContent(mainLayout);
+		//
+		// Save
+		//
+		this.rule = rule;
+		//
+		// Close shortcut
+		//
+		this.setCloseShortcut(KeyCode.ESCAPE);
+		//
+		// Initialize
+		//
+		this.initializeLabel();
+		this.initializeOption();
+		this.initializeText();
+		this.initializeButton();
+	}
+	
+	protected void initializeLabel() {
+		if (this.rule.getRuleId() == null) {
+			this.rule.setRuleId(((XacmlAdminUI)UI.getCurrent()).newRuleID());
+		}
+		this.labelRuleID.setValue(this.rule.getRuleId());
+	}
+
+	protected void initializeOption() {
+		this.optionGroupEffect.setRequiredError("You MUST select an effect (Permit or Deny for the rule.");
+		this.optionGroupEffect.addItem("Permit");
+		this.optionGroupEffect.addItem("Deny");
+		if (this.rule.getEffect() == null) {
+			this.rule.setEffect(EffectType.PERMIT);
+		}
+		if (this.rule.getEffect() == EffectType.PERMIT) {
+			this.optionGroupEffect.setValue("Permit");
+		} else {
+			this.optionGroupEffect.setValue("Deny");
+		}
+	}
+
+	protected void initializeText() {
+		this.textAreaDescription.setValue(this.rule.getDescription());
+	}
+
+	protected void initializeButton() {
+		this.buttonSave.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				try {
+					//
+					// Commit
+					//
+					self.optionGroupEffect.commit();
+					self.textAreaDescription.commit();
+					//
+					// Save everything
+					//
+					if (self.optionGroupEffect.getValue() == "Permit") {
+						self.rule.setEffect(EffectType.PERMIT);
+					} else {
+						self.rule.setEffect(EffectType.DENY);
+					}
+					self.rule.setDescription(self.textAreaDescription.getValue());
+					//
+					// Set ourselves as saved
+					//
+					self.isSaved = true;
+					//
+					// Close the window
+					//
+					self.close();
+				} catch (SourceException | InvalidValueException e) { //NOPMD
+					//
+					// VAADIN will show the required error message to the user
+					//
+				}
+			}			
+		});
+	}
+	
+	public boolean isSaved() {
+		return this.isSaved;
+	}
+	
+	public RuleType getRule() {
+		return this.rule;
+	}
+
+	@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");
+		
+		// labelRuleID
+		labelRuleID = new Label();
+		labelRuleID.setCaption("Rule ID");
+		labelRuleID.setImmediate(false);
+		labelRuleID.setWidth("100.0%");
+		labelRuleID.setHeight("-1px");
+		labelRuleID.setValue("Label");
+		mainLayout.addComponent(labelRuleID);
+		mainLayout.setExpandRatio(labelRuleID, 1.0f);
+		
+		// optionGroupEffect
+		optionGroupEffect = new OptionGroup();
+		optionGroupEffect.setCaption("Choose the effect.");
+		optionGroupEffect.setImmediate(false);
+		optionGroupEffect.setWidth("-1px");
+		optionGroupEffect.setHeight("-1px");
+		optionGroupEffect.setInvalidAllowed(false);
+		optionGroupEffect.setRequired(true);
+		mainLayout.addComponent(optionGroupEffect);
+		
+		// textAreaDescription
+		textAreaDescription = new TextArea();
+		textAreaDescription.setCaption("Enter a description for the Rule.");
+		textAreaDescription.setImmediate(false);
+		textAreaDescription.setWidth("100.0%");
+		textAreaDescription.setHeight("-1px");
+		textAreaDescription.setNullSettingAllowed(true);
+		textAreaDescription.setNullRepresentation("");
+		mainLayout.addComponent(textAreaDescription);
+		mainLayout.setExpandRatio(textAreaDescription, 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/SelectPDPGroupWindow.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/SelectPDPGroupWindow.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/SelectPDPGroupWindow.java
new file mode 100644
index 0000000..fd3d8cb
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/SelectPDPGroupWindow.java
@@ -0,0 +1,207 @@
+/*
+ *  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.Set;
+
+import org.apache.openaz.xacml.api.pap.PDPGroup;
+import com.vaadin.annotations.AutoGenerated;
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.data.Property.ValueChangeListener;
+import com.vaadin.event.ShortcutAction.KeyCode;
+import com.vaadin.ui.AbstractSelect.ItemCaptionMode;
+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.ListSelect;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.Window;
+
+public class SelectPDPGroupWindow 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 ListSelect listSelectPDPGroup;
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+	private final SelectPDPGroupWindow self = this;
+	
+	private boolean saved = false;
+	
+	private PDPGroup selectedGroup = 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.
+	 */
+	// TODO - Refactor.  Unused formal parameter: caption. Either determine
+	// that this parameter is unnecessary and remove it (including removing
+	// it from all constructor method consumers), or use it.
+	// NOTE: Setting to NOPMD for now.
+	public SelectPDPGroupWindow(Set<PDPGroup> groups, String caption) { //NOPMD
+		buildMainLayout();
+		//setCompositionRoot(mainLayout);
+		setContent(mainLayout);
+		//
+		// Setup the shortcuts
+		//
+		this.setCloseShortcut(KeyCode.ESCAPE);
+		this.buttonSave.setClickShortcut(KeyCode.ENTER);
+		//
+		// initialize
+		//
+		this.initialize(groups);
+		//
+		// Focus
+		//
+		this.listSelectPDPGroup.focus();
+		//
+		// setup the button
+		//
+		this.setupButtons();
+	}
+	
+	protected void initialize(Set<PDPGroup> groups) {
+		//
+		// Initialize the list
+		//
+		this.initializeSelect(groups);
+		//
+		// Buttons
+		//
+		this.initializeButtons();
+	}
+	
+	protected void initializeButtons() {
+		this.buttonSave.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				//
+				// Get the selected value
+				//
+				self.selectedGroup = (PDPGroup) self.listSelectPDPGroup.getValue();
+				assert self.selectedGroup != null;
+				//
+				// Mark ourselves as saved
+				//
+				self.saved = true;
+				//
+				// Close window
+				//
+				self.close();
+			}
+		});
+	}
+	
+	public boolean isSaved() {
+		return saved;
+	}
+	
+	public PDPGroup selectedGroup() {
+		return this.selectedGroup;
+	}
+	
+	private void initializeSelect(Set<PDPGroup> groups) {
+		//
+		// Initialize GUI properties
+		//
+		this.listSelectPDPGroup.setImmediate(true);
+		this.listSelectPDPGroup.setItemCaptionMode(ItemCaptionMode.EXPLICIT);
+		this.listSelectPDPGroup.setNullSelectionAllowed(false);
+		this.listSelectPDPGroup.setNewItemsAllowed(false);
+		this.listSelectPDPGroup.setMultiSelect(false);
+		//
+		// Add items
+		//
+		for (PDPGroup group : groups) {
+			this.listSelectPDPGroup.addItem(group);
+			this.listSelectPDPGroup.setItemCaption(group, group.getName());
+		}
+		//
+		// Listen to events
+		//
+		this.listSelectPDPGroup.addValueChangeListener(new ValueChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void valueChange(ValueChangeEvent event) {
+				self.setupButtons();
+			}
+		});
+	}
+	
+	protected void setupButtons() {
+		if (self.listSelectPDPGroup.getValue() == null) {
+			self.buttonSave.setEnabled(false);
+		} else {
+			self.buttonSave.setEnabled(true);
+		}
+	}
+
+	@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");
+		
+		// listSelectPDPGroup
+		listSelectPDPGroup = new ListSelect();
+		listSelectPDPGroup.setImmediate(false);
+		listSelectPDPGroup.setWidth("-1px");
+		listSelectPDPGroup.setHeight("-1px");
+		listSelectPDPGroup.setInvalidAllowed(false);
+		listSelectPDPGroup.setRequired(true);
+		mainLayout.addComponent(listSelectPDPGroup);
+		mainLayout.setExpandRatio(listSelectPDPGroup, 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/SelectPIPConfigurationWindow.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/SelectPIPConfigurationWindow.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/SelectPIPConfigurationWindow.java
new file mode 100644
index 0000000..dfa92ee
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/SelectPIPConfigurationWindow.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.view.windows;
+
+import java.util.Collection;
+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.XacmlAdminUI;
+import org.apache.openaz.xacml.admin.jpa.PIPConfiguration;
+import org.apache.openaz.xacml.api.pap.PDPGroup;
+import org.apache.openaz.xacml.api.pap.PDPPIPConfig;
+import org.apache.openaz.xacml.std.pap.StdPDPPIPConfig;
+import com.vaadin.addon.jpacontainer.EntityItem;
+import com.vaadin.addon.jpacontainer.JPAContainer;
+import com.vaadin.addon.jpacontainer.provider.CachingLocalEntityProvider;
+import com.vaadin.annotations.AutoGenerated;
+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.Table;
+import com.vaadin.ui.UI;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.Window;
+
+public class SelectPIPConfigurationWindow 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 table;
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+	private static final Log logger	= LogFactory.getLog(SelectPIPConfigurationWindow.class);
+	private final SelectPIPConfigurationWindow self = this;
+	private final JPAContainer<PIPConfiguration>	container = new JPAContainer<PIPConfiguration>(PIPConfiguration.class);
+	private boolean isSaved = false;
+	private Set<PDPPIPConfig> selectedConfigs = 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.
+	 */
+	public SelectPIPConfigurationWindow(PDPGroup group) {
+		buildMainLayout();
+		//setCompositionRoot(mainLayout);
+		setContent(mainLayout);
+		//
+		// Initialize
+		//
+		this.initialize(group);
+	}
+	
+	protected void initialize(PDPGroup group) {
+		//
+		// Setup the container
+		//
+		this.container.setEntityProvider(new CachingLocalEntityProvider<PIPConfiguration>(PIPConfiguration.class, ((XacmlAdminUI)UI.getCurrent()).getEntityManager()));
+
+		this.initializeTable(group);
+		this.initializeButton();
+	}
+
+	protected void initializeTable(PDPGroup group) {
+		//
+		// GUI properties
+		//
+		this.table.setContainerDataSource(this.container);
+		this.table.setImmediate(true);
+		this.table.setSelectable(true);
+		this.table.setMultiSelect(true);
+		this.table.setPageLength(this.container.size() > 10 ? 10 : this.container.size());
+		this.table.setVisibleColumns("name", "description");
+		//
+		// Pre-select the group's configurations
+		//
+		for (PDPPIPConfig config : group.getPipConfigs()) {
+			try {
+				Integer id = Integer.parseInt(config.getId());
+				if (this.container.containsId(id)) {
+					this.table.select(id);
+				}
+			} catch (NumberFormatException e) {
+				logger.error("invalid config id: " + config.getId());
+			}
+		}
+	}
+
+	protected void initializeButton() {
+		this.buttonSave.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				//
+				// Commit the table so we have everything that was selected
+				//
+				self.table.commit();
+				//
+				// We are going to fill this structure
+				//
+				self.selectedConfigs = new HashSet<PDPPIPConfig>();
+				//
+				// Get all the selected values
+				//
+				Object values = self.table.getValue();
+				if (values != null && values instanceof Collection) {
+					Collection<?> ids = (Collection<?>) values;
+					for (Object id : ids) {
+						//
+						// Get the entity
+						//
+						EntityItem<PIPConfiguration> entity = self.container.getItem(id);
+						PIPConfiguration config = entity.getEntity();
+						//
+						// Create object needed by PAP REST
+						//
+						StdPDPPIPConfig pipConfig = new StdPDPPIPConfig();
+						pipConfig.setId(Integer.toString(config.getId()));
+						pipConfig.setClassname(config.getClassname());
+						pipConfig.setName(config.getName());
+						pipConfig.setDescription(config.getDescription());
+						Map<String, String> map = config.getConfiguration(null);
+						pipConfig.setValues(map);
+						//
+						// Add it to the saved Set
+						//
+						self.selectedConfigs.add(pipConfig);
+					}
+				}
+				//
+				// Mark ourselves as saved
+				//
+				self.isSaved = true;
+				//
+				// Close the window
+				//
+				self.close();
+			}
+		});
+	}
+	
+	public boolean isSaved() {
+		return this.isSaved;
+	}
+	
+	public Set<PDPPIPConfig> getSelectedConfigs() {
+		return this.selectedConfigs;
+	}
+
+	@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");
+		
+		// table
+		table = new Table();
+		table.setCaption("PIP Configurations");
+		table.setImmediate(false);
+		table.setWidth("-1px");
+		table.setHeight("-1px");
+		mainLayout.addComponent(table);
+		
+		// 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/SelectWorkspacePoliciesWindow.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/SelectWorkspacePoliciesWindow.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/SelectWorkspacePoliciesWindow.java
new file mode 100644
index 0000000..93cea8c
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/SelectWorkspacePoliciesWindow.java
@@ -0,0 +1,331 @@
+/*
+ *  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.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.net.URI;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+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.model.GitRepositoryContainer;
+import org.apache.openaz.xacml.admin.model.GitRepositoryContainer.FileItem;
+import org.apache.openaz.xacml.admin.util.AdminNotification;
+import org.apache.openaz.xacml.std.pap.StdPDPPolicy;
+import com.vaadin.annotations.AutoGenerated;
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.data.Property.ValueChangeListener;
+import com.vaadin.event.ItemClickEvent;
+import com.vaadin.event.ItemClickEvent.ItemClickListener;
+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.TreeTable;
+import com.vaadin.ui.UI;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.Window;
+
+public class SelectWorkspacePoliciesWindow extends Window {
+	@AutoGenerated
+	private VerticalLayout mainLayout;
+
+	@AutoGenerated
+	private Button buttonSave;
+
+	@AutoGenerated
+	private TreeTable treeWorkspace;
+
+	private static Log	logger	= LogFactory.getLog(SelectWorkspacePoliciesWindow.class);
+
+	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+	private final SelectWorkspacePoliciesWindow self = this;
+	private GitRepositoryContainer treeContainer;
+	private boolean isSaved = false;
+	private StdPDPPolicy selectedPolicy = 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.
+	 */
+	public SelectWorkspacePoliciesWindow() {
+		buildMainLayout();
+		//setCompositionRoot(mainLayout);
+		setContent(mainLayout);
+		//
+		// Shortcuts
+		//
+		this.setCloseShortcut(KeyCode.ESCAPE);
+		this.buttonSave.setClickShortcut(KeyCode.ENTER);
+		//
+		//
+		//
+		this.initializeTree();
+		this.initializeButton();
+		//
+		//
+		//
+		this.treeWorkspace.focus();
+	}
+	
+	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) {
+				if (self.treeWorkspace.getValue() != null) {
+					self.buttonSave.setEnabled(true);
+				} else {
+					self.buttonSave.setEnabled(false);
+				}
+			}
+		});
+		//
+		// Double-click events
+		//
+		this.treeWorkspace.addItemClickListener(new ItemClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void itemClick(ItemClickEvent event) {
+				if (event.isDoubleClick()) {
+					//
+					// Save and close
+					//
+					self.doSave();
+				}
+			}
+		});
+	}
+	
+	protected void initializeButton() {
+		this.buttonSave.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				assert treeWorkspace.getValue() != null;
+				//
+				// Save everything
+				//
+				self.doSave();
+			}
+		});
+	}
+	
+	protected void doSave() {
+		//
+		// Get the current selection
+		//
+		FileItem selectedItem = (FileItem) this.treeWorkspace.getItem(this.treeWorkspace.getValue());
+		//
+		//
+		//
+		assert selectedItem != null;
+		if (selectedItem == null) {
+			return;
+		}
+		
+		// create the id of the target file
+		
+		// Our standard for file naming is:
+		//		<domain>.<filename>.<version>.xml
+		
+		// since the file name usually has a ".xml", we need to strip that before adding the other parts
+		String name = selectedItem.getName();
+		String id = name;
+		if (id.endsWith(".xml")) {
+			id = id.substring(0, id.length() - 4);
+		}
+		
+		// add on the version string
+
+		String version = selectedItem.getVersion();
+		id += "." + version;
+		
+		// put the .xml on the end
+		id += ".xml";
+		
+		// tack on the domain in front.  Do this one level at a time until we reach one of the roots
+	
+
+		File parentFile = selectedItem.getFile();
+		while ((parentFile = (File) this.treeWorkspace.getParent(parentFile)) != null) {
+			if (this.treeContainer.isRoot(parentFile)) {
+				break;
+			}
+			id = parentFile.getName() + "." + id;
+		}
+		
+		// Default policy to be Root policy;  user can change to deferred later
+		URI selectedURI = selectedItem.getFile().toURI();
+		try {
+			//
+			// Create the policy
+			//
+			this.selectedPolicy = new StdPDPPolicy(id, true, name, selectedURI);
+			//
+			// Mark ourselves as saved
+			//
+			this.isSaved = true;
+		} catch (IOException e) {
+			logger.error("Unable to create policy '" + id + "': " + e.getMessage());
+			AdminNotification.warn("Unable to create policy '" + id + "': " + e.getMessage());
+		}
+
+		//
+		// Close the window
+		//
+		this.close();
+	}
+
+	public boolean isSaved() {
+		return this.isSaved;
+	}
+	
+	public StdPDPPolicy getSelectedPolicy() {
+		return this.selectedPolicy;
+	}
+
+	
+	@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");
+		
+		// treeWorkspace
+		treeWorkspace = new TreeTable();
+		treeWorkspace.setCaption("Select Policy(s) for PDP Group");
+		treeWorkspace.setImmediate(true);
+		treeWorkspace.setWidth("100.0%");
+		treeWorkspace.setHeight("-1px");
+		mainLayout.addComponent(treeWorkspace);
+		
+		// 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/SubDomainEditorWindow.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/SubDomainEditorWindow.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/SubDomainEditorWindow.java
new file mode 100644
index 0000000..0e38a67
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/SubDomainEditorWindow.java
@@ -0,0 +1,204 @@
+/*
+ *  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 org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.vaadin.annotations.AutoGenerated;
+// import com.vaadin.data.Property.ValueChangeEvent;
+// import com.vaadin.data.Property.ValueChangeListener;
+import com.vaadin.data.Validator.InvalidValueException;
+import com.vaadin.data.validator.RegexpValidator;
+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.FormLayout;
+import com.vaadin.ui.TextField;
+import com.vaadin.ui.Window;
+
+public class SubDomainEditorWindow extends Window {
+
+	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */
+
+	@AutoGenerated
+	private FormLayout mainLayout;
+	@AutoGenerated
+	private Button buttonSave;
+	@AutoGenerated
+	private TextField textFieldSubdomain;
+
+	//
+	// Full domain pattern:
+	// "^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9])(.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9]))*$";
+	//
+	// We just want one part of it.
+	//
+	private static final String SUBDOMAIN_NAME_PATTERN = "^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9])$";
+	private static final String ERROR_MESSAGE = "Either enter a single subdomain via RFC1123 - letters, digits and a hyphen. Cannot start or end with a hyphen.";
+	
+	private static final long serialVersionUID = 1L;
+	private static final Log logger	= LogFactory.getLog(SubDomainEditorWindow.class);
+	private final SubDomainEditorWindow self = this;
+	private boolean saved = false;
+	private String subdomain = 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.
+	 */
+	public SubDomainEditorWindow(String subdomain) {
+		buildMainLayout();
+		setContent(mainLayout);
+		//
+		// Save
+		//
+		this.subdomain = subdomain;
+		//
+		// Set our shortcuts
+		//
+		this.setCloseShortcut(KeyCode.ESCAPE);
+		//
+		// Initialize
+		//
+		this.initializeTextField();
+		this.initializeButtons();
+		//
+		// Focus
+		//
+		this.textFieldSubdomain.focus();
+	}
+	
+	protected void initializeTextField() {
+		this.textFieldSubdomain.setRequired(true);
+		this.textFieldSubdomain.setRequiredError("Please enter a valid sub domain");
+		//
+		// Validate the name entered
+		//
+		this.textFieldSubdomain.addValidator(new RegexpValidator(SUBDOMAIN_NAME_PATTERN, true, ERROR_MESSAGE) {
+			private static final long serialVersionUID = 1L;
+			
+		});
+		//
+		// Respond to events
+		//
+		this.textFieldSubdomain.setImmediate(true);
+		this.textFieldSubdomain.addTextChangeListener(new TextChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void textChange(TextChangeEvent event) {
+				if (event.getText() != null && event.getText().length() > 0) {
+					self.buttonSave.setEnabled(true);
+				} else {
+					self.buttonSave.setEnabled(false);
+				}
+			}
+			
+		});
+	}
+	
+	protected void initializeButtons() {
+		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) {
+				try {
+					//
+					// Make sure the text is valid
+					//
+					self.textFieldSubdomain.validate();
+					//
+					// Parse our the subdomain parts
+					//
+					self.subdomain = self.textFieldSubdomain.getValue();
+					self.saved = true;
+					//
+					// Close it up
+					//
+					self.close();
+				} catch (InvalidValueException e) {
+					logger.error(e);
+				}
+			}
+			
+		});
+	}
+	
+	public boolean isSaved() {
+		return this.saved;
+	}
+	
+	public String	getSubDomain() {
+		return this.subdomain;
+	}
+
+	@AutoGenerated
+	private FormLayout buildMainLayout() {
+		// common part: create layout
+		mainLayout = new FormLayout();
+		mainLayout.setImmediate(false);
+		mainLayout.setWidth("-1px");
+		mainLayout.setHeight("-1px");
+		mainLayout.setMargin(true);
+		mainLayout.setSpacing(true);
+		
+		// top-level component properties
+		setWidth("-1px");
+		setHeight("-1px");
+		
+		// textFieldSubdomain
+		textFieldSubdomain = new TextField();
+		textFieldSubdomain.setCaption("Enter Sub Domain");
+		textFieldSubdomain.setImmediate(false);
+		textFieldSubdomain
+				.setDescription("You can enter sub domain name - do not use spaces or wildcard characters.");
+		textFieldSubdomain.setWidth("-1px");
+		textFieldSubdomain.setHeight("-1px");
+		textFieldSubdomain.setInvalidAllowed(false);
+		textFieldSubdomain
+				.setInputPrompt("Examples: sales hr business marketing.");
+		mainLayout.addComponent(textFieldSubdomain);
+		mainLayout.setExpandRatio(textFieldSubdomain, 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/VariableDefinitionEditorWindow.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/VariableDefinitionEditorWindow.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/VariableDefinitionEditorWindow.java
new file mode 100644
index 0000000..bec843e
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/VariableDefinitionEditorWindow.java
@@ -0,0 +1,202 @@
+/*
+ *  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.VariableDefinitionType;
+
+import com.vaadin.annotations.AutoGenerated;
+import com.vaadin.data.Buffered.SourceException;
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.data.Property.ValueChangeListener;
+import com.vaadin.data.Validator.InvalidValueException;
+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.TextField;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.Window;
+
+public class VariableDefinitionEditorWindow 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 textFieldID;
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+	private final VariableDefinitionEditorWindow self = this;
+	private final VariableDefinitionType variable;
+	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 VariableDefinitionEditorWindow(VariableDefinitionType variable) {
+		buildMainLayout();
+		//setCompositionRoot(mainLayout);
+		setContent(mainLayout);
+		//
+		// Save
+		//
+		this.variable = variable;
+		//
+		// Set our shortcuts
+		//
+		this.setCloseShortcut(KeyCode.ESCAPE);
+		//
+		// Initialize
+		//
+		this.initializeText();
+		this.initializeButton();
+		//
+		// Initial focus
+		//
+		this.textFieldID.focus();
+	}
+	
+	protected void initializeText() {
+		//
+		// Initialize GUI properties
+		//
+		this.textFieldID.setImmediate(true);
+		//
+		// Listen to changes
+		//
+		this.textFieldID.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);
+				}
+			}
+			
+		});
+		this.textFieldID.addValueChangeListener(new ValueChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void valueChange(ValueChangeEvent event) {
+				if (self.textFieldID.getValue() != null && self.textFieldID.getValue().isEmpty() == false) {
+					self.buttonSave.setEnabled(true);
+				} else {
+					self.buttonSave.setEnabled(false);
+				}
+			}			
+		});
+		//
+		// Set the value
+		//
+		this.textFieldID.setValue(variable.getVariableId());
+	}
+	
+	protected void initializeButton() {
+		this.buttonSave.setClickShortcut(KeyCode.ENTER);
+		this.buttonSave.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				try {
+					//
+					// Commit it
+					//
+					self.textFieldID.commit();
+					//
+					// Save it
+					//
+					self.variable.setVariableId(self.textFieldID.getValue());
+					self.isSaved = true;
+					//
+					// Close window
+					//
+					self.close();
+				} catch (SourceException | InvalidValueException e) { //NOPMD
+					// Vaadin will display error
+					// TODO - Verify that Vaadin will display error and update this
+					//        inline documentation accordingly
+				}
+			}			
+		});
+	}
+	
+	public boolean isSaved() {
+		return this.isSaved;
+	}
+	
+	public VariableDefinitionType getVariable() {
+		return this.variable;
+	}
+
+	@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");
+		
+		// textFieldID
+		textFieldID = new TextField();
+		textFieldID.setCaption("Variable ID");
+		textFieldID.setImmediate(false);
+		textFieldID.setWidth("-1px");
+		textFieldID.setHeight("-1px");
+		textFieldID.setInvalidAllowed(false);
+		textFieldID.setRequired(true);
+		textFieldID.setNullRepresentation("");
+		mainLayout.addComponent(textFieldID);
+		
+		// buttonSave
+		buttonSave = new Button();
+		buttonSave.setCaption("Save and Continue");
+		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/VariableReferenceEditorWindow.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/VariableReferenceEditorWindow.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/VariableReferenceEditorWindow.java
new file mode 100644
index 0000000..53b47c4
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/view/windows/VariableReferenceEditorWindow.java
@@ -0,0 +1,242 @@
+/*
+ *  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 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 com.vaadin.annotations.AutoGenerated;
+import com.vaadin.data.Buffered.SourceException;
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.data.Property.ValueChangeListener;
+import com.vaadin.data.Validator.InvalidValueException;
+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.ListSelect;
+import com.vaadin.ui.TextField;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.Window;
+
+public class VariableReferenceEditorWindow 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 textFieldVariable;
+	@AutoGenerated
+	private ListSelect listSelectVariables;
+	/*
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+	private static Log logger	= LogFactory.getLog(VariableReferenceEditorWindow.class);
+	private final VariableReferenceEditorWindow self = this;
+	private final VariableReferenceType variable;
+	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 VariableReferenceEditorWindow(VariableReferenceType variable, Map<VariableDefinitionType, PolicyType> variables) {
+		buildMainLayout();
+		//setCompositionRoot(mainLayout);
+		setContent(mainLayout);
+		//
+		// Save parameters
+		//
+		this.variable = variable;
+		//
+		// Set our shortcuts
+		//
+		this.setCloseShortcut(KeyCode.ESCAPE);
+		//
+		// Initialize
+		//
+		this.initializeTextField();
+		this.initializeSelect(variables);
+		this.initializeButtons();
+		//
+		// Focus
+		//
+		this.textFieldVariable.focus();
+	}
+	
+	protected void initializeTextField() {
+		this.textFieldVariable.setImmediate(true);
+		this.textFieldVariable.setNullRepresentation("");
+		this.textFieldVariable.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);
+				}
+			}
+			
+		});
+		this.textFieldVariable.addValueChangeListener(new ValueChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void valueChange(ValueChangeEvent event) {
+				String value = self.textFieldVariable.getValue();
+				if (value == null || value.isEmpty()) {
+					self.buttonSave.setEnabled(false);
+				} else {
+					self.buttonSave.setEnabled(true);
+				}
+			}
+		});
+		if (this.variable != null) {
+			this.textFieldVariable.setValue(this.variable.getVariableId());
+		}
+	}
+
+	protected void initializeSelect(Map<VariableDefinitionType, PolicyType> vars) {
+		//
+		// Add existing variables into the table
+		//
+		if (vars != null) {
+			for (VariableDefinitionType var : vars.keySet()) {
+				this.listSelectVariables.addItem(var.getVariableId());
+			}
+		}
+		//
+		// Respond to changes
+		//
+		this.listSelectVariables.setImmediate(true);
+		this.listSelectVariables.addValueChangeListener(new ValueChangeListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void valueChange(ValueChangeEvent event) {
+				Object value = self.listSelectVariables.getValue();
+				if (value != null) {
+					self.textFieldVariable.setValue(value.toString());
+				}
+			}			
+		});
+	}
+	
+	protected void initializeButtons() {
+		this.buttonSave.setClickShortcut(KeyCode.ENTER);
+		this.buttonSave.addClickListener(new ClickListener() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void buttonClick(ClickEvent event) {
+				try {
+					//
+					// Commit
+					//
+					self.textFieldVariable.commit();
+					//
+					// Now we can save
+					//
+					self.isSaved = true;
+					self.variable.setVariableId(self.textFieldVariable.getValue());
+					//
+					// And close the window
+					//
+					self.close();
+				} catch (SourceException | InvalidValueException e) {
+					logger.error("Commit variable id: " + e);
+				}
+			}			
+		});
+	}
+	
+	public boolean isSaved() {
+		return this.isSaved;
+	}
+	
+	public VariableReferenceType getVariableReference() {
+		return this.variable;
+	}
+
+	@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");
+		
+		// listSelectVariables
+		listSelectVariables = new ListSelect();
+		listSelectVariables.setCaption("Defined Variables");
+		listSelectVariables.setImmediate(false);
+		listSelectVariables.setWidth("100.0%");
+		listSelectVariables.setHeight("-1px");
+		mainLayout.addComponent(listSelectVariables);
+		mainLayout.setExpandRatio(listSelectVariables, 1.0f);
+		
+		// textFieldVariable
+		textFieldVariable = new TextField();
+		textFieldVariable.setCaption("Variable");
+		textFieldVariable.setImmediate(false);
+		textFieldVariable.setWidth("-1px");
+		textFieldVariable.setHeight("-1px");
+		textFieldVariable.setInvalidAllowed(false);
+		textFieldVariable.setRequired(true);
+		textFieldVariable.setInputPrompt("Eg. \"12345\" or \"myVariable1\"");
+		mainLayout.addComponent(textFieldVariable);
+		mainLayout.setExpandRatio(textFieldVariable, 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;
+	}
+
+}