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

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

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Collection;
import java.util.Iterator;

import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicySetType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.RuleType;

import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.Status;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.dircache.DirCache;
import org.eclipse.jgit.dircache.DirCacheEntry;
import org.eclipse.jgit.errors.NoWorkTreeException;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.transport.PushResult;
import org.vaadin.dialogs.ConfirmDialog;
import org.vaadin.dialogs.ConfirmDialog.ContentMode;

import org.apache.openaz.xacml.admin.XacmlAdminAuthorization;
import org.apache.openaz.xacml.admin.XacmlAdminUI;
import org.apache.openaz.xacml.admin.model.GitRepositoryContainer;
import org.apache.openaz.xacml.admin.util.AdminNotification;
import org.apache.openaz.xacml.admin.util.OnDemandFileDownloader;
import org.apache.openaz.xacml.admin.util.OnDemandFileDownloader.OnDemandStreamResource;
import org.apache.openaz.xacml.admin.util.XACMLPolicyImporter;
import org.apache.openaz.xacml.admin.view.windows.GitPushWindow;
import org.apache.openaz.xacml.admin.view.windows.GitSynchronizeWindow;
import org.apache.openaz.xacml.admin.view.windows.PolicyNameEditorWindow;
import org.apache.openaz.xacml.admin.view.windows.PolicyUploadWindow;
import org.apache.openaz.xacml.admin.view.windows.RenamePolicyFileWindow;
import org.apache.openaz.xacml.admin.view.windows.SubDomainEditorWindow;
import org.apache.openaz.xacml.std.pap.StdPDPPolicy;
import org.apache.openaz.xacml.util.XACMLPolicyScanner;
import org.apache.openaz.xacml.util.XACMLPolicyScanner.CallbackResult;
import org.apache.openaz.xacml.util.XACMLPolicyWriter;
import com.vaadin.annotations.AutoGenerated;
import com.vaadin.data.Item;
import com.vaadin.event.Action;
import com.vaadin.event.Action.Handler;
import com.vaadin.event.ItemClickEvent;
import com.vaadin.event.ItemClickEvent.ItemClickListener;
import com.vaadin.event.ShortcutAction.KeyCode;
import com.vaadin.event.Transferable;
import com.vaadin.event.dd.DragAndDropEvent;
import com.vaadin.event.dd.DropHandler;
import com.vaadin.event.dd.acceptcriteria.AcceptAll;
import com.vaadin.event.dd.acceptcriteria.AcceptCriterion;
import com.vaadin.ui.AbstractSelect.AbstractSelectTargetDetails;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.Component;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.HorizontalSplitPanel;
import com.vaadin.ui.Notification;
import com.vaadin.ui.TabSheet;
import com.vaadin.ui.TabSheet.CloseHandler;
import com.vaadin.ui.TabSheet.Tab;
import com.vaadin.ui.Table.TableDragMode;
import com.vaadin.ui.Table.TableTransferable;
import com.vaadin.ui.TreeTable;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window.CloseEvent;
import com.vaadin.ui.Window.CloseListener;

/**
 * The class represents Policy Editor in Policy Authoring Tool
 */
public class PolicyWorkspace extends CustomComponent implements DropHandler, OnDemandStreamResource {
	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */

	@AutoGenerated
	private VerticalLayout mainLayout;

	@AutoGenerated
	private HorizontalSplitPanel horizontalSplitPanel;

	@AutoGenerated
	private VerticalLayout verticalLayoutRightPanel;

	@AutoGenerated
	private TabSheet tabSheet;

	@AutoGenerated
	private HorizontalLayout horizontalLayoutRightToolbar;

	@AutoGenerated
	private Button buttonRight;

	@AutoGenerated
	private VerticalLayout verticalLayoutLeftPanel;

	@AutoGenerated
	private TreeTable treeWorkspace;

	@AutoGenerated
	private HorizontalLayout horizontalLayoutLeftToolbar;

	@AutoGenerated
	private Button buttonLeft;

	@AutoGenerated
	private HorizontalLayout horizontalLayoutLeftToolbarLeft;

	@AutoGenerated
	private Button buttonExport;

	@AutoGenerated
	private Button buttonSynchronize;

	private static final long serialVersionUID = 1L;
	private static final Log logger	= LogFactory.getLog(PolicyWorkspace.class);
	private final PolicyWorkspace self = this;
	private final OnDemandFileDownloader downloader = new OnDemandFileDownloader(this);
	
	private GitRepositoryContainer treeContainer;
	
	private static final Action EXPORT_REPOSITORY = 	new Action ("Export Repository");
	private static final Action SYNCHRONIZE_REPOSITORY =new Action ("Synchronize");
	private static final Action PUSH_CHANGES = 			new Action ("Push Changes");
	private static final Action CREATE_SUBDOMAIN = 		new Action("Create Sub Domain");
	private static final Action RENAME_SUBDOMAIN = 		new Action("Rename Sub Domain");
	private static final Action CREATE_NEWPOLICY =		new Action ("Create New Policy");
	private static final Action RENAME_POLICY =			new Action ("Rename Policy");
	private static final Action IMPORT_POLICY = 		new Action ("Import Policy");
	private static final Action DELETE_SUBDOMAIN = 		new Action ("Delete Sub Domain");
	private static final Action CLONE_POLICY = 			new Action ("Clone Policy");
	private static final Action VIEW_POLICY = 			new Action ("View Policy");
	private static final Action EDIT_POLICY = 			new Action ("Edit Policy");
	private static final Action EXPORT_POLICY = 		new Action ("Export Policy");
	private static final Action DELETE_POLICY = 		new Action ("Delete Policy");
	
	public static final String VIEWNAME = PolicyWorkspace.class.getCanonicalName();
	
	/**
	 * The constructor should first build the main layout, set the
	 * composition root and then do any custom initialization.
	 *
	 * The constructor will not be automatically regenerated by the
	 * visual editor.
	 */
	public PolicyWorkspace() {
		buildMainLayout();
		setCompositionRoot(mainLayout);
		//
		// Initialize GUI
		//
		this.initializeTree();
		this.initializeButtons();
	}
	
	protected void initializeButtons() {
		buttonLeft.addClickListener(new ClickListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void buttonClick(ClickEvent event) {
				if (horizontalSplitPanel.getSplitPosition() == 100.0)
					horizontalSplitPanel.setSplitPosition(36, Unit.PERCENTAGE);
				else
					horizontalSplitPanel.setSplitPosition(0);
			}
		});
		buttonRight.addClickListener(new ClickListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void buttonClick(ClickEvent event) {
				if (horizontalSplitPanel.getSplitPosition() == 0.0)
					horizontalSplitPanel.setSplitPosition(36, Unit.PERCENTAGE);
				else
					horizontalSplitPanel.setSplitPosition(100, Unit.PERCENTAGE);
			}
		});
		//
		// Check user write-access
		//
		if (((XacmlAdminUI)UI.getCurrent()).isAuthorized( 
				XacmlAdminAuthorization.AdminAction.ACTION_WRITE, 
				XacmlAdminAuthorization.AdminResource.RESOURCE_POLICY_WORKSPACE)) {
			this.buttonSynchronize.addClickListener(new ClickListener() {
				private static final long serialVersionUID = 1L;
	
				@Override
				public void buttonClick(ClickEvent event) {
					self.synchronizeRepository();
				}			
			});
		} else {
			logger.info("user not authorized to write, removing synchronize button.");
			this.buttonSynchronize.setVisible(false);
		}
		//
		// The export button is attached to dynamic downloader
		//
		downloader.extend(this.buttonExport);
	}
	
	protected void initializeTree() {
		//
		// This is where the user's Git repository is located
		//
		final Path gitPath = ((XacmlAdminUI)UI.getCurrent()).getUserGitPath();
		//
		// Create our Git file system container
		//
		this.treeContainer = new GitRepositoryContainer(gitPath, gitPath.toFile());
		//
		// Create our own filter to filter out File extensions and
		// also the Git directory.
		//
		this.treeContainer.setFilter(new FilenameFilter() {

			@Override
			public boolean accept(File dir, String name) {
				//
				// We don't want any of the hidden files
				//
				if (name.startsWith(".git") || name.equals(".DS_Store")) {
					return false;
				}
				//
				// We definitely want xml files
				//
				if (name.endsWith(".xml")) {
					return true;
				}
				//
				// We should test if its a directory, we want those
				// included.
				//
				Path path = Paths.get(dir.getAbsolutePath(), name);
				if (Files.isDirectory(path)) {
					return true;
				}
				logger.warn("Filtering out: " + path.toString());
				return false;
			}
			
		});
		//
		// Set TreeTables datasource as our git container
		//
		this.treeWorkspace.setContainerDataSource(this.treeContainer);
		//
		// Setup other properties etc.
		//
		this.treeWorkspace.setItemIconPropertyId("Icon");
		this.treeWorkspace.setVisibleColumns(new Object[]{"Name", "Version", "Size", "Last Modified", "Status"});
		this.treeWorkspace.setSizeFull();
		this.treeWorkspace.setSelectable(true);
		this.treeWorkspace.setEditable(false);
		//
		// Expand the first couple of directories
		//
		for (Object id : this.treeWorkspace.getItemIds()) {
			this.treeWorkspace.setCollapsed(id, false);
			for (Object child : this.treeWorkspace.getChildren(id)) {
				this.treeWorkspace.setCollapsed(child, false);
			}
		}
		//
		// Respond to table selections
		//
		/*
		this.treeWorkspace.addValueChangeListener(new ValueChangeListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void valueChange(ValueChangeEvent event) {
				File selection = (File) self.treeWorkspace.getValue();
				if (selection != null) {
					self.buttonImport.setEnabled(selection.isDirectory());
					self.buttonExport.setEnabled(selection.isFile());
				} else {
					
				}
			}
			
		});
		*/
		this.treeWorkspace.addItemClickListener(new ItemClickListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void itemClick(ItemClickEvent event) {
				if (event.isDoubleClick() && 
					event.getItemId() instanceof File &&
					((File) event.getItemId()).isFile()) {
					self.openPolicyTab((File) event.getItemId(), true);
				}				
			}
		});
		//
		// Setup our action handlers
		//
		this.treeWorkspace.addActionHandler(new Handler() {
			private static final long serialVersionUID = 1L;

			@Override
			public Action[] getActions(Object target, Object sender) {
				if (target == null) {
					//
					// Nothing is selected, they right-clicked empty space
					//
					return new Action[] {SYNCHRONIZE_REPOSITORY, EXPORT_REPOSITORY, CREATE_SUBDOMAIN};
				}
				if (! (target instanceof File)) {
					return null;
				}
				if (((File)target).isDirectory()) {
					//
					// Selected a directory
					//
					return new Action[] {CREATE_SUBDOMAIN, RENAME_SUBDOMAIN, DELETE_SUBDOMAIN, CREATE_NEWPOLICY, IMPORT_POLICY, PUSH_CHANGES};
				}
				if (((File)target).isFile()) {
					//
					// Selected a policy file
					//
					return new Action[] {VIEW_POLICY, EDIT_POLICY, CLONE_POLICY, EXPORT_POLICY, RENAME_POLICY, DELETE_POLICY, PUSH_CHANGES};
				}
				return null;
			}

			@Override
			public void handleAction(Action action, Object sender, Object target) {
				if (action == SYNCHRONIZE_REPOSITORY) {
					self.synchronizeRepository();
					return;
				}
				if (action == EXPORT_REPOSITORY) {
					self.exportRepository();
					return;
				}
				if (action == PUSH_CHANGES) {
					self.pushChanges((File) target);
					return;
				}
				if (action == CREATE_SUBDOMAIN) {
					self.editSubDomain((File) target, null);
					return;
				}
				if (action == RENAME_SUBDOMAIN) {
					self.editSubDomain((File) self.treeWorkspace.getParent(target), ((File)target).getName());
					return;
				}
				if (action == CREATE_NEWPOLICY) {
					self.createPolicy((File) target);
					return;
				}
				if (action == RENAME_POLICY) {
					self.renamePolicy((File) target);
					return;
					
				}
				if (action == IMPORT_POLICY) {
					self.importPolicy((File) target);
					return;
				}
				if (action == DELETE_SUBDOMAIN) {
					self.deleteSubDomain((File) target);
					return;
				}
				if (action == CLONE_POLICY) {
					self.clonePolicy((File) target);
					return;
				}
				if (action == VIEW_POLICY) {
					self.openPolicyTab((File) target, true);
					return;
				}
				if (action == EDIT_POLICY) {
					self.openPolicyTab((File) target, false);
					return;
				}
				if (action == EXPORT_POLICY) {
					return;

				}
				if (action == DELETE_POLICY) {
					self.deletePolicy((File) target);
					return;
				}
			}
		});
		//
		// Set the drop handler
		//
		this.treeWorkspace.setDragMode(TableDragMode.ROW);
		this.treeWorkspace.setDropHandler(this);
		//
		// Detect when a tab closes and remove it from the
		// tab sheet.
		//
		this.tabSheet.setCloseHandler(new CloseHandler() {
			private static final long serialVersionUID = 1L;

			@Override
			public void onTabClose(TabSheet tabsheet, Component tabContent) {
				logger.info("tabsheet closing: " + tabsheet.getCaption());
				tabsheet.removeTab(tabsheet.getTab(tabContent));
			}
			
		});
	}

	protected void	editSubDomain(final File parent, final String subdomain) {
		final SubDomainEditorWindow editor = new SubDomainEditorWindow(null);
		editor.setCaption((subdomain == null ? "Create New SubDomain" : "Edit SubDomain"));
		editor.setCloseShortcut(KeyCode.ESCAPE);
		editor.setModal(true);
		editor.addCloseListener(new CloseListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void windowClose(CloseEvent event) {
				//
				// Did the user save it
				//
				if (editor.isSaved() == false) {
					return;
				}
				String newSubDomain = editor.getSubDomain();
				if (newSubDomain == null) {
					logger.warn("Shouldn't have a null subdomain if the user clicked save button");
					return;
				}
				//
				// New subdomain?
				//
				if (subdomain == null) {
					//
					// Create new one
					//
					Path createDir;
					if (parent == null) {
						//
						// New Root domain
						//
						createDir = Paths.get(((XacmlAdminUI)UI.getCurrent()).getUserGitPath().toAbsolutePath().toString(), newSubDomain);
					} else {
						//
						// New subdomain
						//
						createDir = Paths.get(parent.getAbsolutePath(), newSubDomain);
					}
					try {
						//
						// Does the new subdomain exist?
						//
						Path newDir;
						if (Files.exists(createDir)) {
							//
							// It already exists
							//
							newDir = createDir;
						} else {
							//
							// Create it
							//
							newDir = Files.createDirectory(createDir);
							//
							// Create empty .gitignore file
							//
							Files.createFile(Paths.get(newDir.toString(), ".gitignore"));
						}
						//
						// Setup the TreeTable
						//
						File file = newDir.toFile();
						if (parent == null) {
							Item item = self.treeWorkspace.addItem(file);
							if (item != null) {
								self.treeWorkspace.setCollapsed(file, false);
								self.treeWorkspace.select(file);
							}
						} else {
							Item item = self.treeWorkspace.addItem(file);
							if (item != null) {
								self.treeWorkspace.setParent(file, parent);
								self.treeWorkspace.setCollapsed(parent, false);
								self.treeWorkspace.select(file);
							}
						}
					} catch (IOException e) {
						logger.error("Failed to create subdomain: " + createDir.toString(), e);
					}
				} else {
					//
					// Get our paths
					//
					Path oldDir = Paths.get(parent.getAbsolutePath(), subdomain);
					Path newDir = Paths.get(parent.getAbsolutePath(), newSubDomain);
					try {
						//
						// Rename the subdomain
						//
						Files.move(oldDir, newDir);
						//
						// Add to the TreeTable
						//
						File newFile = newDir.toFile();
						File oldFile = oldDir.toFile();
						Item item = self.treeWorkspace.addItem(newFile);
						if (item != null) {
							self.treeWorkspace.setChildrenAllowed(newFile, true);
							//
							// Make sure its parent is the same as the old one, unless they
							// renamed the top-level.
							//
							Object parent = self.treeWorkspace.getParent(oldFile);
							if (parent != null) {
								self.treeWorkspace.setParent(newFile, parent);
							}
							//
							// Make any children of the old subdomain now children
							// of the new subdomain.
							//
							Collection<?> children = self.treeWorkspace.getChildren(oldFile);
							Iterator<?> iter = children.iterator();
							while (iter.hasNext()) {
								Object child = iter.next();
								self.treeWorkspace.setParent(child, newFile);
							}
							//
							// Finally remove the old subdomain
							//
							self.treeWorkspace.removeItem(oldFile);
						}
					} catch (IOException e) {
						logger.error("Failed to rename subdomain: " + oldDir.toString() + " to: " + newDir.toString(), e);
					}
				}
			}
		});
		editor.center();
		UI.getCurrent().addWindow(editor);
	}
	
	protected void	deleteSubDomain(final File subdomain) {
		String message = "Are you sure you want to delete subdomain\n" + subdomain.getName() + "\nThis will remove <B>ALL</B> of its subdomains and policy files.";
		ConfirmDialog dialog = ConfirmDialog.getFactory().create("Confirm SubDomain Deletion", message, "Delete", "Cancel");
		dialog.setContentMode(ContentMode.HTML);
		dialog.show(getUI(), new ConfirmDialog.Listener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void onClose(ConfirmDialog dialog) {
				if (dialog.isConfirmed()) {
					//
					// Iterate the subdomain
					//
					try {
						Files.walkFileTree(Paths.get(subdomain.getAbsolutePath()), new SimpleFileVisitor<Path>() {
							@Override
							public FileVisitResult visitFile(Path deleteFile, BasicFileAttributes attrs)
									throws IOException {
								try {
									boolean removeFromTree = deleteFile.getFileName().toString().endsWith(".xml");
									Files.delete(deleteFile);									
									if (removeFromTree) {
										self.treeWorkspace.removeItem(deleteFile.toFile());
									}
									if (logger.isDebugEnabled()) {
										logger.debug("Deleted file: " + deleteFile.toString());
									}
								} catch (IOException e) {
									logger.error("Failed to delete file: " + deleteFile.toString(), e);
									return FileVisitResult.TERMINATE;
								}
								return super.visitFile(deleteFile, attrs);
							}

							@Override
							public FileVisitResult postVisitDirectory(Path dir, IOException exc)
									throws IOException {
								try {
									Files.delete(dir);									
									self.treeWorkspace.removeItem(dir.toFile());
									if (logger.isDebugEnabled()) {
										logger.debug("Deleted dir: " + dir.toString());
									}
								} catch (IOException e) {
									logger.error("Failed to delete directory: " + dir.toString(), e);
									return FileVisitResult.TERMINATE;
								}
								return super.postVisitDirectory(dir, exc);
							}
							
						});
					} catch (IOException e) {
						logger.error("Failed to walk subdomain: " + subdomain.getAbsolutePath(), e);
					}
				}
			}
			
		}, true);
		
	}
	
	protected void	createPolicy(final File parentDirectory) {
		//
		// Construct our parameters
		//
		Path parent = Paths.get(parentDirectory.getAbsolutePath());
		Path newFile = this.getNextFilename(parent, "Policy");
		//
		// Run the window
		//
		this.runPolicyWindow("Create New Policy", parent, newFile, null, null);
	}
	
	protected void	renamePolicy(final File policy) {
		//
		// Run the rename window
		//
		final RenamePolicyFileWindow window = new RenamePolicyFileWindow(policy.getName());
		window.setCaption("Rename Policy");
		window.setModal(true);
		window.addCloseListener(new CloseListener() {
			private static final long serialVersionUID = 1L;
			
			@Override
			public void windowClose(CloseEvent event) {
				String newFilename = window.getNewFilename();
				if (newFilename == null) {
					//
					// User cancelled
					//
					return;
				}
				Path newPolicy = Paths.get(policy.getParent(), newFilename);
				if (Files.exists(newPolicy)) {
					Notification.show("Cannot rename to an existing file", Notification.Type.ERROR_MESSAGE);
					return;
				}
				try {
					if (policy.renameTo(newPolicy.toFile()) == false) {
						throw new Exception("No known error, rename failed");
					}
					self.treeContainer.updateItem(newPolicy.getParent().toFile());
				} catch (Exception e) {
					Notification.show("Failed to rename file: " + e.getLocalizedMessage());
				}
			}
		});
		window.center();
		UI.getCurrent().addWindow(window);
	}
	
	protected void	clonePolicy(final File policy) {
		//
		// Figure out a new name for the cloned policy
		//
		Path policyClone = Paths.get(policy.getAbsolutePath());
		Path newFile = this.getNextFilename(policyClone.getParent(), policy.getName());
		if (newFile == null) {
			return;
		}
		//
		// Scan the policy in, replace policy ID's and rule ID's
		//
		Object policyData = new XACMLPolicyScanner(policyClone, new XACMLPolicyScanner.SimpleCallback() {

			@Override
			public CallbackResult onPreVisitRule(PolicyType parent, RuleType rule) {
				rule.setRuleId(((XacmlAdminUI)getUI()).newRuleID());
				return CallbackResult.CONTINUE;
			}
			
			@Override
			public CallbackResult onPreVisitPolicySet(PolicySetType parent, PolicySetType policySet) {
				policySet.setPolicySetId(((XacmlAdminUI)getUI()).newPolicyID());
				policySet.setVersion("1");
				return CallbackResult.CONTINUE;
			}
			
			@Override
			public CallbackResult onPreVisitPolicy(PolicySetType parent, PolicyType policy) {
				policy.setPolicyId(((XacmlAdminUI)getUI()).newPolicyID());
				policy.setVersion("1");
				return CallbackResult.CONTINUE;
			}
			
		}).scan();
		//
		// Run the window
		//
		this.runPolicyWindow("Clone Policy", newFile.getParent(), newFile.getFileName(), policyData, null);
	}
	
	protected void	runPolicyWindow(String caption, final Path parentPath, final Path policyPath, final Object policyData, final Path oldPolicyFile) {
		//
		// Create our editor window
		//
		final PolicyNameEditorWindow editor = new PolicyNameEditorWindow((policyPath != null ? policyPath.getFileName().toString() : null), 
															policyData, 
															((XacmlAdminUI)getUI()).getPolicyAlgorithms(),
															((XacmlAdminUI)getUI()).getRuleAlgorithms());
		editor.setCaption(caption);
		editor.setCloseShortcut(KeyCode.ESCAPE);
		editor.setModal(true);
		editor.addCloseListener(new CloseListener() {
			private static final long serialVersionUID = 1L;
			
			@Override
			public void windowClose(CloseEvent event) {
				//
				// Did the user hit save button or esc?
				//
				if (editor.isSaved() == false) {
					return;
				}
				final Object data = editor.getPolicyData();
				String filename = editor.getPolicyFilename();
				if (filename == null || data == null) {
					logger.warn("Editor said is was saved but filename/data is null.");
					return;
				}
				//
				// Determine new path
				//
				final Path newPolicyPath = Paths.get(parentPath.toString(), filename);
				//
				// Is it ok to overwrite the new file?
				//
				try {
					//
					// Handle if we are not replacing an old file and we are overwriting
					// an existing file.
					//
					if (self.isOverwritingAPolicy(newPolicyPath, oldPolicyFile) == false && Files.exists(newPolicyPath)) {
						//
						// Confirm they wanted to do this, and figure out
						// new version number.
						//
						String message = "You are overwriting a file: " + newPolicyPath.getFileName().toString();
						ConfirmDialog dialog = ConfirmDialog.getFactory().create("Confirm Policy File Overwriting", message, "Overwrite", "Cancel");
						dialog.setData(false);
						dialog.setContentMode(ContentMode.HTML);
						dialog.setModal(true);
						dialog.show(getUI(), new ConfirmDialog.Listener() {
							private static final long serialVersionUID = 1L;

							@Override
							public void onClose(ConfirmDialog dialog) {
								if (dialog.isConfirmed()) {
									//
									// Yep the user wants to overwrite it
									//
									self.savePolicy(newPolicyPath, data, oldPolicyFile);
									//
									// Open it for editing
									//
									self.openPolicyTab(newPolicyPath.toFile(), false);
								}
							}
							
						}, true);
						//
						// Exit out of this thread
						//
						return;
					}
				} catch (Exception e) {
					logger.error(e);
					return;
				}
				//
				// Save it off
				//
				self.savePolicy(newPolicyPath, data, oldPolicyFile);
				//
				// Open it for editing
				//
				self.openPolicyTab(newPolicyPath.toFile(), false);
			}
		});
		editor.center();
		UI.getCurrent().addWindow(editor);
	}

	protected Path	getNextFilename(Path parent, String filename) {
		filename = FilenameUtils.removeExtension(filename);
		Path newFile = null;
		int i = 0;
		while (true) {
			newFile = Paths.get(parent.toString(), String.format("%s(%02d)", filename, i++) + ".xml");
			if (Files.notExists(newFile)) {
				return newFile;
			}
			if (i == 100) {
				logger.error("Could not construct a new name for cloned policy.");
				return null;
			}
		}
		
	}
	
	protected boolean isOverwritingAPolicy(Path newPolicyPath, Path oldPolicyPath) throws Exception {
		//
		// Check to see if we were editing an existing file. Then check if the
		// new file actually exists. Then check if we are overwriting the original old file
		//
		if (oldPolicyPath != null && Files.exists(newPolicyPath) && Files.isSameFile(newPolicyPath, oldPolicyPath)) {
			//
			// Yes its the same, overwriting it is expected.
			//
			logger.info("isOverwritingAPolicy");
			return true;
		}
		return false;
	}

	protected void	savePolicy(final Path newPolicyPath, final Object policyData, Path oldPolicyPath) {
		//
		// Are they overwriting another policy?
		//
		String version = "1.0";
		boolean delete = false;
		if (oldPolicyPath != null) {
			//
			// This policy name was being edited. Is it still the same?
			//
			try {
				delete = true;
				if (Files.exists(newPolicyPath) && Files.isSameFile(newPolicyPath, oldPolicyPath)) {
					delete = false;
				}
			} catch (Exception e) {
				logger.error("Could not determine if same file", e);
				return;
			}
			logger.info("Deleting old file: " + delete);
		}
		//
		// Are we now overwriting another file?
		//
		if (Files.exists(newPolicyPath)) {
			//
			// Yes
			//
			logger.info("Overwriting file");
			//
			// Overwrite is happening. Bump the version (IF WE CAN)
			//
//TODO - What if user wants to change something other than the last number?  For example, changing 1.5.23 to 2.0.0.
//TODO	  We need a mechanism that allows the user to specify the new policy version (disallowing backtracking) if they desire
//TODO	  and get that new number (if any) passed down to here.  This code then becomes the "then" branch of "If new version has been specified..."
			try {
				int[] versionArray = StdPDPPolicy.versionStringToArray(XACMLPolicyScanner.getVersion(newPolicyPath));
				// increment the right-most digit
				versionArray[versionArray.length - 1]++;
				version = StdPDPPolicy.versionArrayToString(versionArray);
			} catch (NumberFormatException | IOException e) {
				try {
					logger.warn("Previous version '" + XACMLPolicyScanner.getVersion(newPolicyPath) + "' not a series of itegers");
				} catch (IOException e1) {
					logger.error("could not get previous version");
				}
//TODO - This may not be wise since the intent is to increase the version number.  Perhaps we should abort this an go back to the user?
				version = "1.0";
			}
			if (policyData instanceof PolicySetType) {
				((PolicySetType) policyData).setVersion(version);
			} else if (policyData instanceof PolicyType) {
				((PolicyType) policyData).setVersion(version);
			}
		} else {
			//
			// Nope, a completely new file
			//
			logger.info("New file");
		}
		//
		// Is the root a PolicySet or Policy?
		//
		Path finalPolicyPath;
		if (policyData instanceof PolicySetType) {
			//
			// Write it out
			//
			finalPolicyPath = XACMLPolicyWriter.writePolicyFile(newPolicyPath, (PolicySetType) policyData);
		} else if (policyData instanceof PolicyType) {
			//
			// Write it out
			//
			finalPolicyPath = XACMLPolicyWriter.writePolicyFile(newPolicyPath, (PolicyType) policyData);
		} else {
			logger.error("Unknown data type sent back.");
			return;
		}
		//
		// Did it get written?
		//
		if (finalPolicyPath == null || ! Files.exists(finalPolicyPath)) {
			logger.error("Failed to write policy file.");
			return;
		}
		//
		// Add it into our tree
		//
		this.addPolicyFileToTree(finalPolicyPath.getParent().toFile(), finalPolicyPath.toFile());
		//
		// Do we need to delete the old file?
		//
		if (oldPolicyPath != null && delete) {
			try {
				Files.delete(oldPolicyPath);
			} catch (Exception e) {
				logger.error("Failed to delete old policy", e);
			}
			if (self.treeWorkspace.removeItem(oldPolicyPath.toFile()) == false) {
				logger.warn("Failed to remove old policy path");
			}
		}
	}	

	protected void	deletePolicy(final File policy) {
		String message = "Are you sure you want to delete policy: " + policy.getName();
		ConfirmDialog dialog = ConfirmDialog.getFactory().create("Confirm Policy File Deletion", message, "Delete", "Cancel");
		dialog.setContentMode(ContentMode.HTML);
		dialog.show(getUI(), new ConfirmDialog.Listener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void onClose(ConfirmDialog dialog) {
				if (dialog.isConfirmed() && policy.delete()) {
					self.treeWorkspace.removeItem(policy);
					if (logger.isDebugEnabled()) {
						logger.debug("Deleted file: " + policy.toString());
					}
				}
			}
			
		}, true);
		
	}

	protected void	importPolicy(final File domain) {
		//
		// Get the current domain
		//
		if (! domain.isDirectory()) {
			logger.error("Table must have a directory selected to import the file.");
			return;
		}
		//
		// Create the upload window
		//
		final PolicyUploadWindow upload = new PolicyUploadWindow(Paths.get(domain.toURI()));
		upload.setCaption("Import Xacml 3.0 Policy File");
		upload.setCloseShortcut(KeyCode.ESCAPE);
		upload.setModal(true);
		upload.addCloseListener(new CloseListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void windowClose(CloseEvent e) {
				//
				// Was it successful?
				//
				Path newFile = upload.getUploadedFile();
				if (newFile == null) {
					return;
				}
				//
				// Add it
				//
				self.addPolicyFileToTree(domain, newFile.toFile());
				//
				// Are we importing anything in the policy file?
				//
				boolean importAttributes = upload.importAttributes();
				boolean importObligations = upload.importObligations();
				boolean importAdvice = upload.importAdvice();
				if (importAttributes || importObligations || importAdvice) {
					//
					// Create our importer
					//
					XACMLPolicyImporter importer = new XACMLPolicyImporter();
					importer.setImportAttributes(importAttributes);
					importer.setImportObligations(importObligations);
					importer.setImportAdvice(importAdvice);		
					importer.setIgnoreStandardAttributes(upload.ignoreStandard());
					//
					// Yes load and scan the policy
					//
					new XACMLPolicyScanner(newFile, importer).scan();
				}
			}
		});
		upload.center();
		UI.getCurrent().addWindow(upload);
	}
	
	protected	void	addPolicyFileToTree(File domain, File file) {
		//
		// Add it into our tree
		//
		if (this.treeWorkspace.addItem(file) != null) {
			//
			// Make sure it has the right parent
			//
			this.treeWorkspace.setParent(file, domain);
			//
			// Select our new policy
			//
			self.treeWorkspace.select(file);
		} else {
			logger.error("Failed to add policy to workspace tree");
		}
	}
	
	/*
	protected void	publishPolicy(final File policy) {
		//
		// Get its ID
		//
		Item item = this.treeContainer.getItem(policy);
		if (item == null) {
			logger.error("Failed to get the item");
			return;
		}
		Object policyData = item.getItemProperty("Data");
		if (policyData == null) {
			logger.error("Failed to get item data property.");
			return;
		}
		String fullId = XACMLPolicyScanner.getID(policyData);
		String version = XACMLPolicyScanner.getVersion(policyData);
		if (fullId == null || version == null) {
			logger.error("Failed to get policy Id");
			return;
		}
		List<String> ids = Lists.newArrayList(Splitter.on(':').split(fullId));
		if (ids.isEmpty()) {
			logger.error("Couldn't parse policy Id");
			return;
		}
		final String id = ids.get(ids.size() - 1) + "." + version;
		//
		// Is there only one group?
		//
		PAPEngine engine = ((XacmlAdminUI)getUI()).getPAPEngine();
		Set<PDPGroup> groups;
		PDPGroup defaultGroup;
		try {
			groups = engine.getPDPGroups();
		} catch (PAPException e) {
			String message = "Unable to retrieve Groups from server: " + e;
			logger.error(message, e);
			throw new RuntimeException(message);
		}
		try {
			defaultGroup = engine.getDefaultGroup();
		} catch (PAPException e) {
			String message = "Unable to retrieve Default Group from server: " + e;
			logger.error(message, e);
			throw new RuntimeException(message);
		}
		if (groups.size() == 1) {
			this.doPublish(id, policy, defaultGroup);
			return;
		}
		//
		// Have user select a group
		//
		final SelectPDPGroupWindow window = new SelectPDPGroupWindow(groups, "Select PDP Group to publish in");
		window.setCaption("Select PDP Group");
		window.setCloseShortcut(KeyCode.ESCAPE);
		window.setModal(true);
		window.addCloseListener(new CloseListener() {
			private static final long serialVersionUID = 1L;
			
			@Override
			public void windowClose(CloseEvent event) {
				PDPGroup group = window.selectedGroup();
				if (group != null) {
					self.doPublish(id, policy, group);
				}
			}
		});
		window.center();
		UI.getCurrent().addWindow(window);

	}
	
	protected void	doPublish(String id, File policy, PDPGroup group) {
		//
		// The policy status must be up-to-date
		//
		// TODO
		
		//
		// TODO - get list of referenced policies and publish
		// them first.
		//
		
		//
		// Publish the policy
		//
		
		PAPEngine engine = ((XacmlAdminUI)getUI()).getPAPEngine();
		try (InputStream is = new FileInputStream(policy)) {
			engine.publishPolicy(id, policy.getName(), true, is, group);
		} catch (PAPException | IOException e) {
			logger.error("Failed to publish policy: ", e);
		}
	}
	*/
	
	protected void	pushChanges(final File target) {
		try {
			//
			// Grab our working repository
			//
    		Path repoPath = ((XacmlAdminUI)getUI()).getUserGitPath();
			final Git git = Git.open(repoPath.toFile());
			//
			// Get our status
			//
			final String base;
			Status status;
			if (target == null) {
				base = ".";
			} else {
				Path relativePath = repoPath.relativize(Paths.get(target.getPath()));
				base = relativePath.toString();
			}
			if (logger.isDebugEnabled()) {
				logger.debug("Status on base: " + base);
			}
			status = git.status().addPath(base).call();
			//
			// Check if its clean
			//
			if (status.isClean()) {
				//
				// Its clean
				//
				AdminNotification.warn(target.getName() + " is clean!");
				return;
			}
			//
			// Create the window
			//
			final GitPushWindow window = new GitPushWindow(git, target, status);
			window.setCaption("Push Changes");
			window.setModal(true);
			window.addCloseListener(new CloseListener() {
				private static final long serialVersionUID = 1L;

				@Override
				public void windowClose(CloseEvent e) {
					if (window.isSaved() == false) {
						return;
					}
					try {
						//
						// Needs to be added first
						//
						DirCache cache = git.add().addFilepattern(base).call();
						for (int i = 0; i < cache.getEntryCount(); i++) {
							DirCacheEntry entry = cache.getEntry(i);
							if (logger.isDebugEnabled()) {
								logger.debug("Entry: " + entry);
							}
						}
						//
						// Next they need to be committed
						//
						RevCommit rev = git.commit().setMessage(window.getComment()).call();
						if (logger.isDebugEnabled()) {
							logger.debug("RevCommit: " + rev);
						}
						//
						// Now we can push changes to the Git repository
						//
						Iterable<PushResult> results = git.push().call();
						for (PushResult result : results) {
							logger.info(result);
						}
						//
						// Have the container fire an item set change notification
						//
						self.treeContainer.updateItem(target);
					} catch (NoWorkTreeException | GitAPIException e1) {
						logger.error(e);
						AdminNotification.error("Exception occurred while trying to push: " + e1);
					}
				}
				
			});
			window.center();
			UI.getCurrent().addWindow(window);
		} catch (IOException | GitAPIException e) {
			logger.error(e);
			AdminNotification.error("Exception occurred while trying to get status: " + e);
		}
	}
	
	protected void synchronizeRepository() {
		final GitSynchronizeWindow window = new GitSynchronizeWindow();
		window.setCaption("Synchronize with server repository?");
		window.setModal(true);
		window.center();
		UI.getCurrent().addWindow(window);
	}
	
	protected void exportRepository() {
		this.buttonExport.click();
	}
	
	@Override
	public String getFilename() {
		return "Repository.tgz";
	}

	@Override
	public InputStream getStream() {
		//
		// Grab our working repository
		//
		final Path repoPath = ((XacmlAdminUI)getUI()).getUserGitPath();
		Path workspacePath = ((XacmlAdminUI)getUI()).getUserWorkspace();
		final Path tarFile = Paths.get(workspacePath.toString(), "Repository.tgz");
		
		try (OutputStream os = Files.newOutputStream(tarFile)) {
			try (GzipCompressorOutputStream gzOut = new GzipCompressorOutputStream(os)) {
				try (TarArchiveOutputStream tarOut = new TarArchiveOutputStream(gzOut)) {
					
					tarOut.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);
					
					Files.walkFileTree(repoPath, new SimpleFileVisitor<Path>() {

						@Override
						public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
							if (dir.getFileName().toString().startsWith(".git")) {
								return FileVisitResult.SKIP_SUBTREE;
							}
							Path relative = repoPath.relativize(dir);
							if (relative.toString().isEmpty()) {
								return super.preVisitDirectory(dir, attrs);
							}
							TarArchiveEntry entry = new TarArchiveEntry(relative.toFile());
							tarOut.putArchiveEntry(entry);
							tarOut.closeArchiveEntry();
							return super.preVisitDirectory(dir, attrs);
						}

						@Override
						public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
							if (file.getFileName().toString().endsWith(".xml") == false) {
								return super.visitFile(file, attrs);
							}
							Path relative = repoPath.relativize(file);
							TarArchiveEntry entry = new TarArchiveEntry(relative.toFile());
							entry.setSize(Files.size(file));
							tarOut.putArchiveEntry(entry);
							try {
								IOUtils.copy(Files.newInputStream(file), tarOut);
							} catch (IOException e) {
								logger.error(e);
							}
							tarOut.closeArchiveEntry();
							return super.visitFile(file, attrs);
						}
						
					});
					tarOut.finish();
				}				
			}
		} catch (IOException e) {
			logger.error(e);
		}
		try {
			return Files.newInputStream(tarFile);
		} catch (IOException e) {
			logger.error(e);
		}
		return null;
	}

	protected void openPolicyTab(File policy, boolean readOnly) {
		//
		// Sanity check
		//
		assert policy != null;
		assert policy.isFile();
		if (policy == null || ! policy.isFile()) {
			throw new IllegalArgumentException("You must specify a file.");
		}
		Status status;
		Path relativePath;
		String base;
		try {
			//
			// Grab our working repository
			//
			Path repoPath = ((XacmlAdminUI)getUI()).getUserGitPath();
			final Git git = Git.open(repoPath.toFile());
			//
			// Get our status
			//
			relativePath = repoPath.relativize(Paths.get(policy.getPath()));
			base = relativePath.toString();
			if (logger.isDebugEnabled()) {
				logger.debug("Status on base: " + base);
			}
			status = git.status().addPath(base).call();
		} catch (NoWorkTreeException | IOException | GitAPIException e) {
			logger.error("Failed to get status on " + policy + " " + e);
			AdminNotification.error("Could not get Git status on the file.");
			return;
		}
		//
		// Check if its clean
		//
		if (status.isClean() == false) {
			//
			// Check if its conflicting
			//
			for (String conflict : status.getConflicting()) {
				if (conflict.equals(base)) {
					//
					// Yes - we won't be able to edit it
					//
					AdminNotification.error("Policy has conflicts with master, please synchronize the repository.");
					return;
				}
			}
		}
		//
		// Check to see if there already is a tab open
		//
		Iterator<Component> iter = self.tabSheet.iterator();
		while (iter.hasNext()) {
			Component c = iter.next();
			if (c instanceof PolicyEditor) {
				Object data = ((PolicyEditor) c).getData();
				if (data != null && data instanceof File && ((File)data).equals(policy)) {
					self.tabSheet.setSelectedTab(c);
					return;
				}
			}
		}
		//
		// No tab is open, create a new one
		//
		PolicyEditor editor = null;
		try {
			editor = new PolicyEditor(policy, this.treeContainer, readOnly);
		} catch (IOException e) {
			logger.error("Failed to open policy");
			editor = null;
		}
		if (editor != null) {
			editor.setWidth("100%");
			Tab tab = self.tabSheet.addTab(editor);
			editor.setTab(tab);
			tab.setClosable(true);
			
			self.tabSheet.setSelectedTab(editor);
		} else {
			AdminNotification.error("The Policy File is not a Xacml 3.0 policy.");
		}
	}

	@Override
	public void drop(DragAndDropEvent event) {
		Transferable t = event.getTransferable();
		Component source = t.getSourceComponent();
		if (source != this.treeWorkspace) {
			assert false;
			throw new IllegalArgumentException();
		}
		TableTransferable tt = (TableTransferable) t;
		File sourceFile = (File) tt.getItemId();
		
		AbstractSelectTargetDetails target = (AbstractSelectTargetDetails)event.getTargetDetails();
		File targetFile = (File) target.getItemIdOver();
		
		if (sourceFile.isFile() && targetFile != null && targetFile.isDirectory()) {
			//
			// Construct destination filename
			//
			Path dest = targetFile.toPath().resolve(sourceFile.getName());
			//
			// Check if the target domain exists
			//
			if (Files.exists(dest)) {
				//
				// Prompt the user
				//
				Notification.show("A policy file with that name already exists in that directory.", Notification.Type.ERROR_MESSAGE);
			} else {
				//
				// Go ahead and rename it
				//
				this.renamePolicyFile(sourceFile, dest.toFile(), targetFile);
			}
		}
	}
	
	protected void renamePolicyFile(File sourceFile, File dest, File parent) {
		try {
			if (sourceFile.renameTo(dest)) {
				this.treeContainer.setParent(sourceFile, parent);
				this.treeContainer.updateItem(parent);
			}
		} catch (Exception e) {
			String error = "Failed to rename " + sourceFile + " to: " + dest + System.lineSeparator() + e.getLocalizedMessage();
			logger.error(error);
			AdminNotification.error(error);
		}
	}

	@Override
	public AcceptCriterion getAcceptCriterion() {
        return AcceptAll.get();
	}
	
	@AutoGenerated
	private VerticalLayout buildMainLayout() {
		// common part: create layout
		mainLayout = new VerticalLayout();
		mainLayout.setImmediate(false);
		mainLayout.setWidth("100%");
		mainLayout.setHeight("100%");
		mainLayout.setMargin(false);
		
		// top-level component properties
		setWidth("100.0%");
		setHeight("100.0%");
		
		// horizontalSplitPanel
		horizontalSplitPanel = buildHorizontalSplitPanel();
		mainLayout.addComponent(horizontalSplitPanel);
		mainLayout.setExpandRatio(horizontalSplitPanel, 1.0f);
		
		return mainLayout;
	}

	@AutoGenerated
	private HorizontalSplitPanel buildHorizontalSplitPanel() {
		// common part: create layout
		horizontalSplitPanel = new HorizontalSplitPanel();
		horizontalSplitPanel.setImmediate(false);
		horizontalSplitPanel.setWidth("100.0%");
		horizontalSplitPanel.setHeight("100.0%");
		
		// verticalLayoutLeftPanel
		verticalLayoutLeftPanel = buildVerticalLayoutLeftPanel();
		horizontalSplitPanel.addComponent(verticalLayoutLeftPanel);
		
		// verticalLayoutRightPanel
		verticalLayoutRightPanel = buildVerticalLayoutRightPanel();
		horizontalSplitPanel.addComponent(verticalLayoutRightPanel);
		
		return horizontalSplitPanel;
	}

	@AutoGenerated
	private VerticalLayout buildVerticalLayoutLeftPanel() {
		// common part: create layout
		verticalLayoutLeftPanel = new VerticalLayout();
		verticalLayoutLeftPanel.setImmediate(false);
		verticalLayoutLeftPanel.setWidth("100.0%");
		verticalLayoutLeftPanel.setHeight("100.0%");
		verticalLayoutLeftPanel.setMargin(true);
		verticalLayoutLeftPanel.setSpacing(true);
		
		// horizontalLayoutLeftToolbar
		horizontalLayoutLeftToolbar = buildHorizontalLayoutLeftToolbar();
		verticalLayoutLeftPanel.addComponent(horizontalLayoutLeftToolbar);
		
		// treeWorkspace
		treeWorkspace = new TreeTable();
		treeWorkspace.setImmediate(true);
		treeWorkspace.setWidth("100.0%");
		treeWorkspace.setHeight("100.0%");
		verticalLayoutLeftPanel.addComponent(treeWorkspace);
		verticalLayoutLeftPanel.setExpandRatio(treeWorkspace, 1.0f);
		
		return verticalLayoutLeftPanel;
	}

	@AutoGenerated
	private HorizontalLayout buildHorizontalLayoutLeftToolbar() {
		// common part: create layout
		horizontalLayoutLeftToolbar = new HorizontalLayout();
		horizontalLayoutLeftToolbar.setImmediate(false);
		horizontalLayoutLeftToolbar.setWidth("100.0%");
		horizontalLayoutLeftToolbar.setHeight("-1px");
		horizontalLayoutLeftToolbar.setMargin(false);
		horizontalLayoutLeftToolbar.setSpacing(true);
		
		// horizontalLayoutLeftToolbarLeft
		horizontalLayoutLeftToolbarLeft = buildHorizontalLayoutLeftToolbarLeft();
		horizontalLayoutLeftToolbar
				.addComponent(horizontalLayoutLeftToolbarLeft);
		
		// buttonLeft
		buttonLeft = new Button();
		buttonLeft.setCaption("<<");
		buttonLeft.setImmediate(true);
		buttonLeft.setDescription("Minimize left panel.");
		buttonLeft.setWidth("-1px");
		buttonLeft.setHeight("-1px");
		horizontalLayoutLeftToolbar.addComponent(buttonLeft);
		horizontalLayoutLeftToolbar.setComponentAlignment(buttonLeft,
				new Alignment(34));
		
		return horizontalLayoutLeftToolbar;
	}

	@AutoGenerated
	private HorizontalLayout buildHorizontalLayoutLeftToolbarLeft() {
		// common part: create layout
		horizontalLayoutLeftToolbarLeft = new HorizontalLayout();
		horizontalLayoutLeftToolbarLeft.setImmediate(false);
		horizontalLayoutLeftToolbarLeft.setWidth("-1px");
		horizontalLayoutLeftToolbarLeft.setHeight("-1px");
		horizontalLayoutLeftToolbarLeft.setMargin(false);
		horizontalLayoutLeftToolbarLeft.setSpacing(true);
		
		// buttonSynchronize
		buttonSynchronize = new Button();
		buttonSynchronize.setCaption("Synchronize Repository");
		buttonSynchronize.setImmediate(true);
		buttonSynchronize
				.setDescription("Synchronize local repository with main branch.");
		buttonSynchronize.setWidth("-1px");
		buttonSynchronize.setHeight("-1px");
		horizontalLayoutLeftToolbarLeft.addComponent(buttonSynchronize);
		
		// buttonExport
		buttonExport = new Button();
		buttonExport.setCaption("Export Workspace");
		buttonExport.setImmediate(true);
		buttonExport.setDescription("Export your workspace to your local drive.");
		buttonExport.setWidth("-1px");
		buttonExport.setHeight("-1px");
		horizontalLayoutLeftToolbarLeft.addComponent(buttonExport);
		
		return horizontalLayoutLeftToolbarLeft;
	}

	@AutoGenerated
	private VerticalLayout buildVerticalLayoutRightPanel() {
		// common part: create layout
		verticalLayoutRightPanel = new VerticalLayout();
		verticalLayoutRightPanel.setImmediate(false);
		verticalLayoutRightPanel.setWidth("100.0%");
		verticalLayoutRightPanel.setHeight("-1px");
		verticalLayoutRightPanel.setMargin(true);
		verticalLayoutRightPanel.setSpacing(true);
		
		// horizontalLayoutRightToolbar
		horizontalLayoutRightToolbar = buildHorizontalLayoutRightToolbar();
		verticalLayoutRightPanel.addComponent(horizontalLayoutRightToolbar);
		
		// tabSheet
		tabSheet = new TabSheet();
		tabSheet.setImmediate(true);
		tabSheet.setWidth("100.0%");
		tabSheet.setHeight("-1px");
		verticalLayoutRightPanel.addComponent(tabSheet);
		verticalLayoutRightPanel.setExpandRatio(tabSheet, 1.0f);
		
		return verticalLayoutRightPanel;
	}

	@AutoGenerated
	private HorizontalLayout buildHorizontalLayoutRightToolbar() {
		// common part: create layout
		horizontalLayoutRightToolbar = new HorizontalLayout();
		horizontalLayoutRightToolbar.setImmediate(false);
		horizontalLayoutRightToolbar.setWidth("100.0%");
		horizontalLayoutRightToolbar.setHeight("-1px");
		horizontalLayoutRightToolbar.setMargin(false);
		horizontalLayoutRightToolbar.setSpacing(true);
		
		// buttonRight
		buttonRight = new Button();
		buttonRight.setCaption(">>");
		buttonRight.setImmediate(true);
		buttonRight.setDescription("Restore left panel.");
		buttonRight.setWidth("-1px");
		buttonRight.setHeight("-1px");
		horizontalLayoutRightToolbar.addComponent(buttonRight);
		
		return horizontalLayoutRightToolbar;
	}
}
