/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 *
 */

package org.apache.openaz.xacml.admin.components;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionsType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.AllOfType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.AnyOfType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeValueType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.ConditionType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.MatchType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObligationExpressionType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObligationExpressionsType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicySetType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.RuleType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.TargetType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.VariableDefinitionType;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.openaz.xacml.admin.jpa.Attribute;
import org.apache.openaz.xacml.admin.model.GitRepositoryContainer;
import org.apache.openaz.xacml.admin.model.PolicyContainer;
import org.apache.openaz.xacml.admin.util.AdminNotification;
import org.apache.openaz.xacml.admin.util.JPAUtils;
import org.apache.openaz.xacml.admin.view.windows.AttributeSelectionWindow;
import org.apache.openaz.xacml.admin.view.windows.AttributeValueEditorWindow;
import org.apache.openaz.xacml.admin.view.windows.ExpressionBuilderComponent;
import org.apache.openaz.xacml.admin.view.windows.MatchEditorWindow;
import org.apache.openaz.xacml.admin.view.windows.ObligationAdviceEditorWindow;
import org.apache.openaz.xacml.admin.view.windows.PolicyEditorWindow;
import org.apache.openaz.xacml.admin.view.windows.PolicySetEditorWindow;
import org.apache.openaz.xacml.admin.view.windows.RuleEditorWindow;
import org.apache.openaz.xacml.admin.view.windows.VariableDefinitionEditorWindow;
import org.apache.openaz.xacml.util.XACMLObjectCopy;
import org.apache.openaz.xacml.util.XACMLPolicyWriter;
import com.vaadin.annotations.AutoGenerated;
import com.vaadin.data.Container.ItemSetChangeEvent;
import com.vaadin.data.Container.ItemSetChangeListener;
import com.vaadin.data.Item;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.Property.ValueChangeListener;
import com.vaadin.event.Action;
import com.vaadin.event.Action.Handler;
import com.vaadin.event.DataBoundTransferable;
import com.vaadin.event.ItemClickEvent;
import com.vaadin.event.ItemClickEvent.ItemClickListener;
import com.vaadin.event.ShortcutAction;
import com.vaadin.event.dd.DragAndDropEvent;
import com.vaadin.event.dd.DropHandler;
import com.vaadin.event.dd.acceptcriteria.AcceptAll;
import com.vaadin.event.dd.acceptcriteria.AcceptCriterion;
import com.vaadin.server.BrowserWindowOpener;
import com.vaadin.server.FileDownloader;
import com.vaadin.server.StreamResource;
import com.vaadin.shared.ui.dd.VerticalDropLocation;
import com.vaadin.ui.AbstractSelect.AbstractSelectTargetDetails;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.CheckBox;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.TabSheet.Tab;
import com.vaadin.ui.Table.TableDragMode;
import com.vaadin.ui.TreeTable;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window.CloseEvent;
import com.vaadin.ui.Window.CloseListener;

public class PolicyEditor extends CustomComponent {
	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */

	@AutoGenerated
	private VerticalLayout mainLayout;

	@AutoGenerated
	private TreeTable tree;

	@AutoGenerated
	private HorizontalLayout horizontalLayoutToolbar;

	@AutoGenerated
	private Button buttonExport;

	@AutoGenerated
	private Button buttonViewXML;

	@AutoGenerated
	private Button buttonSave;

	@AutoGenerated
	private CheckBox checkBoxAutoSave;

	@AutoGenerated
	private CheckBox checkBoxReadOnly;

	private static final long serialVersionUID = 1L;
	private static Log logger	= LogFactory.getLog(PolicyEditor.class);
	private final PolicyEditor self = this;

	private static final Action CREATE_POLICY =			new Action ("New Policy");
	private static final Action CREATE_POLICYSET =		new Action ("New Policy Set");
	private static final Action CREATE_RULE =			new Action ("New Rule");
	private static final Action EDIT_POLICY =			new Action ("Edit Policy");
	private static final Action EDIT_POLICYSET =		new Action ("Edit Policy Set");
	private static final Action EDIT_RULE =				new Action ("Edit Rule");
	private static final Action DELETE_POLICYSET =		new Action ("Delete Policy Set");
	private static final Action DELETE_POLICY = 		new Action ("Delete Policy");
	private static final Action DELETE_RULE = 			new Action ("Delete Rule");
	private static final Action CREATE_NEWANYOF =		new Action ("New Any Of (Match)");
	private static final Action CREATE_NEWALLOF =		new Action ("New All Of (Match)");
	private static final Action CREATE_NEWMATCH =		new Action ("New Match");
	private static final Action DELETE_ANYOF =			new Action ("Delete Any Of");
	private static final Action DELETE_ALLOF =			new Action ("Delete All Of");
	private static final Action DELETE_MATCH =			new Action ("Delete Match");
	private static final Action EDIT_MATCH =			new Action ("Edit Match");
	private static final Action EDIT_OBLIGATIONS =		new Action ("Edit Obligations");
	private static final Action DELETE_OBLIGATIONS = 	new Action ("Delete Obligations");
	private static final Action EDIT_ADVICE =			new Action ("Edit Advice");
	private static final Action DELETE_ADVICE = 		new Action ("Delete Advice");
	private static final Action CREATE_VARIABLE =		new Action ("Create Variable");
	private static final Action EDIT_VARIABLE =			new Action ("Edit Variable");
	private static final Action DELETE_VARIABLE =		new Action ("Delete Variable");
	private static final Action CREATE_TARGET = 		new Action ("Create Target");
	private static final Action CREATE_CONDITION =		new Action ("Create Condition");
	private static final Action EDIT_CONDITION =		new Action ("Edit Condition");
	private static final Action DELETE_CONDITION =		new Action ("Delete Condition");
	private static final Action EDIT_EXPRESSIONS =		new Action ("Edit Expressions");
	
	private static final Action CLIPBOARD_CUT =			new ShortcutAction ("Cut", ShortcutAction.KeyCode.S, new int[] {ShortcutAction.ModifierKey.CTRL});
	private static final Action CLIPBOARD_COPY =		new ShortcutAction ("Copy", ShortcutAction.KeyCode.C, new int[] {ShortcutAction.ModifierKey.CTRL});
	private static final Action CLIPBOARD_PASTE = 		new ShortcutAction ("Paste", ShortcutAction.KeyCode.V, new int[] {ShortcutAction.ModifierKey.CTRL});

	private static final Object[] VISIBLE_COLUMNS = new Object[] {PolicyContainer.PROPERTY_NAME, PolicyContainer.PROPERTY_SHORTALGORITHM, PolicyContainer.PROPERTY_DESCRIPTION};
	private static final String[] COLUMN_HEADERS = new String[] { "Name", "Algorithm or Effect", "Description"};

	private final File file;
	private final GitRepositoryContainer gitContainer;
	private final PolicyContainer policyContainer;
	private Tab tab = null;
	private boolean isModified = false;
	
	private Object clipboardObject = null;

	/**
	 * The constructor should first build the main layout, set the
	 * composition root and then do any custom initialization.
	 *
	 * The constructor will not be automatically regenerated by the
	 * visual editor.
	 * @throws IOException 
	 */
	public PolicyEditor(File policyFile, GitRepositoryContainer gitContainer, boolean readOnly) throws IOException {
		buildMainLayout();
		setCompositionRoot(mainLayout);
		this.mainLayout.setSizeFull();
		//
		// Save
		//
		this.file = policyFile;
		this.gitContainer = gitContainer;
		this.policyContainer = new PolicyContainer(this.file);
		//
		// Its our data also
		//
		this.setData(policyFile);
		//
		// Initialize GUI
		//
		this.initializeCheckboxes(readOnly);
		this.initializeButtons();
		this.initializeDownload();
		this.initializeTree();
// PLD TODO next release		this.initializeContextMenu();
		//
		// setup the caption etc.
		//
		this.setupCaption();
		this.resetComponents();
	}
	
	protected void initializeCheckboxes(boolean readOnly) {
		//
		// The readonly check box
		//
		this.checkBoxReadOnly.setImmediate(true);
		this.checkBoxReadOnly.setValue(readOnly);
		this.checkBoxReadOnly.addValueChangeListener(new ValueChangeListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void valueChange(ValueChangeEvent event) {
				self.resetComponents();
				self.setupCaption();
			}
			
		});
		//
		// The autosave check box
		//
		this.checkBoxAutoSave.setImmediate(true);
		this.checkBoxAutoSave.setValue(true);
	}
	
	protected void initializeButtons() {
		//
		// The Save button
		//
		this.buttonSave.addClickListener(new ClickListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void buttonClick(ClickEvent event) {
				self.savePolicy();
			}
		});
		//
		// Attach a window opener to the View XML button
		//
		BrowserWindowOpener opener = new BrowserWindowOpener(new StreamResource(new StreamResource.StreamSource() {
			private static final long serialVersionUID = 1L;

			@Override
			public InputStream getStream() {
				try {
					if (logger.isDebugEnabled()) {
						logger.debug("Setting view xml button to: " + self.file.getAbsolutePath());
					}
					return new FileInputStream(self.file);
				} catch (Exception e) {
					logger.error("Failed to open input stream " + self.file);
				}
				return null;
			}
		}, self.file.getName()));
		opener.setWindowName("_new");
		opener.extend(this.buttonViewXML);
	}
	
	protected void initializeDownload() {
		//
		// Create a stream resource pointing to the file
		//
		StreamResource r = new StreamResource(new StreamResource.StreamSource() {
			private static final long serialVersionUID = 1L;

			@Override
			public InputStream getStream() {
				try {
					return new FileInputStream(self.file);
				} catch (Exception e) {
					logger.error("Failed to open input stream " + self.file);
				}
				return null;
			}
		}, self.file.getName());
		r.setCacheTime(-1);
		r.setMIMEType("application/xml");
		//
		// Extend a downloader to attach to the Export Button
		//
		FileDownloader downloader = new FileDownloader(r);
		downloader.extend(this.buttonExport);
	}
	
	public void setTab(Tab tab) {
		this.tab = tab;
		this.setupCaption();
	}
	
	public boolean isAutoSave() {
		if (this.checkBoxAutoSave.isEnabled() == false) {
			return false;
		}
		return this.checkBoxAutoSave.getValue();
	}
	
	public boolean isReadOnly() {
		return this.checkBoxReadOnly.getValue();
	}

	protected void initializeTree() {
		//
		// Create our container and set it as the tree's data source
		//
		this.tree.setContainerDataSource(this.policyContainer);
		this.tree.setItemIconPropertyId("Icon");
		this.tree.setVisibleColumns(VISIBLE_COLUMNS);
		this.tree.setColumnHeaders(COLUMN_HEADERS);
		this.tree.setSelectable(true);
		this.tree.setSizeFull();
		//
		// Expand it down a few items
		//
		for (Object id : this.tree.getItemIds()) {
			this.tree.setCollapsed(id, false);
			for (Object child : this.tree.getChildren(id)) {
				this.tree.setCollapsed(child, false);
			}
		}
		//
		// Respond to double-click's
		//
		this.tree.addItemClickListener(new ItemClickListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void itemClick(ItemClickEvent event) {
				if (event.isDoubleClick()) {
					if (self.isReadOnly()) {
						AdminNotification.info("You are in read-only mode.");
						return;
					}
					Object target = event.getItemId();
					if (target instanceof PolicySetType) {
						self.editPolicySet((PolicySetType) target, (PolicySetType) self.policyContainer.getParent(target));
					} else if (target instanceof PolicyType) {
						self.editPolicy((PolicyType) target, (PolicySetType) self.policyContainer.getParent(target));
					} else if (target instanceof RuleType) {
						self.editRule((RuleType) target, (PolicyType) self.policyContainer.getParent(target));
					} else if (target instanceof ConditionType) {
						self.editCondition((ConditionType) target, (RuleType) self.policyContainer.getParent(target));
					} else if (target instanceof VariableDefinitionType) {
						self.editVariable((VariableDefinitionType) target, (PolicyType) self.policyContainer.getParent(target));
					} else if (target instanceof MatchType) {
						self.editMatch((MatchType) target, (AllOfType) self.policyContainer.getParent(target), null, null, "Edit Match");
					} else if (target instanceof ObligationExpressionType) {
						self.editObAdvice(true, self.policyContainer.getParent(target));
					} else if (target instanceof AdviceExpressionType) {
						self.editObAdvice(false, self.policyContainer.getParent(target));
					}
				}
			}
			
		});
		//
		// Respond to container changes
		//
		this.policyContainer.addItemSetChangeListener(new ItemSetChangeListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void containerItemSetChange(ItemSetChangeEvent event) {
				self.isModified = true;
				if (self.isAutoSave()) {
					self.savePolicy();
				} else {
					self.setupCaption();
					self.buttonSave.setEnabled(true);
				}
			}
		});
		//
		// Implement drag-n-drop
		//
		this.tree.setDropHandler(new DropHandler() {
			private static final long serialVersionUID = 1L;

			@Override
			public void drop(DragAndDropEvent event) {
				DataBoundTransferable t = (DataBoundTransferable) event.getTransferable();
			    AbstractSelectTargetDetails target = (AbstractSelectTargetDetails) event.getTargetDetails();
			    
			    //
			    // Get ids of the dragged item and the target item
			    //
			    Object sourceItemId = t.getData("itemId");
				Object targetItemId = target.getItemIdOver();
				VerticalDropLocation location = target.getDropLocation();
				if (logger.isDebugEnabled()) {
					logger.debug("Drop " + sourceItemId + " target " + targetItemId + " location " + location);
				}
				//
				// Tell our container what to do
				//
				try {
					if (location == VerticalDropLocation.MIDDLE) {
						//
						// Drop right on top of item making it a child
						//
						self.policyContainer.setParent(sourceItemId, targetItemId);
					}

					/*
					} else if (location == VerticalDropLocation.TOP) {
						//
						// Drop at the top of the tree making it the previous
						//
						Object parent = self.policyContainer.getParent(targetItemId);
						self.policyContainer.setParent(sourceItemId, parent);
						self.policyContainer.moveAfterSibling(sourceItemId, targetItemId);
						self.policyContainer.moveAfterSibling(targetItemId, sourceItemId);
					} else if (location == VerticalDropLocation.BOTTOM) {
						//
						// Drop below another item
						//
						Object parent = self.policyContainer.getParent(targetItemId);
						self.policyContainer.setParent(sourceItemId, targetItemId);
						self.policyContainer.moveAfterSibling(sourceItemId, targetItemId);
					}
					*/
				} catch (UnsupportedOperationException e) {
					logger.error("Unsupported " + e.getLocalizedMessage());
				}
			}

			@Override
			public AcceptCriterion getAcceptCriterion() {
				return AcceptAll.get();
			}
		});
	}
	
	protected void removeObject(Object target) {
		if (target instanceof PolicySetType) {
			this.removePolicySet((PolicySetType) target);
		} else if (target instanceof PolicyType) {
			this.removePolicy((PolicyType) target);
		} else if (target instanceof RuleType) {
			this.removeRule((RuleType) target);
		} else if (target instanceof ConditionType) {
			this.removeCondition((ConditionType) target);
		} else if (target instanceof VariableDefinitionType) {
			this.removeVariable((VariableDefinitionType) target);
		} else if (target instanceof AdviceExpressionType) {
			this.removeAdvice((AdviceExpressionType) target);
		} else if (target instanceof ObligationExpressionType) {
			this.removeObligations((ObligationExpressionType) target);
		}
	}

	protected void removeAdvice(AdviceExpressionType target) {
		if (this.tree.removeItem(target) == false) {
			logger.error("Failed to remove advice.");
		}
	}

	protected void removeVariable(VariableDefinitionType target) {
		if (this.tree.removeItem(target) == false) {
			logger.error("Failed to remove variable.");
		}
	}

	protected void removeCondition(ConditionType target) {
		if (this.tree.removeItem(target) == false) {
			logger.error("Failed to remove condition.");
		}
	}

	protected void removeObligations(ObligationExpressionType target) {
		if (this.tree.removeItem(target) == false) {
			logger.error("Failed to remove obligations.");
		}
	}

	protected void removeRule(RuleType target) {
		if (this.tree.removeItem(target) == false) {
			logger.error("Failed to remove rule.");
		}
	}

	protected void removePolicy(PolicyType target) {
		Object parent = this.tree.getParent(target);
		if (parent == null) {
			this.deleteRoot(target);
		} else {
			if (this.tree.removeItem(target) == false) {
				logger.error("Failed to remove policy.");
			}
		}
	}

	protected void removePolicySet(PolicySetType target) {
		Object parent = this.tree.getParent(target);
		if (parent == null) {
			this.deleteRoot(target);
		} else {
			if (this.tree.removeItem(target) == false) {
				logger.error("Failed to remove policy set.");
			}
		}
	}

	/*
	protected void initializeContextMenu() {
		ContextMenu menu = new ContextMenu();
		menu.setAsTableContextMenu(this.tree);
		menu.addContextMenuTableListener(new TableListener() {

			@Override
			public void onContextMenuOpenFromFooter(
					ContextMenuOpenedOnTableFooterEvent event) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onContextMenuOpenFromHeader(
					ContextMenuOpenedOnTableHeaderEvent event) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onContextMenuOpenFromRow(ContextMenuOpenedOnTableRowEvent event) {
				logger.info("context menu row");
			}
		});
		menu.addItem("test");
	}
	*/
	
	protected void savePolicy() {
		if (this.isReadOnly()) {
			logger.warn("Should not call savePolicy when in read only mode.");
			return;
		}
		Collection<?> roots = this.policyContainer.rootItemIds();
		if (roots.size() > 1) {
			logger.warn("More than one root policy.");
		}
		//
		// There should only be one root
		// Save the policy to disk.
		//
		for (Object root : roots) {
			logger.info("Saving policy: " + this.file.getName());
			//
			// TODO - Bump the version?
			//
			if (root instanceof PolicySetType) {
				XACMLPolicyWriter.writePolicyFile(Paths.get(this.file.getAbsolutePath()), (PolicySetType) root);
			} else if (root instanceof PolicyType) {
				XACMLPolicyWriter.writePolicyFile(Paths.get(this.file.getAbsolutePath()), (PolicyType) root);
			}
			//
			// TODO ????
			//
			this.gitContainer.updateItem(this.file);
			break; // NOPMD
		}
		//
		// No longer modified
		//
		this.isModified = false;
		this.setupCaption();
		this.resetComponents();
	}
	
	protected void installTreeActionHandler() {
		//
		// Remove any existing action handlers
		//
		this.tree.removeAllActionHandlers();
		//
		// Are we read-only?
		//
		if (this.isReadOnly()) {
			//
			// Yes - no action handler's allowed
			//
			return;
		}
		//
		// Setup our action handlers
		//
		this.tree.addActionHandler(new Handler() {
			private static final long serialVersionUID = 1L;

			@Override
			public Action[] getActions(Object target, Object sender) {
				//
				// Are we read-only?
				//
				if (self.isReadOnly()) {
					if (logger.isDebugEnabled()) {
						logger.debug("Policy is read-only");
					}
					return null;
				}
				if (target == null) {
					//
					// Nothing is selected, they right-clicked empty space
					//
					if (logger.isDebugEnabled()) {
						logger.debug("action tree target is null");
					}
					return null;
				}
				if (target instanceof PolicySetType) {
					List<Action> actions = new ArrayList<Action>();
					actions.add(EDIT_POLICYSET);
					if (((PolicySetType) target).getTarget() == null) {
						actions.add(CREATE_TARGET);
					}
					/*
					actions.add(CLIPBOARD_CUT);
					actions.add(CLIPBOARD_COPY);
					actions.add(CLIPBOARD_PASTE);
					*/
					actions.add(CREATE_POLICYSET);
					actions.add(CREATE_POLICY);
					actions.add(EDIT_OBLIGATIONS);
					actions.add(EDIT_ADVICE);
					actions.add(DELETE_POLICYSET);
					return (Action[]) actions.toArray(new Action[0]);
				}
				if (target instanceof PolicyType) {
					List<Action> actions = new ArrayList<Action>();
					actions.add(EDIT_POLICY);
					if (((PolicyType) target).getTarget() ==  null) {
						actions.add(CREATE_TARGET);
					}
					/*
					actions.add(CLIPBOARD_CUT);
					actions.add(CLIPBOARD_COPY);
					actions.add(CLIPBOARD_PASTE);
					*/
					actions.add(CREATE_RULE);
					actions.add(CREATE_VARIABLE);
					actions.add(EDIT_OBLIGATIONS);
					actions.add(EDIT_ADVICE);
					actions.add(DELETE_POLICY);
					return (Action[]) actions.toArray(new Action[0]);
				}
				if (target instanceof RuleType) {
					List<Action> actions = new ArrayList<Action>();
					actions.add(EDIT_RULE);
					if (((RuleType) target).getTarget() == null) {
						actions.add(CREATE_TARGET);
					}
					/*
					actions.add(CLIPBOARD_CUT);
					actions.add(CLIPBOARD_COPY);
					actions.add(CLIPBOARD_PASTE);
					*/
					if (((RuleType)target).getCondition() == null) {
						actions.add(CREATE_CONDITION);
					}
					actions.add(EDIT_OBLIGATIONS);
					actions.add(EDIT_ADVICE);
					actions.add(DELETE_RULE);
					return (Action[]) actions.toArray(new Action[0]);
				}
				if (target instanceof TargetType) {
					return new Action[] {CREATE_NEWANYOF};
				}
				if (target instanceof AnyOfType) {
					return new Action[] {CREATE_NEWALLOF, DELETE_ANYOF};
				}
				if (target instanceof AllOfType) {
					return new Action[] {CREATE_NEWMATCH, DELETE_ALLOF};
				}
				if (target instanceof MatchType) {
					return new Action[] {EDIT_MATCH, DELETE_MATCH};
				}
				if (target instanceof ConditionType) {
					return new Action[] {EDIT_CONDITION, DELETE_CONDITION};
				}
				if (target instanceof VariableDefinitionType) {
					return new Action[] {EDIT_VARIABLE, DELETE_VARIABLE};
				}
				if (target instanceof ObligationExpressionType) {
					return new Action[] {EDIT_OBLIGATIONS, DELETE_OBLIGATIONS};
				}
				if (target instanceof AdviceExpressionType) {
					return new Action[] {EDIT_ADVICE, DELETE_ADVICE};
				}
				return null;
			}
			
			@Override
			public void handleAction(Action action, Object sender, Object target) {
				if (action == CLIPBOARD_CUT) {
					assert target != null;
					self.clipboardObject = XACMLObjectCopy.deepCopy(target);
					self.removeObject(target);
					return;
				}
				if (action == CLIPBOARD_COPY) {
					assert target != null;
					self.clipboardObject = XACMLObjectCopy.deepCopy(target);
					return;
				}
				if (action == CLIPBOARD_PASTE) {
					assert target != null;
					self.clipboardPaste(target, true);
					return;
				}
				if (action == CREATE_POLICYSET) {
					assert target instanceof PolicySetType;
					self.editPolicySet(null, (PolicySetType) target);
					return;
				}
				if (action == CREATE_POLICY) {
					assert target instanceof PolicySetType;
					self.editPolicy(null, (PolicySetType) target);
					return;
				}
				if (action == CREATE_RULE) {
					assert target instanceof PolicyType;
					self.editRule(null, (PolicyType) target);
					return;
				}
				if (action == CREATE_TARGET) {
					assert target instanceof RuleType || target instanceof PolicyType || target instanceof PolicySetType;
					TargetType newTarget = new TargetType();
					self.policyContainer.addItem(newTarget, target);
					return;
				}
				if (action == EDIT_POLICYSET) {
					assert target instanceof PolicySetType;
					self.editPolicySet((PolicySetType) target, (PolicySetType) self.policyContainer.getParent(target));
					return;
				}
				if (action == EDIT_POLICY) {
					assert target instanceof PolicyType;
					self.editPolicy((PolicyType) target, (PolicySetType) self.policyContainer.getParent(target));
					return;
				}
				if (action == EDIT_RULE) {
					assert target instanceof RuleType;
					self.editRule((RuleType) target, (PolicyType) self.policyContainer.getParent(target));
					return;
				}				
				if (action == DELETE_POLICYSET) {
					assert target instanceof PolicySetType;
					self.removePolicySet((PolicySetType) target);
					return;
				}
				if (action == DELETE_POLICY) {
					assert target instanceof PolicyType;
					self.removePolicy((PolicyType) target);
					return;
				}
				if (action == DELETE_RULE) {
					assert target instanceof RuleType;
					self.removeRule((RuleType) target);
					return;
				}
				if (action == CREATE_NEWANYOF) {
					assert target instanceof TargetType;
					self.editMatch(null, null, null, (TargetType) target, "Create New Match");
					return;
				}
				if (action == CREATE_NEWALLOF) {
					assert target instanceof AnyOfType;
					self.editMatch(null, null, (AnyOfType) target, null, "Create New Match");
					return;
				}
				if (action == CREATE_NEWMATCH) {
					if (target instanceof AllOfType) {
						self.editMatch(null, (AllOfType) target, null, null, "Create New Match");
					} else if (target instanceof TargetType) {
						self.editMatch(null, null, null, (TargetType) target, "Create New Match");
					} else {
						assert false;
					}
					return;
				}
				if (action == DELETE_ANYOF) {
					assert target instanceof AnyOfType;
					self.removeAnyOf((AnyOfType) target, (TargetType) self.policyContainer.getParent(target));
					return;
				}
				if (action == DELETE_ALLOF) {
					assert target instanceof AllOfType;
					self.removeAllOf((AllOfType) target, (AnyOfType) self.policyContainer.getParent(target));
					return;
				}
				if (action == DELETE_MATCH) {
					assert target instanceof MatchType;
					self.removeMatch((MatchType) target, (AllOfType) self.policyContainer.getParent(target));
					return;
				}
				if (action == EDIT_MATCH) {
					assert target instanceof MatchType;
					self.editMatch((MatchType) target, (AllOfType) self.policyContainer.getParent(target), null, null, "Edit Match");
					return;
				}
				if (action == EDIT_OBLIGATIONS) {
					assert target instanceof RuleType || 
							target instanceof PolicyType || 
							target instanceof PolicySetType ||
							target instanceof ObligationExpressionType;
					if (target instanceof ObligationExpressionType) {
						self.editObAdvice(true, self.policyContainer.getParent(target));
					} else {
						self.editObAdvice(true, target);
					}
					return;
				}
				if (action == DELETE_OBLIGATIONS) {
					assert target instanceof ObligationExpressionType;
					self.removeObligations((ObligationExpressionType) target);
					return;
				}
				if (action == EDIT_ADVICE) {
					assert target instanceof RuleType || 
							target instanceof PolicyType || 
							target instanceof PolicySetType ||
							target instanceof AdviceExpressionType;
					if (target instanceof AdviceExpressionType) {
						self.editObAdvice(false, self.policyContainer.getParent(target));
					} else {
						self.editObAdvice(false, target);
					}
					return;
				}
				if (action == DELETE_ADVICE) {
					assert target instanceof AdviceExpressionType;
					self.removeAdvice((AdviceExpressionType) target);
					return;
				}
				if (action == CREATE_VARIABLE) {
					assert target instanceof PolicyType;
					self.editVariable(null, (PolicyType) target);
					return;
				}
				if (action == CREATE_CONDITION) {
					assert target instanceof RuleType;
					self.editCondition(null, (RuleType) target);
					return;
				}
				if (action == EDIT_CONDITION) {
					assert target instanceof ConditionType;
					self.editCondition((ConditionType) target, (RuleType) self.policyContainer.getParent(target));
					return;
				}
				if (action == DELETE_CONDITION) {
					assert target instanceof ConditionType;
					self.removeCondition((ConditionType) target);
					return;
				}
				if (action == EDIT_EXPRESSIONS) {
					return;
				}
				if (action == DELETE_VARIABLE) {
					assert target instanceof VariableDefinitionType;
					self.removeVariable((VariableDefinitionType) target);
					return;
				}
				if (action == EDIT_VARIABLE) {
					assert target instanceof VariableDefinitionType;
					self.editVariable((VariableDefinitionType) target, (PolicyType) self.policyContainer.getParent(target));
					return;
				}
			}
		});		
	}
	
	protected void resetComponents() {
		if (this.isReadOnly()) {
			this.checkBoxAutoSave.setEnabled(false);
			this.buttonSave.setEnabled(false);
			this.tree.setDragMode(TableDragMode.NONE);
			this.tree.removeAllActionHandlers();
			this.tree.setReadOnly(true);
		} else {
			this.checkBoxAutoSave.setEnabled(true);
			this.buttonSave.setEnabled(this.isModified);
			this.tree.setReadOnly(false);
			this.tree.setDragMode(TableDragMode.ROW);
			this.installTreeActionHandler();
		}
	}
		
	public void	setupCaption() {
		String caption = this.file.getName();
		if (this.isModified) {
			caption = caption + " *";
		}
		if (this.isReadOnly()) {
			caption = caption + " (Read-Only)";
		}
		if (this.tab != null) {
			this.tab.setCaption(caption);
		}
	}
	
	protected void editPolicySet(final PolicySetType policy, final PolicySetType parent) {
		logger.info("editPolicySet: " + policy + " parent " + parent);
		//
		// Create a copy
		//
		final PolicySetType newPolicySet = (policy == null ? new PolicySetType() : XACMLObjectCopy.copy(policy));
		//
		// Create window
		//
		final PolicySetEditorWindow window = new PolicySetEditorWindow(newPolicySet);
		window.setCaption(policy == null ? "Create New Policy Set" : "Edit Policy Set");
		window.setModal(true);
		window.addCloseListener(new CloseListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void windowClose(CloseEvent e) {
				//
				// Did the user click save?
				//
				if (window.isSaved() == false) {
					if (logger.isDebugEnabled()) {
						logger.debug("user did NOT save");
					}
					return;
				}
				//
				// Was it a new Policy Set?
				//
				if (policy == null) {
					logger.info("adding new policy set " + newPolicySet.getPolicySetId());
					//
					// Yes - new add it in
					//
					if (newPolicySet.getTarget() == null) {
						newPolicySet.setTarget(new TargetType());
					}
					if (self.policyContainer.addItem(newPolicySet, parent) == null) {
						logger.error("Failed to add new policy set");
					} else {
						self.tree.setCollapsed(parent, false);
						self.tree.setCollapsed(newPolicySet, false);
						self.tree.select(newPolicySet);
					}
				} else {
					logger.info("updating new policy set " + newPolicySet.getPolicySetId());
					//
					// No - copy everything
					//
					policy.setDescription(newPolicySet.getDescription());
					policy.setVersion(newPolicySet.getVersion());
					policy.setPolicyCombiningAlgId(newPolicySet.getPolicyCombiningAlgId());
					//
					// Update
					//
					self.policyContainer.updateItem(policy);
				}
			}			
		});
		window.center();
		UI.getCurrent().addWindow(window);
	}
	
	protected void editPolicy(final PolicyType policy, final PolicySetType parent) {
		//
		// Create a copy
		//
		final PolicyType newPolicy = (policy == null ? new PolicyType() : XACMLObjectCopy.copy(policy));
		//
		// Create window
		//
		final PolicyEditorWindow window = new PolicyEditorWindow(newPolicy);
		window.setCaption(policy == null ? "Create New Policy" : "Edit Policy");
		window.setModal(true);
		window.addCloseListener(new CloseListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void windowClose(CloseEvent e) {
				//
				// Did the user click save?
				//
				if (window.isSaved() == false) {
					return;
				}
				//
				// Was it a new Policy?
				//
				if (policy == null) {
					//
					// Yes - new add it in
					//
					if (newPolicy.getTarget() == null) {
						newPolicy.setTarget(new TargetType());
					}
					if (self.policyContainer.addItem(newPolicy, parent) == null) {
						logger.error("Failed to add policy");
					} else {
						self.tree.setCollapsed(parent, false);
						self.tree.setCollapsed(newPolicy, false);
						self.tree.select(newPolicy);
					}
				} else {
					//
					// No - copy everything
					//
					policy.setDescription(newPolicy.getDescription());
					policy.setVersion(newPolicy.getVersion());
					policy.setRuleCombiningAlgId(newPolicy.getRuleCombiningAlgId());
					//
					// Update
					//
					self.policyContainer.updateItem(policy);
				}
			}			
		});
		window.center();
		UI.getCurrent().addWindow(window);
	}
	
	protected void editRule(final RuleType rule, final PolicyType parent) {
		//
		// Create a copy
		//
		final RuleType newRule = (rule == null ? new RuleType() : XACMLObjectCopy.copy(rule));
		//
		// Create window
		//
		final RuleEditorWindow window = new RuleEditorWindow(newRule);
		window.setCaption(rule == null ? "Create New Rule" : "Edit Rule");
		window.setModal(true);
		window.addCloseListener(new CloseListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void windowClose(CloseEvent e) {
				//
				// Did the user click save?
				//
				if (window.isSaved() == false) {
					return;
				}
				//
				// Was this a new rule?
				//
				if (rule == null) {
					//
					// Yes a new rule
					//
					if (newRule.getTarget() == null) {
						newRule.setTarget(new TargetType());
					}
					if (self.policyContainer.addItem(newRule, parent) == null) {
						logger.error("Failed to add new rule");
					} else {
						self.tree.setCollapsed(parent, false);
						self.tree.setCollapsed(newRule, false);
						self.tree.select(newRule);
					}
				} else {
					//
					// No - editing existing rule. Copy everything
					//
					rule.setEffect(newRule.getEffect());
					rule.setDescription(newRule.getDescription());
					self.policyContainer.updateItem(rule);
				}
			}
		});
		window.center();
		UI.getCurrent().addWindow(window);
	}

	protected void editCondition(final ConditionType condition, final RuleType rule) {
		//
		// Make a copy of it first, in case the user manipulates it
		// and then decides to NOT save it
		//
		final ConditionType copyCondition = (condition == null ? new ConditionType() : XACMLObjectCopy.copy(condition));
		//
		// Create the window
		//
		final ExpressionBuilderComponent expression = new ExpressionBuilderComponent(copyCondition, 
											(copyCondition.getExpression() != null ? copyCondition.getExpression().getValue() : null), 
											null,
											self.policyContainer.getVariables());
		if (condition == null) {
			expression.setCaption("Create An Expression For The Condition");
		} else {
			expression.setCaption("Edit The Condition Expression");
		}
		expression.setModal(true);
		//
		// Add the close listener
		//
		expression.addCloseListener(new CloseListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void windowClose(CloseEvent e) {
				//
				// Did the user hit save?
				//
				if (expression.isSaved() == false) {
					return;
				}
				//
				// Were we creating something new?
				//
				if (condition == null) {
					//
					// Yes add the new one into the container
					//
					if (self.policyContainer.addItem(copyCondition, rule) == null) {
						logger.error("Failed to add condition");
					} else {
						self.tree.setCollapsed(rule, false);
						self.tree.setCollapsed(copyCondition, false);
						self.tree.select(copyCondition);
					}
				} else {
					//
					// We were editing an existing condition, so copy
					// over the new edited expression.
					//
					condition.setExpression(copyCondition.getExpression());
					//
					// Update the container
					//
					self.policyContainer.updateItem(condition);
				}
			}			
		});
		expression.center();
		UI.getCurrent().addWindow(expression);
	}

	protected void editVariable(final VariableDefinitionType variable, final PolicyType parent) {
		//
		// Make a copy of it first, in case the user manipulates it
		// and then decides to NOT save it
		//
		final VariableDefinitionType copyVariable = (variable == null ? new VariableDefinitionType(): XACMLObjectCopy.copy(variable));
		//
		// Have the user create or edit the Variables ID
		//
		final VariableDefinitionEditorWindow editor = new VariableDefinitionEditorWindow(copyVariable);
		if (variable == null) {
			editor.setCaption("Create Variable");			
		} else {
			editor.setCaption("Edit Variable" + (copyVariable.getVariableId() == null ? "" : copyVariable.getVariableId()));
		}
		editor.setModal(true);
		editor.addCloseListener(new CloseListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void windowClose(CloseEvent e) {
				//
				// Did the user click save button?
				//
				if (editor.isSaved() == false) {
					return;
				}
				//
				// Create the window
				//
				final ExpressionBuilderComponent expression = new ExpressionBuilderComponent(copyVariable, 
													(copyVariable.getExpression() != null ? copyVariable.getExpression().getValue() : null), 
													null, 
													self.policyContainer.getVariables());
				expression.setCaption("Edit The Variable \"" + copyVariable.getVariableId() + "\" Expression");
				//
				// Add the close listener
				//
				expression.addCloseListener(new CloseListener() {
					private static final long serialVersionUID = 1L;
		
					@Override
					public void windowClose(CloseEvent e) {
						//
						// Did the user click save button?
						//
						if (expression.isSaved() == false) {
							return;
						}
						//
						// Was it a new variable or were we editing an existing one?
						//
						if (variable == null) {
							//
							// New one, add it to the container
							//
							if (self.policyContainer.addItem(copyVariable, parent) == null) {
								logger.error("Failed to add variable");
							} else {
								self.tree.setCollapsed(parent, false);
								self.tree.setCollapsed(copyVariable, false);
								self.tree.select(copyVariable);
							}
						} else {
							//
							// We were editing one, copy it back over.
							//
							variable.setVariableId(copyVariable.getVariableId());
							variable.setExpression(copyVariable.getExpression());
							//
							// Update the container
							//
							self.policyContainer.updateItem(variable);
						}
					}
				});
				expression.center();
				UI.getCurrent().addWindow(expression);
			}
		});
		editor.center();
		UI.getCurrent().addWindow(editor);
	}

	protected void editMatch(final MatchType match, final AllOfType allOf, final AnyOfType anyOf, final TargetType target, final String caption) {
		//
		// Create an empty match or copy the one we are going to edit.
		//
		final MatchType newMatch = (match == null ? new MatchType() : XACMLObjectCopy.copy(match));
		//
		// Have user select an attribute
		//
		final AttributeSelectionWindow selection = new AttributeSelectionWindow(null, 
									(newMatch.getAttributeDesignator() != null ? newMatch.getAttributeDesignator() : newMatch.getAttributeSelector()));
		selection.setCaption("Select Attribute To Match Against");
		selection.setModal(true);
		selection.addCloseListener(new CloseListener() {
			private static final long serialVersionUID = 1L;
			
			@Override
			public void windowClose(CloseEvent event) {
				//
				// Did the user save anything?
				//
				if (selection.isSaved() == false) {
					return;
				}
				//
				// Save the selected attribute
				//
				final Attribute attribute = selection.getAttribute();
				if (attribute.isDesignator()) {
					newMatch.setAttributeDesignator(JPAUtils.createDesignator(attribute));
				} else {
					newMatch.setAttributeSelector(JPAUtils.createSelector(attribute));
				}
				//
				// Yes - now match it up to a function
				//
				final MatchEditorWindow editor = new MatchEditorWindow(newMatch, attribute.getDatatypeBean());
				editor.setCaption(caption);
				editor.setModal(true);
				editor.addCloseListener(new CloseListener() {
					private static final long serialVersionUID = 1L;
					
					@Override
					public void windowClose(CloseEvent event) {
						//
						// Did the user hit save?
						//
						if (editor.isSaved() == false) {
							return;
						}
						//
						// Yes - now we need the value to check the attribute against
						//
						final AttributeValueType copyAttributeValue = (newMatch.getAttributeValue() == null ? new AttributeValueType() : newMatch.getAttributeValue());
//						String currentValue = null;
//						if (newMatch.getAttributeValue() != null) {
//							currentValue = XACMLObjectCopy.getContent(newMatch.getAttributeValue().getContent());
//						}
						final AttributeValueEditorWindow value = new AttributeValueEditorWindow(copyAttributeValue, attribute.getDatatypeBean());
						value.setCaption("Set the value the attribute should match against.");
						value.setModal(true);
						value.addCloseListener(new CloseListener() {
							private static final long serialVersionUID = 1L;
							
							@Override
							public void windowClose(CloseEvent event) {
								//
								// Did the user save?
								//
								if (value.isSaved() == false) {
									return;
								}
								//
								// Yes - copy the value into the match
								//
								AttributeValueType val = new AttributeValueType();
								val.getContent().add(value.getValue());
								val.setDataType(value.getDatatype().getXacmlId());
								newMatch.setAttributeValue(val);
								//
								// Was this a new match or were we editing an
								// existing match?
								//
								if (match != null) {
									//
									// Editing - now we can save it
									//
									match.setAttributeDesignator(newMatch.getAttributeDesignator());
									match.setAttributeSelector(newMatch.getAttributeSelector());
									match.setAttributeValue(newMatch.getAttributeValue());
									match.setMatchId(newMatch.getMatchId());
									//
									// Update the container
									//
									self.policyContainer.updateItem(match);
								} else {
									//
									// Do we have a parent(s)?
									//
									AllOfType allOfParent = allOf;
									AnyOfType anyOfParent = anyOf;
									if (allOfParent == null) {
										//
										// No direct AllOfParent
										//
										if (anyOfParent == null) {
											//
											// No AnyOfParent
											//
											if (target == null) {
												logger.error("We should NOT get this");
												return;
											}
											anyOfParent = new AnyOfType();
											if (self.policyContainer.addItem(anyOfParent, target) == null) {
												logger.error("Failed to add anyOf parent");
												assert false;
											}
											self.tree.setCollapsed(anyOfParent, false);
										}
										allOfParent = new AllOfType();
										if (self.policyContainer.addItem(allOfParent, anyOfParent) == null) {
											logger.error("Failed to add allOf parent");
											assert false;
										}
										self.tree.setCollapsed(allOfParent, false);
									}
									//
									// Add the MatchType into the Tree
									//
									if (self.policyContainer.addItem(newMatch, allOfParent) == null) {
										logger.error("Failed to add match");
										assert false;
									}
									self.tree.select(newMatch);
								}
							}								
						});
						value.center();
						UI.getCurrent().addWindow(value);
					}
				});
				editor.center();
				UI.getCurrent().addWindow(editor);
			}
		});
		selection.center();
		UI.getCurrent().addWindow(selection);
	}
	
	protected void deleteRoot(Object root) {
		//
		// TODO - prompt user for new root object
		//
		
	}
	
	protected void editObAdvice(boolean isObligation, final Object target) {
		//
		// Get the object
		//
		String caption;
		Object expressionsObject = null;
		if (target instanceof RuleType) {
			if (isObligation) {
				expressionsObject = ((RuleType) target).getObligationExpressions();
				if (expressionsObject == null) {
					caption = "Create New Obligation for Rule";
				} else {
					caption = "Edit Obligations for Rule"; 
				}
			} else {
				expressionsObject = ((RuleType) target).getAdviceExpressions();
				if (expressionsObject == null) {
					caption = "Create New Advice for Rule";
				} else {
					caption = "Edit Advice for Rule"; 
				}
			}
		} else if (target instanceof PolicyType) {
			if (isObligation) {
				expressionsObject = ((PolicyType) target).getObligationExpressions();
				if (expressionsObject == null) {
					caption = "Create New Obligation for Policy";
				} else {
					caption = "Edit Obligations for Policy"; 
				}
			} else {
				expressionsObject = ((PolicyType) target).getAdviceExpressions();
				if (expressionsObject == null) {
					caption = "Create New Advice for Policy";
				} else {
					caption = "Edit Advice for Policy"; 
				}
			}
		} else if (target instanceof PolicySetType) {
			if (isObligation) {
				expressionsObject = ((PolicySetType) target).getObligationExpressions();
				if (expressionsObject == null) {
					caption = "Create New Obligation for Policy Set";
				} else {
					caption = "Edit Obligation for Policy Set"; 
				}
			} else {
				expressionsObject = ((PolicySetType) target).getAdviceExpressions();
				if (expressionsObject == null) {
					caption = "Create New Advice for Policy Set";
				} else {
					caption = "Edit Advice for Policy Set"; 
				}
			}
		} else {
			throw new IllegalArgumentException("Expected a rule/policy/policyset.");
		}
		//
		// Make a copy
		//
		final Object originalExpressions = expressionsObject;
		final Object copyExpression = (originalExpressions == null 
										? (isObligation ? new ObligationExpressionsType() : new AdviceExpressionsType())
										: originalExpressions instanceof ObligationExpressionsType 
												? XACMLObjectCopy.copy((ObligationExpressionsType) originalExpressions)
												: XACMLObjectCopy.copy((AdviceExpressionsType) originalExpressions))
										;
		//
		// Invoke the editor window
		//
		final ObligationAdviceEditorWindow window = new ObligationAdviceEditorWindow(copyExpression, this.policyContainer.getVariables());
		window.setCaption(caption);
		window.setModal(true);
		window.addCloseListener(new CloseListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void windowClose(CloseEvent e) {
				//
				// Did the user save?
				//
				if (window.isSaved() == false) {
					return;
				}
				//
				// It was saved - is this a new object?
				//
				if (originalExpressions == null) {
					//
					// New object
					//
					if (self.policyContainer.addItem(copyExpression, target) == null) {
						logger.error("Failed to add expression");
						assert false;
					}
				} else {
					//
					// Editing an existing object.
					//
					if (originalExpressions instanceof ObligationExpressionsType) {
						//
						// Remove old obligations
						//
						while (((ObligationExpressionsType) originalExpressions).getObligationExpression().isEmpty() == false) {
//						for (ObligationExpressionType old : ((ObligationExpressionsType) originalExpressions).getObligationExpression()) {
							ObligationExpressionType old  = ((ObligationExpressionsType) originalExpressions).getObligationExpression().get(0);
							self.policyContainer.removeItem(old);
						}
						//
						// Copy new ones in
						//
						for (ObligationExpressionType newObligation : ((ObligationExpressionsType) copyExpression).getObligationExpression()) {
							self.policyContainer.addItem(newObligation, (ObligationExpressionsType) originalExpressions);
						}
					} else if (originalExpressions instanceof AdviceExpressionsType) {
						((AdviceExpressionsType) originalExpressions).getAdviceExpression().clear();
						((AdviceExpressionsType) originalExpressions).getAdviceExpression().addAll(((AdviceExpressionsType) copyExpression).getAdviceExpression());
					}
				}
			}
		});
		window.center();
		UI.getCurrent().addWindow(window);
	}
	
	protected void removeMatch(MatchType match, AllOfType parent) {
		assert match != null && parent != null;
		if (self.policyContainer.removeItem(match) == false) {
			logger.error("Failed to remove match");
			assert false;
		}
		//
		// Check for empty AllOf's
		//
		if (parent.getMatch().isEmpty()) {
			this.removeAllOf(parent, (AnyOfType) this.policyContainer.getParent(parent));
		}
	}

	protected void removeAllOf(AllOfType allOf, AnyOfType parent) {
		assert allOf != null && parent != null;
		if (self.policyContainer.removeItem(allOf) == false) {
			logger.error("Failed to remove AllOf");
			assert false;
		}
		//
		// Check for empty AnyOf's
		//
		if (parent.getAllOf().isEmpty()) {
			this.removeAnyOf(parent, (TargetType) this.policyContainer.getParent(parent));
		}
	}

	protected void removeAnyOf(AnyOfType anyOf, TargetType parent) {
		assert anyOf != null && parent != null;
		if (self.policyContainer.removeItem(anyOf) == false) {
			logger.error("Failed to remove anyOf");
			assert false;
		}
	}

	protected boolean clipboardPaste(final Object target, boolean performPaste) {
		if (this.clipboardObject == null) {
			if (logger.isDebugEnabled()) {
				logger.debug("nothing in clipboard.");
			}
			return false;
		}
		boolean doPaste = false;
		if (this.clipboardObject instanceof PolicySetType && target instanceof PolicySetType) {
			doPaste = true;
		}
		if (this.clipboardObject instanceof PolicyType && target instanceof PolicySetType) {
			doPaste = true;
		}
		if (this.clipboardObject instanceof RuleType && target instanceof PolicyType) {
			doPaste = true;
		}
		if (doPaste == false) {
			//
			// Pasting clipboard object onto target not
			// possible.
			//
			return false;
		}
		if (performPaste == false) {
			//
			// They did not ask to do the actual paste,
			// but the called wanted to know if it was
			// possible.
			//
			return true;
		}
		//
		// Do the actual paste
		//
		Item item = this.policyContainer.addItem(XACMLObjectCopy.deepCopy(this.clipboardObject), target);
		assert item != null;
		this.tree.select(this.clipboardObject);
		
		return true;
	}
	
	@AutoGenerated
	private VerticalLayout buildMainLayout() {
		// common part: create layout
		mainLayout = new VerticalLayout();
		mainLayout.setImmediate(false);
		mainLayout.setWidth("-1px");
		mainLayout.setHeight("100.0%");
		mainLayout.setMargin(false);
		mainLayout.setSpacing(true);
		
		// top-level component properties
		setWidth("-1px");
		setHeight("100.0%");
		
		// horizontalLayoutToolbar
		horizontalLayoutToolbar = buildHorizontalLayoutToolbar();
		mainLayout.addComponent(horizontalLayoutToolbar);
		mainLayout.setExpandRatio(horizontalLayoutToolbar, 1.0f);
		
		// tree
		tree = new TreeTable();
		tree.setImmediate(true);
		tree.setWidth("100.0%");
		tree.setHeight("100.0%");
		mainLayout.addComponent(tree);
		mainLayout.setExpandRatio(tree, 1.0f);
		
		return mainLayout;
	}

	@AutoGenerated
	private HorizontalLayout buildHorizontalLayoutToolbar() {
		// common part: create layout
		horizontalLayoutToolbar = new HorizontalLayout();
		horizontalLayoutToolbar.setImmediate(false);
		horizontalLayoutToolbar.setWidth("-1px");
		horizontalLayoutToolbar.setHeight("-1px");
		horizontalLayoutToolbar.setMargin(true);
		horizontalLayoutToolbar.setSpacing(true);
		
		// checkBoxReadOnly
		checkBoxReadOnly = new CheckBox();
		checkBoxReadOnly.setCaption("Read Only");
		checkBoxReadOnly.setImmediate(false);
		checkBoxReadOnly
				.setDescription("Check this to turn-off policy editing.");
		checkBoxReadOnly.setWidth("-1px");
		checkBoxReadOnly.setHeight("-1px");
		horizontalLayoutToolbar.addComponent(checkBoxReadOnly);
		
		// checkBoxAutoSave
		checkBoxAutoSave = new CheckBox();
		checkBoxAutoSave.setCaption("Auto Save");
		checkBoxAutoSave.setImmediate(false);
		checkBoxAutoSave
				.setDescription("Check this to turn-on automatic saving of policy when a change occurs.");
		checkBoxAutoSave.setWidth("-1px");
		checkBoxAutoSave.setHeight("-1px");
		horizontalLayoutToolbar.addComponent(checkBoxAutoSave);
		
		// buttonSave
		buttonSave = new Button();
		buttonSave.setCaption("Save");
		buttonSave.setImmediate(true);
		buttonSave.setDescription("Click to save the policy.");
		buttonSave.setWidth("-1px");
		buttonSave.setHeight("-1px");
		horizontalLayoutToolbar.addComponent(buttonSave);
		
		// buttonViewXML
		buttonViewXML = new Button();
		buttonViewXML.setCaption("View XML");
		buttonViewXML.setImmediate(true);
		buttonViewXML.setWidth("-1px");
		buttonViewXML.setHeight("-1px");
		horizontalLayoutToolbar.addComponent(buttonViewXML);
		
		// buttonExport
		buttonExport = new Button();
		buttonExport.setCaption("Export Policy");
		buttonExport.setImmediate(false);
		buttonExport.setWidth("-1px");
		buttonExport.setHeight("-1px");
		horizontalLayoutToolbar.addComponent(buttonExport);
		
		return horizontalLayoutToolbar;
	}
}
