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

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

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.vaadin.dialogs.ConfirmDialog;
import org.vaadin.dialogs.ConfirmDialog.ContentMode;

import org.apache.openaz.xacml.admin.XacmlAdminAuthorization;
import org.apache.openaz.xacml.admin.XacmlAdminUI;
import org.apache.openaz.xacml.admin.model.PDPContainer;
import org.apache.openaz.xacml.admin.model.PDPGroupContainer;
import org.apache.openaz.xacml.admin.model.PDPPIPContainer;
import org.apache.openaz.xacml.admin.model.PDPPolicyContainer;
import org.apache.openaz.xacml.admin.util.AdminNotification;
import org.apache.openaz.xacml.admin.view.windows.EditPDPGroupWindow;
import org.apache.openaz.xacml.admin.view.windows.EditPDPWindow;
import org.apache.openaz.xacml.admin.view.windows.PDPStatusWindow;
import org.apache.openaz.xacml.admin.view.windows.SelectPDPGroupWindow;
import org.apache.openaz.xacml.api.pap.PAPEngine;
import org.apache.openaz.xacml.api.pap.PAPException;
import org.apache.openaz.xacml.api.pap.PDP;
import org.apache.openaz.xacml.api.pap.PDPGroup;
import org.apache.openaz.xacml.api.pap.PDPGroupStatus;
import org.apache.openaz.xacml.api.pap.PDPStatus;
import org.apache.openaz.xacml.std.pap.StdPDPGroup;
import com.vaadin.annotations.AutoGenerated;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.Property.ValueChangeListener;
import com.vaadin.event.Action;
import com.vaadin.event.Action.Handler;
import com.vaadin.event.ItemClickEvent;
import com.vaadin.event.ItemClickEvent.ItemClickListener;
import com.vaadin.event.ShortcutAction.KeyCode;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.Table;
import com.vaadin.ui.Table.ColumnGenerator;
import com.vaadin.ui.TextArea;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window.CloseEvent;
import com.vaadin.ui.Window.CloseListener;


public class PDPManagement extends CustomComponent {

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

	@AutoGenerated
	private VerticalLayout mainLayout;

	@AutoGenerated
	private Table table;

	@AutoGenerated
	private HorizontalLayout horizontalLayoutToolbar;

	@AutoGenerated
	private Button buttonRemove;

	@AutoGenerated
	private Button buttonCreate;

	private static final long serialVersionUID = 1L;
	private final PDPManagement self = this;
	private static final Log logger	= LogFactory.getLog(PDPManagement.class);
	
	private PDPGroupContainer container;
	
	private static final Action CREATE_GROUP = 	new Action ("Create Group");
	private static final Action REPAIR_GROUP = 	new Action ("Repair Group");
	private static final Action EDIT_GROUP = 	new Action ("Edit Group");
	private static final Action DELETE_GROUP = 	new Action ("Delete Group");
	private static final Action SYNCHRONIZE = 	new Action ("Synchronize");
	private static final Action MAKE_DEFAULT = 	new Action ("Make Default");
	private static final Action CREATE_PDP = 	new Action ("Create PDP");
	private static final Action EDIT_PDP = 		new Action ("Edit PDP");
	private static final Action DELETE_PDP = 	new Action ("Delete PDP");
	private static final Action MOVE_PDP = 		new Action ("Move PDP");
	private static final Action GET_PDP_STATUS = new Action ("View Status");
	
	private PAPEngine papEngine;

	/**
	 * The constructor should first build the main layout, set the
	 * composition root and then do any custom initialization.
	 *
	 * The constructor will not be automatically regenerated by the
	 * visual editor.
	 */
	public PDPManagement(PAPEngine engine) {
		buildMainLayout();
		setCompositionRoot(mainLayout);
		//
		// Initialize
		//
		this.papEngine = engine;
		//
		// Initialize
		//
		this.initialize();
		//
		// setup the buttons
		//
		this.setupButtons();
	}
	
	protected void initialize() {
		//
		// Don't create a container if the engine doesn't exist
		//
		if (this.papEngine == null) {
			//
			// remove all the components
			//
			this.mainLayout.removeAllComponents();
			//
			// Add a label
			//
			this.mainLayout.addComponent(new Label("PDP Management unavailable - PAP servlet unavailable."));
			//
			// done
			//
			return;
		}
		//
		// Create our container
		//
		this.container = new PDPGroupContainer(this.papEngine);
		//
		// Determine authorization level
		//
		boolean isAdmin = ((XacmlAdminUI)UI.getCurrent()).isAuthorized( 
				XacmlAdminAuthorization.AdminAction.ACTION_ADMIN, 
				XacmlAdminAuthorization.AdminResource.RESOURCE_PDP_ADMIN);
		try {
			this.initializeTree(isAdmin);
			this.initializeButtons(isAdmin);
		} catch (Exception e) {
			logger.error("UNABLE TO START PDPManagement: " + e, e);
			// check if PAP servlet is up
			try {
				Set<PDPGroup> groups = this.papEngine.getPDPGroups();
				if (groups == null) {
					throw new PAPException("PAP not running");
				}
			} catch (PAPException | NullPointerException e1) {
				setCompositionRoot(new Label("Cannot use PDP Management because the PAP servlet was not running when Admin Console Servlet first initialized."));
				return;
			}
			setCompositionRoot(new Label("Cannot use PDP Management because of error during initialization: " + e.getMessage()));
		}
	}
	
	protected void initializeTree(final boolean isAdmin) {
		//
		// Set the data source
		//
		this.table.setContainerDataSource(this.container);
		//
		// Setup the GUI properties
		//
		this.table.setVisibleColumns("Name", "Description", "Status", "Default", "PDPs", "Policies", "PIP Configurations");
		this.table.setColumnHeaders("Name", "Description", "Status", "Default", "PDP's", "Policies", "PIP Configurations");
		//
		// The description should be a text area
		//
		this.table.addGeneratedColumn("Description", new ColumnGenerator() {
			private static final long serialVersionUID = 1L;

			@Override
			public Object generateCell(Table source, Object itemId, Object columnId) {
				TextArea area = new TextArea();
				area.setValue(((PDPGroup) itemId).getDescription());
				area.setReadOnly(true);
				return area;
			}
			
		});
		//
		// Generate a GUI element for the PDP's
		//
		this.table.addGeneratedColumn("PDPs", new ColumnGenerator() {
			private static final long serialVersionUID = 1L;

			@Override
			public Object generateCell(Table source, Object itemId, Object columnId) {
	        	final Table table = new Table();
	        	final PDPContainer container = new PDPContainer((PDPGroup) itemId);
	        	//
	        	// Setup the container data
	        	//
	        	table.setContainerDataSource(container);
	        	//
	        	// Save the group for easy access
	        	//
	        	table.setData(itemId);
	        	//
	        	// GUI properties
	        	//
	        	table.setPageLength(table.getContainerDataSource().size() + 2);
	        	table.setVisibleColumns("Name", "Status", "Description");
				table.setColumnCollapsingAllowed(true);
				table.setColumnCollapsed("Description", true);
				table.setWidth("100%");
				//
				// If an admin, then it is editable
				//
				if (isAdmin) {
					//
					// Set it as selectable
					//
					table.setSelectable(true);
					//
					// Add actions
					//
					table.addActionHandler(new Handler() {
						private static final long serialVersionUID = 1L;

						@Override
						public Action[] getActions(Object target, Object sender) {
							if (target == null) {
								return new Action[] {CREATE_PDP};
							}
							if (target instanceof PDP) {
								if (self.container.size() > 1) {
									return new Action[] {EDIT_PDP, GET_PDP_STATUS, MOVE_PDP, DELETE_PDP};
								} else {
									return new Action[] {EDIT_PDP, GET_PDP_STATUS, DELETE_PDP};
								}
							}
							return null;
						}

						@Override
						public void handleAction(Action action, Object sender, Object target) {
							if (action == CREATE_PDP) {
								self.editPDP(null, (PDPGroup) table.getData());
								return;
							}
							if (action == EDIT_PDP) {
								assert target instanceof PDP;
								self.editPDP((PDP) target, (PDPGroup) table.getData());
								return;
							}
							if (action == MOVE_PDP) {
								assert target instanceof PDP;
								self.movePDP((PDP) target, (PDPGroup) table.getData());
								return;
							}
							if (action == DELETE_PDP) {
								assert target instanceof PDP;
								self.deletePDP((PDP) target, (PDPGroup) table.getData());
								return;
							}
							if (action == GET_PDP_STATUS) {
								assert target instanceof PDP;
								self.getPDPStatus((PDP) target, (PDPGroup) table.getData());
							}
						}
					});
					//
					// Respond to events
					//
					table.addItemClickListener(new ItemClickListener() {
						private static final long serialVersionUID = 1L;

						@Override
						public void itemClick(ItemClickEvent event) {
							if (event.isDoubleClick()) {
								self.editPDP((PDP) event.getItemId(), (PDPGroup) table.getData());
							}
						}
					});
				}
	        	return table;
			}
		});
		//
		// Generate a GUI element for the policies
		//
		this.table.addGeneratedColumn("Policies", new ColumnGenerator() {
			private static final long serialVersionUID = 1L;

			@Override
			public Object generateCell(Table source, Object itemId, Object columnId) {
	        	Table table = new Table();
	        	table.setContainerDataSource(new PDPPolicyContainer((PDPGroup) itemId));
	        	table.setPageLength(table.getContainerDataSource().size() + 2);

	        	table.setVisibleColumns("Root", "Name", "Version", "Description");
				table.setColumnCollapsingAllowed(true);
				table.setColumnCollapsed("Description", true);

				table.setWidth("100%");

	        	return table;
			}
		});
		//
		// Generate a GUI element for the PIP configurations
		//
		this.table.addGeneratedColumn("PIP Configurations", new ColumnGenerator() {
			private static final long serialVersionUID = 1L;

			@Override
			public Object generateCell(Table source, Object itemId, Object columnId) {
	        	Table table = new Table();
				if (itemId instanceof PDPGroup) {
		        	table.setContainerDataSource(new PDPPIPContainer((PDPGroup) itemId));
		        	table.setPageLength(table.getContainerDataSource().size() + 2);
				}
				if (itemId instanceof PDP) {
		        	table.setContainerDataSource(new PDPPIPContainer((PDP) itemId));
		        	table.setVisible(false);
		        	table.setPageLength(0);
				}
				table.setVisibleColumns("Name", "Description");
				table.setColumnCollapsingAllowed(true);
				table.setColumnCollapsed("Description", true);
				
				table.setWidth("100%");

	        	return table;
			}
		});
		//
		// Check the user's authorization level
		//
		if (((XacmlAdminUI)UI.getCurrent()).isAuthorized( 
				XacmlAdminAuthorization.AdminAction.ACTION_ADMIN, 
				XacmlAdminAuthorization.AdminResource.RESOURCE_PDP_ADMIN)) {
			this.table.setSelectable(true);
		} else {
			if (logger.isDebugEnabled()) {
				logger.debug("No admin access to pdp management");
			}
			return;
		}
		//
		// Setup Action Handlers
		//
		this.table.addActionHandler(new Handler() {
			private static final long serialVersionUID = 1L;

			@Override
			public Action[] getActions(Object target, Object sender) {
				if (target == null) {
					//
					// Nothing is selected, they right-clicked empty space.
					// Only one action.
					//
					return new Action[] {CREATE_GROUP};
				}
				if (target instanceof PDPGroup) {
					List<Action> actions = new ArrayList<Action>();
					PDPGroupStatus.Status status = ((PDPGroup)target).getStatus().getStatus();
					if (status == PDPGroupStatus.Status.LOAD_ERRORS) {
						actions.add(REPAIR_GROUP);
					}
					if (((PDPGroup)target).isDefaultGroup() == false) {
						actions.add(MAKE_DEFAULT);
					}
					actions.add(EDIT_GROUP);
					if (status == PDPGroupStatus.Status.OUT_OF_SYNCH) {
						actions.add(SYNCHRONIZE);
					}
					if (((PDPGroup)target).isDefaultGroup() == false) {
						actions.add(DELETE_GROUP);
					}
					actions.add(CREATE_PDP);
					// Throws a class cast exception
//					return (Action[]) actions.toArray();
					Action[] actions2 = new Action[actions.size()];
					int index = 0;
					for (Action a : actions) {
						actions2[index++] = a;
					}
					return actions2;
				}
				return null;
			}

			@Override
			public void handleAction(Action action, Object sender, Object target) {
				if (action == CREATE_GROUP) {
					self.editPDPGroup(null);
					return;
				}
				if (action == EDIT_GROUP) {
					assert target instanceof PDPGroup;
					self.editPDPGroup((PDPGroup) target);
					return;
				}
				if (action == DELETE_GROUP) {
					self.deleteGroup((PDPGroup) target);
					return;
				}
				if (action == REPAIR_GROUP) {
					if (target instanceof PDPGroup) {
						((PDPGroup) target).repair();
					} else {
						String message = "Action '" + REPAIR_GROUP.getCaption() + "' called on non-group target '" + target + "'";
						logger.error(message);
						AdminNotification.error(message);
					}
					return;
				}
				if (action == MAKE_DEFAULT) {
					if (target instanceof PDPGroup) {
						try {
							self.container.makeDefault((PDPGroup) target);
						} catch (Exception e) {
							AdminNotification.error("Make Default failed. Reason:\n" + e.getMessage());
						}
					} else {
						String message = "Action '" + MAKE_DEFAULT.getCaption() + "' called on non-group target '" + target + "'";
						logger.error(message);
						AdminNotification.error(message);
					}
					return;
				}
				if (action == SYNCHRONIZE) {
					if (target instanceof PDPGroup) {
logger.error("SYNCHRONIZE NOT YET IMPLMENTED");
AdminNotification.error("Synchronize not yet implemented");
					} else {
						String message = "Action '" + SYNCHRONIZE.getCaption() + "' called on non-group target '" + target + "'";
						logger.error(message);
						AdminNotification.error(message);
					}
					return;
				}
				if (action == CREATE_PDP) {
					if (target instanceof PDPGroup) {
						self.editPDP(null, ((PDPGroup)target));
					} else {
						String message = "Action '" + CREATE_PDP.getCaption() + "' called on non-group target '" + target + "'";
						logger.error(message);
						AdminNotification.error(message);
					}
					return;
				}
			}
		});
		//
		// Listen for item change notifications
		//
		this.table.addItemClickListener(new ItemClickListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void itemClick(ItemClickEvent event) {
				if (event.isDoubleClick()) {
					assert event.getItemId() instanceof PDPGroup;
					self.editPDPGroup((PDPGroup) event.getItemId());
				}
			}
		});
		//
		// Respond to selection events
		//
		this.table.addValueChangeListener(new ValueChangeListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void valueChange(ValueChangeEvent event) {
				Object id = self.table.getValue();
				if (id == null) {
					self.buttonRemove.setEnabled(false);
				} else {
					//
					// Make sure its not the default group
					//
					if (((PDPGroup) id).isDefaultGroup()) {
						self.buttonRemove.setEnabled(false);
					} else {
						self.buttonRemove.setEnabled(true);
					}
				}
			}
		});
		//
		// Maximize the table
		//
		this.table.setSizeFull();
	}
	
	protected void initializeButtons(final boolean isAdmin) {
		if (isAdmin == false) {
			return;
		}
		this.buttonCreate.addClickListener(new ClickListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void buttonClick(ClickEvent event) {
				self.editPDPGroup(null);
			}
		});
		this.buttonRemove.addClickListener(new ClickListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void buttonClick(ClickEvent event) {
				Object id = self.table.getValue();
				assert id != null;
				assert id instanceof PDPGroup;
				self.deleteGroup((PDPGroup) id);
				self.table.select(self.table.getNullSelectionItemId());
			}
		});
	}
	
	protected void setupButtons() {
		if (this.table.getValue() == null) {
			this.buttonRemove.setEnabled(false);
		} else {
			this.buttonRemove.setEnabled(true);
		}		
	}
		
	protected void editPDP(final PDP pdp, final PDPGroup group) {
		final EditPDPWindow editor = new EditPDPWindow(pdp, this.container.getGroups());
		if (pdp == null) {
			editor.setCaption("Create New PDP");
		} else {
			editor.setCaption("Edit PDP " + pdp.getId());
		}
		editor.setModal(true);
		editor.addCloseListener(new CloseListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void windowClose(CloseEvent event) {
				if (editor.isSaved() == false) {
					return;
				}
				try {
					//
					// Adding a new PDP?
					//
					if (pdp == null) {
						//
						// Yes tell the container to add it
						//
						self.container.addNewPDP(editor.getPDPId(), group, editor.getPDPName(), editor.getPDPDescription());
					} else {
						//
						// No tell the container to update it
						//
						pdp.setName(editor.getPDPName());
						pdp.setDescription(editor.getPDPDescription());
						self.container.updatePDP(pdp);
					}
				} catch (Exception e) {
					String message = "Unable to create PDP.  Reason:\n" + e.getMessage();
					logger.error(message);
					AdminNotification.error(message);
				}
			}
		});
		editor.center();
		UI.getCurrent().addWindow(editor);
	}
	
	protected void editPDPGroup(final PDPGroup group) {
		//
		// copy the group
		//
		final StdPDPGroup copyGroup = (group == null ? null : new StdPDPGroup(group));
		//
		//
		//
		final EditPDPGroupWindow editor = new EditPDPGroupWindow(copyGroup, this.container.getGroups(), papEngine);
		if (group == null) {
			editor.setCaption("Create PDP Group");
		} else {
			editor.setCaption("Edit PDP Group " + ((PDPGroup) group).getName());
		}
		editor.setModal(true);
		editor.addCloseListener(new CloseListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void windowClose(CloseEvent event) {
				if (editor.isSaved() == false) {
					return;
				}
				if (group == null) {
					//
					// Creating a new group
					//
					try {
						self.container.addNewGroup(editor.getGroupName(), editor.getGroupDescription());
					} catch (Exception e) {
						String message = "Unable to create Group.  Reason:\n" + e.getMessage();
						logger.error(message);
						AdminNotification.error(message);
					}
				} else {
					//
					// Update group
					//
					self.container.updateGroup(editor.getUpdatedObject());
				}
			}
		});
		editor.center();
		UI.getCurrent().addWindow(editor);
	}
	
	protected void deletePDP(final PDP pdp, final PDPGroup pdpGroup) {
		String message = "Are you sure you want to delete <B>" + (pdp.getName() == null ? "" : pdp.getName()) + "</B> group?";
		ConfirmDialog dialog = ConfirmDialog.getFactory().create("Confirm PDP Deletion", message, "Delete", "Cancel");
		dialog.setContentMode(ContentMode.HTML);
		dialog.show(getUI(), new ConfirmDialog.Listener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void onClose(ConfirmDialog dialog) {
				if (dialog.isConfirmed()) {
					try {
						self.container.removePDP(pdp, pdpGroup);
					} catch (PAPException e) {
						logger.warn("Failed to remove pdp");
						AdminNotification.warn("Failed to remove PDP");
					}
				}
			}
		}, true);
	}
	
	protected void movePDP(final PDP pdp, final PDPGroup currentGroup) {
		List<PDPGroup> currentGroups = this.container.getGroups();
		Set<PDPGroup> otherGroups = new HashSet<PDPGroup>(currentGroups);
		if (otherGroups.remove(currentGroup) == false) {
			logger.warn("Group list inconsistency - failed to move pdp to selected group");
			return;
		}
		final SelectPDPGroupWindow editor = new SelectPDPGroupWindow(otherGroups, "What was this?");
		editor.setCaption("Move PDP to group");
		editor.setModal(true);
		editor.addCloseListener(new CloseListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void windowClose(CloseEvent event) {
				if (editor.isSaved()) {
					self.container.movePDP((PDP) pdp, editor.selectedGroup());
				}
			}
		});
		editor.center();
		UI.getCurrent().addWindow(editor);
	}
	
	protected void getPDPStatus(final PDP pdp, final PDPGroup group) {
		PDPStatus status;
		try {
			status = papEngine.getStatus(pdp);
		} catch (Exception e) {
			AdminNotification.error("Unable to get details for pdp '" + pdp.getId() + "' with summary status: " + pdp.getStatus().getStatus());
			return;
		}
		logger.info(status);
		PDPStatusWindow window = new PDPStatusWindow(status);
		window.setCaption("Status for PDP " + pdp.getName());
		window.setModal(true);
		window.center();
		UI.getCurrent().addWindow(window);
	}
	
	private void deleteGroup(final PDPGroup group) {
		//
		// Cannot be the default group
		//
		if (group.isDefaultGroup()) {
			logger.error("Cannot delete the Default group");
			return;
		}
		//
		// Any PDPs in the group?
		//
		Set<PDP> pdps = group.getPdps();
		if (pdps.isEmpty()) {
			//
			// There are no PDP's, so just prompt to remove it
			//
			String message = "Are you sure you want to delete <B>" + (group.getName() == null ? "" : group.getName()) + "</B> group?";
			ConfirmDialog dialog = ConfirmDialog.getFactory().create("Confirm Group Deletion", message, "Delete", "Cancel");
			dialog.setContentMode(ContentMode.HTML);
			dialog.show(getUI(), new ConfirmDialog.Listener() {
				private static final long serialVersionUID = 1L;

				@Override
				public void onClose(ConfirmDialog dialog) {
					if (dialog.isConfirmed()) {
						try {
							self.container.removeGroup(group, null);
						} catch (Exception e1) {
							logger.warn("Container failed to remove group");
							AdminNotification.error("Unable to delete group '" + group.getId() + "'.  Reason:\n" + e1.getMessage());
						}
						return;
					}
				}
			}, true);
			return;
		}
		//
		// Get our set of groups
		//
		List<PDPGroup> currentGroups = this.container.getGroups();
		Set<PDPGroup> otherGroups = new HashSet<PDPGroup>(currentGroups);
		if (otherGroups.remove(group) == false) {
			logger.warn("Group list inconsistency - failed to remove group we are attempting to delete");
			return;
		}
		//
		// We should have at least one group
		//
		if (otherGroups.isEmpty()) {
			logger.error("Group list inconsistency - no other groups to choose from.");
			return;
		}
		//
		// If there is only one group, it SHOULD be the default group
		//
		if (otherGroups.size() == 1) {
			PDPGroup loneGroup = otherGroups.iterator().next();
			if (loneGroup.isDefaultGroup() == false) {
				logger.error("Group list inconsistency - lone group is NOT default.");
				return;
			}
		}
		//
		// Create our confirmation window
		//
		final SelectPDPGroupWindow window = new SelectPDPGroupWindow(otherGroups, "Select New Group for PDPs");
		window.setCaption("Confirm Group " + group.getName() + " Deletion");
		window.setCloseShortcut(KeyCode.ESCAPE);
		window.setModal(true);
		window.addCloseListener(new CloseListener() {
			private static final long serialVersionUID = 1L;


			@Override
			public void windowClose(CloseEvent e) {
				if (window.isSaved()) {
					PDPGroup newGroup = window.selectedGroup();
					if (newGroup == null) {
						logger.warn("No group selected for moving PDPs into");
						AdminNotification.warn("No group selected for moving PDPs into.  Group '" + group.getId() + "' not deleted");
						return;
					}
					try {
						self.container.removeGroup(group, newGroup);
					} catch (Exception e1) {
						logger.warn("Container failed to remove group: " + e1, e1);
						AdminNotification.error("Unable to delete group '" + group.getId() + "'.  Reason:\n" + e1.getMessage());
					}
				}
			}
			
		});
		getUI().addWindow(window);
	}

	public void refreshContainer() {
		if (this.container != null) {
			this.container.refreshGroups();
		}
	}

	@AutoGenerated
	private VerticalLayout buildMainLayout() {
		// common part: create layout
		mainLayout = new VerticalLayout();
		mainLayout.setImmediate(false);
		mainLayout.setWidth("100%");
		mainLayout.setHeight("100%");
		mainLayout.setMargin(false);
		
		// top-level component properties
		setWidth("100.0%");
		setHeight("100.0%");
		
		// horizontalLayoutToolbar
		horizontalLayoutToolbar = buildHorizontalLayoutToolbar();
		mainLayout.addComponent(horizontalLayoutToolbar);
		
		// tree
		table = new Table();
		table.setImmediate(false);
		table.setWidth("-1px");
		table.setHeight("-1px");
		mainLayout.addComponent(table);
		mainLayout.setExpandRatio(table, 1.0f);
		
		return mainLayout;
	}

	@AutoGenerated
	private HorizontalLayout buildHorizontalLayoutToolbar() {
		// common part: create layout
		horizontalLayoutToolbar = new HorizontalLayout();
		horizontalLayoutToolbar.setImmediate(false);
		horizontalLayoutToolbar.setWidth("-1px");
		horizontalLayoutToolbar.setHeight("-1px");
		horizontalLayoutToolbar.setMargin(true);
		horizontalLayoutToolbar.setSpacing(true);
		
		// buttonCreate
		buttonCreate = new Button();
		buttonCreate.setCaption("Create Group");
		buttonCreate.setImmediate(false);
		buttonCreate.setWidth("-1px");
		buttonCreate.setHeight("-1px");
		horizontalLayoutToolbar.addComponent(buttonCreate);
		
		// buttonRemove
		buttonRemove = new Button();
		buttonRemove.setCaption("Remove Group");
		buttonRemove.setImmediate(false);
		buttonRemove.setWidth("-1px");
		buttonRemove.setHeight("-1px");
		horizontalLayoutToolbar.addComponent(buttonRemove);
		
		return horizontalLayoutToolbar;
	}

}
