/*******************************************************************************
 * Copyright (c) 2007, 2008 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 * IBM Corporation - initial API and implementation
 * yyyymmdd bug      Email and other contact information
 * -------- -------- -----------------------------------------------------------
 * 20071106 196997   ericdp@ca.ibm.com - Eric Peters
 * 20071120 209858 ericdp@ca.ibm.com - Eric Peters, Enhancing service policy framework and UI 
 * 20071212   209858 ericdp@ca.ibm.com - Eric Peters, Enhancing service policy framework and UI
 * 20080211   218520 pmoogk@ca.ibm.com - Peter Moogk
 * 20080324   222095 pmoogk@ca.ibm.com - Peter Moogk, UI now listens for state changes.
 * 20080324   223634 ericdp@ca.ibm.com - Eric D. Peters, Service Policies preference tree should be 3 level tree
 * 20080506   219005 ericdp@ca.ibm.com - Eric D. Peters, Service policy preference page not restoring properly
 * 20080530   234944 pmoogk@ca.ibm.com - Peter Moogk, Fixed focus problem for action controls
 * 20080716   239457 ericdp@ca.ibm.com - Eric D. Peters, Service Policy UI Restore defaults does not refresh validation error
 *******************************************************************************/
package org.eclipse.wst.ws.internal.service.policy.ui;

import java.util.Enumeration;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.events.ExpansionAdapter;
import org.eclipse.ui.forms.events.ExpansionEvent;
import org.eclipse.ui.forms.widgets.ExpandableComposite;
import org.eclipse.ui.help.IWorkbenchHelpSystem;
import org.eclipse.wst.ws.service.policy.IDescriptor;
import org.eclipse.wst.ws.service.policy.IPolicyEnumerationList;
import org.eclipse.wst.ws.service.policy.IPolicyRelationship;
import org.eclipse.wst.ws.service.policy.IPolicyState;
import org.eclipse.wst.ws.service.policy.IPolicyStateEnum;
import org.eclipse.wst.ws.service.policy.IServicePolicy;
import org.eclipse.wst.ws.service.policy.IStateEnumerationItem;
import org.eclipse.wst.ws.service.policy.ServicePolicyPlatform;
import org.eclipse.wst.ws.service.policy.listeners.IPolicyChildChangeListener;
import org.eclipse.wst.ws.service.policy.listeners.IPolicyStateChangeListener;
import org.eclipse.wst.ws.service.policy.ui.IPolicyOperation;
import org.eclipse.wst.ws.service.policy.ui.ServicePolicyActivatorUI;
import org.eclipse.wst.ws.service.policy.ui.ServicePolicyPlatformUI;
import org.eclipse.wst.ws.service.policy.ui.IPolicyOperation.OperationKind;
import org.eclipse.wst.ws.service.policy.ui.utils.ServiceUtils;
import org.osgi.framework.Bundle;

public class ServicePoliciesComposite extends Composite implements
		SelectionListener, IPolicyChildChangeListener  {

	private ScrolledComposite operationsScrolledComposite;
	//a scrollable composite containing operations available for the selected policies
	private Composite operationsComposite;
	private IWorkbenchHelpSystem helpSystem;
	private Composite masterComposite;
	private Composite detailsComposite;
	private Tree masterPolicyTree;
	//tertiary and higher level policy nodes in a separate tree
	private Tree detailsPolicyTree;
	private Text text_DetailsPanel_description;
	private Text text_DetailsPanel_dependencies;
	private Label label_DetailsPanel_description;
	private Label label_detailsPanel_dependancies;
	private Hashtable<String, IStatus> allErrors;
	private IStatus error;
	private boolean bComplexOpCompleted = true;
	private List<ChildChangeEvent> listChildChangeEvents;
	private IConManager iconManager = new IConManager();
	private IProject project = null;
	private SelectionListener listener;
	private ExpandableComposite excomposite;
	private ServicePolicyPlatform platform = ServicePolicyPlatform
			.getInstance();
	private ServicePolicyPlatformUI platformUI = ServicePolicyPlatformUI
			.getInstance();
	private IPolicyStateChangeListener stateChangeListener  = new StateChangeListener();
	private boolean                    stateChangeEnabled   = true;
	private HashSet<IServicePolicy>    stateChangePolicySet = new HashSet<IServicePolicy>();
	private List<IServicePolicy>       lastSelectedSp       = null;

	/**
	 * Creates an expandable composite
	 * @param parent
	 * @param nColumns
	 * @return
	 */
	private ExpandableComposite createExpandableComposite(Composite parent,
			int nColumns) {
		ExpandableComposite excomposite = new ExpandableComposite(parent,
				SWT.NONE, ExpandableComposite.TWISTIE
						| ExpandableComposite.CLIENT_INDENT);
		excomposite.setExpanded(false);
		excomposite.setVisible(false);
		excomposite.setFont(JFaceResources.getFontRegistry().getBold(
				JFaceResources.DIALOG_FONT));
		excomposite.setLayoutData(new GridData(GridData.FILL, GridData.FILL,
				true, false, nColumns, 1));
		excomposite.addExpansionListener(new ExpansionAdapter() {
			public void expansionStateChanged(ExpansionEvent e) {
				expandedStateChanged((ExpandableComposite) e.getSource());
			}
		});
		makeScrollableCompositeAware(excomposite);
		return excomposite;
	}
	
	/**
	 * @author ericdp
	 * Helper class that encapsulates data required when an action control changes state
	 *
	 */
	private class ActionControlData {
		private List<IServicePolicy> spList;
		private List<IPolicyOperation> poList;
//		private IPolicyOperation po;

		public ActionControlData(List<IServicePolicy> spList, List<IPolicyOperation> poList) {
			this.spList = spList;
			this.poList = poList;
		}
		public List<IServicePolicy> getSpList() {
			return spList;
		}

		public void setSpList(List<IServicePolicy> spList) {
			this.spList = spList;
		}
//
//		public IPolicyOperation getPo() {
//			return po;
//		}
//
//		public void setPo(IPolicyOperation po) {
//			this.po = po;
//		}

		public List<IPolicyOperation> getPoList() {
			return poList;
		}

		public void setPoList(List<IPolicyOperation> poList) {
			this.poList = poList;
		}
	}

	/**
	 * Makes the scrollable composite aware of this control, so expand/collapse
	 * of the scrollable composite will move this control down/up accordingly
	 * @param control the control to make the scrollable composite aware of
	 */
	private void makeScrollableCompositeAware(Control control) {
		ScrolledPageContent parentScrolledComposite = getParentScrolledComposite(control);
		if (parentScrolledComposite != null) {
			parentScrolledComposite.adaptChild(control);
		}
	}

	private ScrolledPageContent getParentScrolledComposite(Control control) {
		Control parent = control.getParent();
		while (!(parent instanceof ScrolledPageContent) && parent != null) {
			parent = parent.getParent();
		}
		if (parent instanceof ScrolledPageContent) {
			return (ScrolledPageContent) parent;
		}
		return null;
	}

	private final void expandedStateChanged(ExpandableComposite expandable) {
		ScrolledPageContent parentScrolledComposite = getParentScrolledComposite(expandable);
		if (parentScrolledComposite != null) {
			parentScrolledComposite.reflow(true);
		}
	}

	/**
	 * @param parent
	 * @return a scrollable composite containing an expandable content
	 *
	 */
	private Composite createDetailsScrollPageContent(Composite parent) {

		int nColumns = 1;

		final ScrolledPageContent pageContent = new ScrolledPageContent(parent);

		GridLayout pageContLayout = new GridLayout();
		pageContLayout.numColumns = nColumns;
		pageContLayout.marginHeight = 0;
		pageContLayout.marginWidth = 0;

		Composite composite = pageContent.getBody();
		composite.setLayout(pageContLayout);

		excomposite = createExpandableComposite(composite, nColumns);

		Composite inner = new Composite(excomposite, SWT.NONE);
		inner.setFont(composite.getFont());
		inner.setLayout(new GridLayout(nColumns, false));
		excomposite.setClient(inner);
		//details policy tree for tertiary and higher level service policies
		detailsPolicyTree = new Tree(inner, SWT.BORDER | SWT.MULTI);
		detailsPolicyTree.addSelectionListener(this);
		GridData detailsPrefTreeGD = new GridData(
				GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL);
		detailsPrefTreeGD.heightHint = 50;
		detailsPolicyTree.setLayoutData(detailsPrefTreeGD);
		detailsPolicyTree.setToolTipText(WstSPUIPluginMessages.TOOLTIP_PSP_DETAILSTREE);
		//make the scrollable composite aware of the tree so expand/collapse works properly
		makeScrollableCompositeAware(detailsPolicyTree);
		
		createPolicyOperationsComposite(composite);

		label_DetailsPanel_description = new Label(composite, SWT.NONE);

		label_DetailsPanel_description
				.setText(WstSPUIPluginMessages.LABEL_SERVICEPOLICIES_DESCRIPTION);
		makeScrollableCompositeAware(label_DetailsPanel_description);
		text_DetailsPanel_description = new Text(composite, SWT.WRAP
				| SWT.BORDER | SWT.V_SCROLL | SWT.READ_ONLY);
		GridData detailsGD = new GridData(GridData.HORIZONTAL_ALIGN_FILL
				| GridData.GRAB_HORIZONTAL);
		detailsGD.heightHint = 50;
		detailsGD.widthHint = 400;
		text_DetailsPanel_description.setLayoutData(detailsGD);
		text_DetailsPanel_description.setToolTipText(WstSPUIPluginMessages.TOOLTIP_PSP_DESCRIPTION);

		makeScrollableCompositeAware(text_DetailsPanel_description);
		label_detailsPanel_dependancies = new Label(composite, SWT.NONE);
		makeScrollableCompositeAware(label_detailsPanel_dependancies);
		label_detailsPanel_dependancies
				.setText(WstSPUIPluginMessages.LABEL_SERVICEPOLICIES_DEPENDENCIES);
		text_DetailsPanel_dependencies = new Text(composite, SWT.WRAP
				| SWT.BORDER | SWT.V_SCROLL | SWT.READ_ONLY);
		text_DetailsPanel_dependencies.setToolTipText(WstSPUIPluginMessages.TOOLTIP_PSP_DEPENDENCIES);
		makeScrollableCompositeAware(text_DetailsPanel_dependencies);
		GridData dependenciesGD = new GridData(GridData.HORIZONTAL_ALIGN_FILL
				| GridData.GRAB_HORIZONTAL);
		dependenciesGD.heightHint = 100;
		dependenciesGD.widthHint = 400;
		text_DetailsPanel_dependencies.setLayoutData(dependenciesGD);

		return pageContent;
	}

	/**
	 * Creates the scrollable composite that will contain widgets associated with a policy operation
	 * @param parent the parent composite
	 */
	private void createPolicyOperationsComposite(Composite parent) {
		operationsScrolledComposite = new ScrolledComposite(parent,
				SWT.H_SCROLL | SWT.V_SCROLL);
		operationsScrolledComposite.setExpandHorizontal(true);
		operationsScrolledComposite.setExpandVertical(true);
		GridData operationsScrolledCompositeGD = new GridData(
				GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL);
		operationsScrolledCompositeGD.heightHint =60;
		operationsScrolledComposite.setLayoutData(operationsScrolledCompositeGD);
		operationsComposite = new Composite(operationsScrolledComposite,
				SWT.NONE);
		operationsScrolledComposite.setContent(operationsComposite);
		GridLayout layout = new GridLayout();
		layout.numColumns = 2;
		operationsComposite.setLayout(layout);
//		GridData operationsCompositeGD = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL);
//		operationsCompositeGD.heightHint = 1000;
//		operationsCompositeGD.widthHint = 1000;
//		operationsComposite.setLayoutData(operationsCompositeGD);
		operationsScrolledComposite.setMinSize(operationsComposite.computeSize(
				400, 100));
		makeScrollableCompositeAware(operationsScrolledComposite);
		makeScrollableCompositeAware(operationsComposite);
	}

	public ServicePoliciesComposite(Composite parent, IProject project,
			SelectionListener listener) {

		super(parent, SWT.NONE);
		this.project = project;
		this.listener = listener;
		allErrors = new Hashtable<String, IStatus>();
		helpSystem = PlatformUI.getWorkbench().getHelpSystem();
		GridLayout parentLayout = new GridLayout();
		parentLayout.numColumns = 2;
		parentLayout.horizontalSpacing = 0;
		this.setLayout(parentLayout);
		this.setLayoutData(new GridData(GridData.FILL_BOTH));
		masterComposite = new Composite(this, SWT.NONE);

		GridLayout masterLayout = new GridLayout();
		masterLayout.numColumns = 1;
		masterLayout.horizontalSpacing = 0;
		masterComposite.setLayout(masterLayout);
		masterComposite.setLayoutData(new GridData(GridData.FILL_VERTICAL));

		detailsComposite = new Composite(this, SWT.NONE);
		GridLayout detailsLayout = new GridLayout();
		detailsLayout.numColumns = 1;
		detailsLayout.horizontalSpacing = 0;
		detailsComposite.setLayout(detailsLayout);
		detailsComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
		masterPolicyTree = new Tree(masterComposite, SWT.BORDER | SWT.MULTI);
		masterPolicyTree.setLayoutData(new GridData(GridData.FILL_VERTICAL));
		masterPolicyTree.setToolTipText(WstSPUIPluginMessages.TOOLTIP_PSP_TREE);

		Composite othersComposite = createDetailsScrollPageContent(detailsComposite);
		GridData gridData = new GridData(GridData.FILL, GridData.FILL, true,
				true);
		othersComposite.setLayoutData(gridData);

		masterPolicyTree.addSelectionListener(this);

		List<IServicePolicy> policyList = platform.getRootServicePolicies(null);
		
		policyList = ServiceUtils.sortList( policyList );
		
		for (IServicePolicy policy : policyList) {
			addPolicy(policy, masterPolicyTree, true);
		}
		TreeItem[] treeItems = masterPolicyTree.getItems();
		if (treeItems.length > 0) {
			//select the first item in the tree & fire event so UI is updated
			masterPolicyTree.setSelection(treeItems[0]);
			masterPolicyTree.notifyListeners(SWT.Selection, new Event());
		}
	}

	/**
	 * Sets the image on ti, if associated service policy defines an icon
	 * it will will be used, otherwise default Folder/Leaf icons will be used
	 * @param ti the TreeItem to set the image for
	 * @param sp the service policy associated with ti
	 * @param iconOverlays description of which overlays should be applied 
	 */
	private void setImage(TreeItem ti, IServicePolicy sp, String[] iconOverlays) {
		Image i = (sp.getChildren().size() == 0) ? iconManager.getIconOverlay(
				iconManager.getLeafBaseUrl(), iconOverlays) : iconManager
				.getIconOverlay(iconManager.getFolderBaseUrl(), iconOverlays);
		if (sp.getDescriptor() != null) {
			String iconPathBundleID = null;
			String iconPath = null;
			iconPathBundleID = sp.getDescriptor().getIconBundleId();
			iconPath = sp.getDescriptor().getIconPath();
			if (iconPathBundleID != null && iconPath != null
					&& iconPathBundleID.length() > 0 && iconPath.length() > 0) {
				Bundle b = Platform.getBundle(iconPathBundleID);
				i = iconManager.getIconOverlay(FileLocator.find(b,
						new Path(iconPath), null).toString(), iconOverlays);
			}
		}
		ti.setImage(i);
		// image has changed, notify change listeners so tree gets updated
		ti.notifyListeners(SWT.Modify, new Event());
	}
	
	private boolean is4thLevelOrHigherPolicy (IServicePolicy sp) {
		return sp.getParentPolicy() != null
		&& sp.getParentPolicy().getParentPolicy() != null && sp.getParentPolicy().getParentPolicy().getParentPolicy() != null;
		
	}
	
	private boolean is3rdLevelPolInMasterTreeWithChildren (List<IServicePolicy> spListInMasterTree) {
		return spListInMasterTree.get(0).getParentPolicy() != null && spListInMasterTree.get(0).getParentPolicy().getParentPolicy() != null
		&& spListInMasterTree.get(0).getChildren().size() > 0 ;
	}
	/**
	 * Add service policy sp and children of sp to the parent
	 * @param sp the service policy to add
	 * @param parent either a Tree (masterPolicyTree or DetailsPolicyTree), or a TreeItem
	 * to add service policy children to
	 * @param addUpToLevel3Only false if should add 4th and higher level
	 * child policies
	 */
	private void addPolicy(IServicePolicy sp, Widget parent,
			boolean addUpToLevel3Only) {
		sp.addPolicyChildChangeListener(this);
		addStateListener( sp );
		if (addUpToLevel3Only && is4thLevelOrHigherPolicy(sp) )
			// don't add 4th level and higher branches, these are added on demand
			// to a different tree
			return;
		TreeItem ti;
		if (parent instanceof TreeItem)
			ti = new TreeItem((TreeItem) parent, SWT.NONE);
		else
			ti = new TreeItem((Tree) parent, SWT.NONE);
		ti.setText(sp.getDescriptor().getLongName());
		ti.setData(sp);

		setImage(ti, sp, getIconOverlayInfo(sp, false));
		List<IServicePolicy> childrenPolicyList = sp.getChildren();
		
		childrenPolicyList = ServiceUtils.sortList( childrenPolicyList );
		
		for (IServicePolicy policy : childrenPolicyList) {
			addPolicy(policy, ti, addUpToLevel3Only);
		}

	}

	/**
	 * Returns icon overlay information
	 * @param sp the service policy that should have some overlay images associated with it
	 * @param invalid true if the service policy is valid
	 * @return String[] containing information about what overlays to apply to the icon that
	 * is associated with sp
	 */
	private String[] getIconOverlayInfo(IServicePolicy sp, boolean invalid) {
		String[] overLays = new String[4];
				
		IPolicyState polState = (project == null) ? sp.getPolicyState() : sp
				.getPolicyState(project);
		IPolicyStateEnum polEnum = (project == null) ? sp.getPolicyStateEnum()
				: sp.getPolicyStateEnum(project);
		if (!polState.isMutable())
			overLays[0] = iconManager.lock;
		if ((sp.getStatus() != null && sp.getStatus().getSeverity() == IStatus.ERROR) || invalid)
			overLays[1] = iconManager.invalid;
		if ((sp.getStatus() != null && sp.getStatus().getSeverity() == IStatus.WARNING))
			overLays[2] = iconManager.warning;
		if (polEnum != null) {
			if (polEnum.getEnumId().equals(
					"org.eclipse.wst.service.policy.booleanEnum")) { //$NON-NLS-1$
				if (policyHasIconSelectionOperationSelected(sp))
					overLays[3] = iconManager.favorite;
			}
				
		}
		return overLays;
	}

	/**
	 * @param sp
	 */
	private boolean policyHasIconSelectionOperationSelected(IServicePolicy sp) {
		boolean iconSelectionOperationSelected = false;
		List<IPolicyOperation> operationList = platformUI.getOperations(sp, project == null);
		for (IPolicyOperation operationItem : operationList) {
			if (operationItem.getOperationKind().equals(OperationKind.iconSelection)) {
				String stateID = operationItem.getStateItem(project);
				if (stateID.equals("org.eclipse.wst.true"))  //$NON-NLS-1$
					return true;
			}
			
		}
		return iconSelectionOperationSelected;
	}

	/**
	 * Does anything necessary because the default button has been pressed.
	 */
	public void performDefaults() {
		initializeDefaults();
		List<IServicePolicy> policyList = platform.getRootServicePolicies(null);
		
		policyList = ServiceUtils.sortList( policyList );
		masterPolicyTree.removeAll();
		
		for (IServicePolicy policy : policyList) {
			addPolicy(policy, masterPolicyTree, true);
		}
		TreeItem[] treeItems = masterPolicyTree.getItems();
		if (treeItems.length > 0) {
			//select the first item in the tree & fire event so UI is updated
			masterPolicyTree.setSelection(treeItems[0]);
			masterPolicyTree.notifyListeners(SWT.Selection, new Event());
			error = validateAllPolicies((IServicePolicy)treeItems[0].getData());
		}

	}
	private class ChildChangeEvent {
		public ChildChangeEvent(List<IServicePolicy> changedChildren, List<Boolean> added ) {
			this.changedChildren = changedChildren;
			this.added = added;
			
		}
		private List<IServicePolicy> changedChildren;
		private List<Boolean> added;
		public List<IServicePolicy> getChangedChildren() {
			return changedChildren;
		}
		public void setChangedChildren(List<IServicePolicy> changedChildren) {
			this.changedChildren = changedChildren;
		}
		public List<Boolean> getAdded() {
			return added;
		}
		public void setAdded(List<Boolean> added) {
			this.added = added;
		}
	}
	/* (non-Javadoc)
	 * @see org.eclipse.wst.ws.service.policy.listeners.IPolicyChildChangeListener#childChange(List<org.eclipse.wst.ws.service.policy.IServicePolicy>, List<java.lang.Boolean>)
	 */
	public void childChange( List<IServicePolicy> child, List<Boolean> added ) {
		//ignore events unless we are in a complex operation
		if (!bComplexOpCompleted)
			//cache the event until complex operation completed
			listChildChangeEvents.add(new ChildChangeEvent(child, added));
			
	}
	
	
	/**
	 * @param child
	 * @param added
	 */
	private void processChildChangeEvent(ChildChangeEvent cce,
			Hashtable<String, IServicePolicy> htTopLevelAddtions) {
		List<IServicePolicy> changedServicePolicyList = cce.getChangedChildren();
		List<Boolean> changedServicePolicyAddedList = cce.getAdded();
		for (int i = 0; i < changedServicePolicyList.size(); i++) {
			IServicePolicy nextChangedServicePolicy = changedServicePolicyList.get(i);
			boolean added = changedServicePolicyAddedList.get(i);
			if (!added) {
				//delete node
				processChildChangeEventRemoveServicePolicy(nextChangedServicePolicy);
			} else {
				//an addition, only process top level additions as this is a recursive operation (adds children too)
				if (htTopLevelAddtions.containsKey(nextChangedServicePolicy.getId())) {
					processChildChangeEventAddServicePolicy(nextChangedServicePolicy);
				}
			}
		}
	}

	
	/**
	 * @param nextChangedServicePolicy
	 */
	private void processChildChangeEventRemoveServicePolicy(IServicePolicy nextChangedServicePolicy) {
		boolean is4thLevelOrHigher = is4thLevelOrHigherPolicy(nextChangedServicePolicy);
		
		removeStateListener( nextChangedServicePolicy );
		
		if (is4thLevelOrHigher) {
			if (detailsPolicyTree.isVisible()) {
				TreeItem[] children = detailsPolicyTree.getItems();
				TreeItem found = null;
				for (int i=0; i < children.length; i++) {
					 found = findPolicy(nextChangedServicePolicy, children[i]);	
					 if (found != null)
						 break;
				}
				if (found != null && !found.isDisposed()) {
					processChildChangeEventDeleteTreeItem(found);
				}
			}
		} else {
			TreeItem[] children = masterPolicyTree.getItems();
			TreeItem found = null;
			for (int i=0; i < children.length; i++) {
				 found = findPolicy(nextChangedServicePolicy, children[i]);	
				 if (found != null)
					 break;
			}
			if (found != null && !found.isDisposed()) {
				processChildChangeEventDeleteTreeItem(found);
				
			}

			
			
		}
		
	}

	/**
	 * Delete the item, and choose set a new selection as appropriate from one of the policy trees 
	 * @param deleteItem
	 */
	private void processChildChangeEventDeleteTreeItem(TreeItem deleteItem) {
		Tree parentTree = deleteItem.getParent();
		Tree selectionTree = parentTree;
		TreeItem parentTreeItem = deleteItem.getParentItem();
		//index of found in the tree
		int idx = (parentTreeItem == null) ? parentTree.indexOf(deleteItem) : parentTreeItem.indexOf(deleteItem);
		//is index the last index in the tree
		boolean isLastIndex = (parentTreeItem == null) ? parentTree.indexOf(deleteItem) == parentTree.getItemCount() -1 : parentTreeItem.indexOf(deleteItem) == parentTreeItem.getItemCount() -1;
		//number of siblings
		int siblingsCount = (parentTreeItem == null) ? parentTree.getItemCount() -1 : parentTreeItem.getItemCount() -1;
		boolean hasParent = (parentTreeItem == null) ? parentTree.getItemCount() == 0 : parentTreeItem.getItemCount() == 0;
		deleteItem.dispose();
		parentTree.redraw();
		TreeItem selectItem = null;
		if (siblingsCount == 0) {
			if (hasParent) {
			//no siblings, select parent
			if  (parentTreeItem == null) 
				selectItem = parentTree.getItem(0);
			else 
				selectItem = parentTreeItem;
			} else {
				if (parentTree == detailsPolicyTree)
					//select something from master tree
					if (masterPolicyTree.getItems().length > 0) {
						selectItem = masterPolicyTree.getItem(0);
						selectionTree = masterPolicyTree;
					}
				
			}
			
		} else {
			if  (parentTreeItem == null) {
				if (isLastIndex)
					selectItem = parentTree.getItem(idx -1);
				else 
					selectItem = parentTree.getItem(idx);
			} else {
				if (isLastIndex)
					selectItem = parentTreeItem.getItem(idx -1);
				else 
					selectItem = parentTreeItem.getItem(idx);

			}
		}
		if (selectItem != null) {
			selectionTree.setSelection(selectItem);
			selectionTree.notifyListeners(SWT.Selection, new Event());
		}
	}

	/**
	 * @param policyToAdd
	 */
	private void processChildChangeEventAddServicePolicy(IServicePolicy policyToAdd) {
		boolean is4thLevelOrHigher = is4thLevelOrHigherPolicy(policyToAdd);
		IServicePolicy parent = policyToAdd.getParentPolicy();
		if (is4thLevelOrHigher) {
			if (detailsPolicyTree.isVisible()) {
				TreeItem[] children = detailsPolicyTree.getItems();
				TreeItem found = null;
				for (int i=0; i < children.length; i++) {
					 found = findPolicy(parent, children[i]);	
					 if (found != null)
						 break;
				}
				if (found != null && !found.isDisposed()) {
					addPolicy(policyToAdd, found, false);
				}
			}
		} else {
				//less than 4th level policy
				TreeItem[] children = masterPolicyTree.getItems();
				TreeItem found = null;
				for (int i=0; i < children.length; i++) {
					 found = findPolicy(parent, children[i]);	
					 if (found != null)
						 break;
				}
				if (found != null && !found.isDisposed()) {
					addPolicy(policyToAdd, found, false);
					
				}
		}
	}

	/**
	 * Find the policy within the tree ti
	 * @param policyToFind
	 */
	private TreeItem findPolicy(IServicePolicy policyToFind, TreeItem ti) {
		TreeItem toReturn = null;
		if (ti == null || !(ti.getData() instanceof IServicePolicy))
			return toReturn;
		IServicePolicy sp = (IServicePolicy)ti.getData();
		if (sp.getId().equals(policyToFind.getId()))
			return ti;
		else {
			TreeItem[] tiChildren = ti.getItems();
			for (int i =0; i < tiChildren.length; i++) {
				toReturn = findPolicy(policyToFind, tiChildren[i]);
				if (toReturn != null)
					break;
			}
		}
		return toReturn;
	}
	/**
	 * Initializes states of the controls using default values in the preference
	 * store.
	 */
	private void initializeDefaults() {
		if (project == null)
			platform.restoreDefaults();
		else
			platform.restoreDefaults(project);

	}

	/* (non-Javadoc)
	 * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
	 */
	public void widgetSelected(SelectionEvent e) {
		if (e.getSource() == masterPolicyTree || e.getSource() == detailsPolicyTree) {
			TreeItem[] selectedItems;
			if (e.getSource() == masterPolicyTree)
				selectedItems = masterPolicyTree.getSelection();
			else
				selectedItems = detailsPolicyTree.getSelection();
			//possible that an event is fired and no nodes selected
			if (!(selectedItems.length > 0))
				return;
			List<IServicePolicy> sp = new Vector<IServicePolicy>();
			for (int i = 0; i < selectedItems.length; i++) {
				sp.add((IServicePolicy) selectedItems[i].getData());
			}
			//update the context sensitive help
			updateCSH(sp);
			updateInfoPanels(sp);

			if (e.getSource() == masterPolicyTree) {
				// if selected node in master tree is 3rd level & has
				// children, populate details tree
				if (is3rdLevelPolInMasterTreeWithChildren(sp)) {
					populateDetailsPolicyTree(sp);
				} else {
					//if expandable composite was visible, collapse and set invisible
					if (excomposite.getVisible()) {
						excomposite.setVisible(false);
						excomposite.setExpanded(false);
						expandedStateChanged(excomposite);
					}
				}
			}
			addActionButtons(sp);
			lastSelectedSp = sp;

		} else {
			// an action control fired a change event
			Control actionControl = (Control) e.getSource();
			Object  oldData       = actionControl.getData();
			
			updatePolicy(actionControl);
			
			if( lastSelectedSp != null )
			{
			  addActionButtons(lastSelectedSp);  
			}
			
			//policy updates might delete nodes in the tree, so make sure action control not disposed
			IServicePolicy changedSP = null;
			if (!actionControl.isDisposed())
				changedSP = ((ActionControlData) actionControl.getData())
					.getSpList().get(0);
			error = validateAllPolicies(changedSP);
			//inform listeners that a control has changed, as composite may be in error now
			listener.widgetSelected(e);
			
			setFocusForLastControl( oldData );
		}
	}

	// The UI is continually recreating the action buttons, so the focus is
	// is lost when an action button is selected.  This method attempts
	// to find the newly created control that is associated with operation
	// that was previously selected.  The focus is then reestablished for this 
	// control.
	private void setFocusForLastControl( Object oldData )
	{
	  if( oldData != null && oldData instanceof ActionControlData )
	  {
	    ActionControlData controlData       = (ActionControlData)oldData;
	    IPolicyOperation  operation         = controlData.getPoList().get(0);
	    Control[]         compositeControls = operationsComposite.getChildren();
 
	    for( Control newControl : compositeControls )
	    {
	      Object newData = newControl.getData();
	      
	      if( newData != null && newData instanceof ActionControlData )
	      {
	        IPolicyOperation newOperation = ((ActionControlData)newData).poList.get(0);
	        
	        if( newOperation == operation )
	        {
	          newControl.setFocus();
	          break;
	        }
	      }
	    }
	  }
	}
	
	/**
	 * Populate the details policy tree with sp and their children
	 * @param sp a list of top level details tree service policies
	 */
	private void populateDetailsPolicyTree(List<IServicePolicy> sp) {
		List<IServicePolicy> childpolicyList = sp.get(0)
				.getChildren();
		detailsPolicyTree.removeAll();
		for (IServicePolicy policy : childpolicyList) {
			addPolicy(policy, detailsPolicyTree, false);
		}
		// update details preference tree
		TreeItem[] treeItems = detailsPolicyTree.getItems();
		for (int i = 0; i < treeItems.length; i++) {
			updateValidStates(treeItems[i], true);
		}

		excomposite.setVisible(true);
		excomposite.setText(sp.get(0).getDescriptor().getLongName()
				+ " (" + WstSPUIPluginMessages.TEXT_DETAILS + ")"); //$NON-NLS-1$ //$NON-NLS-2$
		// text has changed, so need to force layout so updated
		excomposite.layout();
	}

	/**
	 * Updates the details and dependencies panels for the first service
	 * policy in spList
	 * @param spList a list of selected service policies
	 */
	private void updateInfoPanels(List<IServicePolicy> spList) {
		String desc = (spList.get(0) == null
				|| spList.get(0).getDescriptor() == null || spList.get(0)
				.getDescriptor().getDescription() == null) ? "" : spList.get(0) //$NON-NLS-1$
				.getDescriptor().getDescription();
		text_DetailsPanel_description.setText(desc);
		text_DetailsPanel_dependencies.setText(getDependanciesText(spList
				.get(0)));
	}

	/**
	 * Updates the context sensitive help for the composite with 
	 * that defined for the first policy in spList (or a parent of 
	 * first policy in spList policy does not define any CSH)
	 * @param spList the list of selected service policies
	 */
	private void updateCSH(List<IServicePolicy> spList) {
		String CSH_ID = (spList.get(0) == null || spList.get(0).getDescriptor() == null) ? null
				: spList.get(0).getDescriptor().getContextHelpId();
		IServicePolicy parentSP = spList.get(0);
		while ((CSH_ID == null || CSH_ID.length() == 0)) {
			parentSP = parentSP.getParentPolicy();
			if (parentSP == null)
				break;
			CSH_ID = (parentSP.getDescriptor() == null) ? null : parentSP
					.getDescriptor().getContextHelpId();
		}
		helpSystem.setHelp(this, CSH_ID);
	}

	/**
	 * Validates all Service Policies in the model
	 * 
	 * @param IServicePolicy
	 *            the focus policy, i.e. one that changed state
	 * @return IStatus null if no Service policies in error, otherwise a Service
	 *         Policy error (the focucPolicy error if it is in error).
	 *         Postcondition- the error property is updated.
	 */
	private IStatus validateAllPolicies(IServicePolicy focusPolicy) {
		// remove all errors as going to re-validate
		allErrors.clear();
		// re-validate all policies in model
		List<IServicePolicy> servicePolicyList = platform
				.getRootServicePolicies(null);
		for (IServicePolicy servicePolicyItem : servicePolicyList) {
			validatePolicy(servicePolicyItem);
		}
		// get the error for the selected/focusPolicy
		IStatus error = (focusPolicy == null) ? null : allErrors
				.get(focusPolicy.getId());
		//if there was no error for the selected/focusPolicy, get the first error in the list of errors
		if (error == null)
			if (!allErrors.isEmpty())
				error = allErrors.get(allErrors.keys().nextElement());

		// update master policy tree nodes denoting node error status
		TreeItem[] treeItems = masterPolicyTree.getItems();
		for (int i = 0; i < treeItems.length; i++) {
			updateValidStates(treeItems[i], false);
		}
		if (detailsPolicyTree.isVisible()) {
			// update details preference tree nodes denoting node error status
			treeItems = detailsPolicyTree.getItems();
			for (int i = 0; i < treeItems.length; i++) {
				updateValidStates(treeItems[i], false);
			}

		}
		return error;
	}

	/**
	 * Updates the policy trees to reflect valid or invalid states, invalid states are 
	 * propagated up through the tree, and up to master tree if updateDetailsOnly is false
	 * @param ti the TreeItem to update, updates ti and all it's children
	 * @param updateDetailsOnly if false then propagate invalid states into
	 * master tree 
	 */
	private void updateValidStates(TreeItem ti, boolean updateDetailsOnly) {
		// assume tree item is valid for now
		IServicePolicy sp = (IServicePolicy) ti.getData();
		setValidPolicyState(ti);

		if (allErrors.containsKey(sp.getId()))
			setInvalidPolicyState(ti, updateDetailsOnly);
		TreeItem[] treeItems = ti.getItems();
		if (ti.getItems().length == 0) {
			if (sp.getChildren().size() != 0 && policyChildrenInvalid(sp))
				setInvalidPolicyState(ti, updateDetailsOnly);
		} else {
			for (int i = 0; i < treeItems.length; i++) {

				updateValidStates(treeItems[i], updateDetailsOnly);
			}
		}

	}

	/**
	 * Checks whether the sp has invalid children
	 * @param sp the service policy whose children may be invalid
	 * @return true if sp has an invalid child
	 */
	private boolean policyChildrenInvalid(IServicePolicy sp) {
		boolean toReturn = false;
		List<IServicePolicy> servicePolicyList = sp.getChildren();
		for (IServicePolicy servicePolicyItem : servicePolicyList) {
			if (allErrors.containsKey(servicePolicyItem.getId()))
				return true;
			else
				toReturn = policyChildrenInvalid(servicePolicyItem);
		}
		return toReturn;
	}

	/**
	 * Validates the Service Policies for the sp and all it's children, creating 
	 * error status objects for any unsatisfied relationships
	 * 
	 * @param sp
	 *            the service policy to validate
	 */
	private void validatePolicy(IServicePolicy sp) {
		String operationLongName;
		String operationSelectionLongName;
		String dependantPolicyShortName;
		List<IPolicyRelationship> relationShipList = sp.getRelationships();
		String currentValueID = null;
		if (relationShipList != null && relationShipList.size() > 0) {
		for (IPolicyRelationship relationShipItem : relationShipList) {
			//operations for the policy
			List<IPolicyOperation> policyOperationsList = platformUI
					.getOperations(relationShipItem.getPolicyEnumerationList()
							.getPolicy(), project == null);
			//default operation name
			operationLongName = ""; //$NON-NLS-1$
			for (IPolicyOperation policyOperationItem : policyOperationsList) {
				if (policyOperationItem.isUseDefaultData()) {
					operationLongName = policyOperationItem.getDescriptor()
							.getLongName();
					currentValueID = policyOperationItem.getStateItem(project);
					break;
				}
			}
			// a list of states
			List<IStateEnumerationItem> spStateEnumerationList = relationShipItem
					.getPolicyEnumerationList().getEnumerationList();
			// a list of related policies and their acceptable states to satisfy a stateEnumerationItem in spStateEnumerationList
			List<IPolicyEnumerationList> relatedPolicies = relationShipItem
					.getRelatedPolicies();
			for (IStateEnumerationItem stateEnumerationItem : spStateEnumerationList) {
				if (stateEnumerationItem.getId() != currentValueID)
					continue;
				//long name of the related policy operation
				operationSelectionLongName = stateEnumerationItem.getLongName();
				for (IPolicyEnumerationList relatedPolicyEnumerationItem : relatedPolicies) {
					dependantPolicyShortName = relatedPolicyEnumerationItem
							.getPolicy().getDescriptor().getShortName();
					//the list of related sp states that satisfy the stateEnumerationItem
					List<IStateEnumerationItem> relatedSPStateEnumerationList = relatedPolicyEnumerationItem
							.getEnumerationList();
					//the list of valid ids for the related service policy operation
					List<String> validIds = new Vector<String>();
					for (int i = 0; i < relatedSPStateEnumerationList
							.size(); i++) {
						validIds
								.add(relatedSPStateEnumerationList
										.get(i).getId());

					}
					//get the current value of the related service policy default operation
					String currentItemID = ""; //$NON-NLS-1$
					List<IPolicyOperation> relatedServicePolicyPolicyOperationsList = platformUI.getOperations(relatedPolicyEnumerationItem.getPolicy(), project ==null);
					IPolicyOperation relatedPolicyOperationItem = null;
					for (IPolicyOperation relatedServicePolicyPolicyOperationItem : relatedServicePolicyPolicyOperationsList) {
						if (relatedServicePolicyPolicyOperationItem.isUseDefaultData()) {
							currentItemID = relatedServicePolicyPolicyOperationItem.getStateItem(project);
							relatedPolicyOperationItem = relatedServicePolicyPolicyOperationItem;
							break;
						}
					}
					
					if (!validIds
							.contains(currentItemID)) {
						// policy state is invalid
						IStatus error = createUnsatisfiedRelationshipError(sp,
								operationLongName,
								operationSelectionLongName,
								dependantPolicyShortName,
								relatedPolicyOperationItem,
								relatedSPStateEnumerationList);
						allErrors.put(sp.getId(), error);

					}


				}

			}

		}
		}

		List<IServicePolicy> servicePolicyChildrenList = sp.getChildren();
		for (IServicePolicy servicePolicyChildrenItem : servicePolicyChildrenList) {
			validatePolicy(servicePolicyChildrenItem);

		}

	}

	/**
	 * Sets the icon for the ti denoting it as valid
	 * @param ti a valid tree item
	 */
	private void setValidPolicyState(TreeItem ti) {
		IServicePolicy sp = (IServicePolicy) ti.getData();
		setImage(ti, sp, getIconOverlayInfo(sp, false));
	}

	/**
	 * Sets the icon for ti denoting it as invalid, as well as ti's parent tree items
	 * @param ti an invalid tree item
	 * @param updateDetailsOnly true indicates do not update parent tree items only in master tree
	 */
	private void setInvalidPolicyState(TreeItem ti, boolean updateDetailsOnly) {
		IServicePolicy SP = (IServicePolicy) ti.getData();
		setImage(ti, SP, getIconOverlayInfo(SP, true));
		TreeItem parent;
		if (ti.getParent() == masterPolicyTree || updateDetailsOnly)
			parent = ti.getParentItem();
		else
			parent = (ti.getParentItem() == null && SP.getParentPolicy() != null) ? getParentInMasterTree(SP
					.getId())
					: ti.getParentItem();
		while (parent != null) {
			setImage(parent, (IServicePolicy) parent.getData(),
					getIconOverlayInfo((IServicePolicy) parent.getData(),
							true));
			if (updateDetailsOnly)
				parent = parent.getParentItem();
			else {
				parent = (parent.getParentItem() == null && ((IServicePolicy) parent
						.getData()).getParentPolicy() != null) ? getParentInMasterTree(((IServicePolicy) parent
						.getData()).getParentPolicy().getId())
						: parent.getParentItem();
			}

		}
	}

	/**
	 * Creates an error status object for the sp. The error message contains information about 
	 * an unsatisfied relationship
	 * @param sp
	 * @param operationLongName
	 * @param operationSelectionLongName
	 * @param dependantPolicyShortName
	 * @param relatedOperation
	 * @param relatedOperationAcceptableValues
	 * @return an Error status
	 */
	private IStatus createUnsatisfiedRelationshipError(IServicePolicy sp,
			String operationLongName, String operationSelectionLongName,
			String dependantPolicyShortName,
			IPolicyOperation relatedOperation,
			List<IStateEnumerationItem> relatedOperationAcceptableValues) {
		String dependantOperationShortName;
		String dependantOperationSelectionShortNameList;
		dependantOperationShortName = relatedOperation
				.getDescriptor().getShortName();
		dependantOperationSelectionShortNameList = new String();
		for (int i = 0; i < relatedOperationAcceptableValues.size(); i++) {
			IStateEnumerationItem item = relatedOperationAcceptableValues.get(i);
			if (i != 0)
				dependantOperationSelectionShortNameList += " | "; //$NON-NLS-1$
			dependantOperationSelectionShortNameList += item.getShortName();

		}
		String[] args = { sp.getDescriptor().getLongName(), operationLongName,
				operationSelectionLongName, dependantPolicyShortName,
				dependantOperationShortName,
				dependantOperationSelectionShortNameList};
		IStatus error = new Status(Status.ERROR,
				ServicePolicyActivatorUI.PLUGIN_ID, NLS.bind(
						WstSPUIPluginMessages.SERVICEPOLICIES_DEPENDENCY_ERROR,
						args));
		return error;
	}

	/**
	 * @param parentID the id to find in the master tree
	 * @return a TreeItem with the id in the master tree
	 */
	private TreeItem getParentInMasterTree(String parentID) {
		TreeItem parent = null;
		TreeItem[] rootNodes = masterPolicyTree.getItems();
		for (int i = 0; i < rootNodes.length; i++) {
			parent = findChildNode(rootNodes[i], parentID);
			if (parent != null)
				break;
		}
		return parent;

	}

	/**
	 * Returns a TreeItem associated with a child policy of ti
	 * @param ti
	 * @param id the policy id of a child node of ti
	 * @return null if there is no child policy matching id
	 */
	private TreeItem findChildNode(TreeItem ti, String id) {
		TreeItem toReturn = null;
		if (((IServicePolicy) ti.getData()).getId().equals(id)) {
			toReturn = ti;
		} else {
			TreeItem[] childItems = ti.getItems();
			for (int i = 0; i < childItems.length; i++) {
				toReturn = findChildNode(childItems[i], id);
			}

		}
		return toReturn;

	}

	/**
	 * Returns dependancy information about sp, that is information about
	 * it's relationships (if any) with other service policies
	 * @param sp the service policy to get dependency info about
	 * @return
	 */
	private String getDependanciesText(IServicePolicy sp) {
		// the relationships defined for the policy
		List<IPolicyRelationship> relationShipList = sp.getRelationships();
		if (relationShipList == null || relationShipList.size() == 0)
			return WstSPUIPluginMessages.SERVICEPOLICIES_DEPENDENCIES_NONE;
		String toReturn = new String();

		String operationLongName;
		String operationSelectionLongName;
		String dependantPolicyShortName;
		String dependantOperationShortName;
		String dependantOperationSelectionShortNameList;

		for (IPolicyRelationship relationShipItem : relationShipList) {
			List<IPolicyOperation> policyOperationsList = platformUI
					.getOperations(relationShipItem.getPolicyEnumerationList()
							.getPolicy(), project == null);
			operationLongName = ""; //$NON-NLS-1$
			for (IPolicyOperation policyOperationItem : policyOperationsList) {
				if (policyOperationItem.isUseDefaultData()) {
					operationLongName = policyOperationItem.getDescriptor()
							.getLongName();
				break;
				}
			}
			// policies associated with the relationship item
			List<IPolicyEnumerationList> relatedPolicies = relationShipItem
					.getRelatedPolicies();
			List<IStateEnumerationItem> spStateEnumerationList = relationShipItem
					.getPolicyEnumerationList().getEnumerationList();
			for (IStateEnumerationItem stateEnumerationItem : spStateEnumerationList) {
				operationSelectionLongName = stateEnumerationItem.getLongName();
				for (IPolicyEnumerationList relatedPolicyEnumerationItem : relatedPolicies) {
					dependantPolicyShortName = relatedPolicyEnumerationItem
							.getPolicy().getDescriptor().getShortName();
					List<IStateEnumerationItem> relatedSPStateEnumerationList = relatedPolicyEnumerationItem
							.getEnumerationList();
					List<IPolicyOperation> relatedPolicyOperationsList = platformUI
							.getOperations(relatedPolicyEnumerationItem
									.getPolicy(), (project == null));
					dependantOperationShortName = ""; //$NON-NLS-1$
					for (IPolicyOperation relatedPolicyOperationItem : relatedPolicyOperationsList) {
						if (relatedPolicyOperationItem.isUseDefaultData())
							dependantOperationShortName = relatedPolicyOperationItem
									.getDescriptor().getShortName();
						break;
					}

					dependantOperationSelectionShortNameList = new String();
					for (int i = 0; i < relatedSPStateEnumerationList.size(); i++) {
						IStateEnumerationItem item = relatedSPStateEnumerationList
								.get(i);
						if (i != 0)
							dependantOperationSelectionShortNameList += " | "; //$NON-NLS-1$
						dependantOperationSelectionShortNameList += item
								.getShortName();

					}
					String[] args = { operationLongName,
							operationSelectionLongName,
							dependantPolicyShortName,
							dependantOperationShortName,
							dependantOperationSelectionShortNameList };
					toReturn += NLS.bind(
							WstSPUIPluginMessages.SERVICEPOLICIES_DEPENDENCIES,
							args)
							+ "\r\n"; //$NON-NLS-1$

				}

			}

		}
		return toReturn;
	}


	/**
	 * Saves to the preference store the widget data (widget data contains all 
	 * service policy operations the control applies to)
	 * @param actionControl a widget who's data needs to be saved to the preference store
	 * 
	 */
	private void updatePolicy(Control actionControl) {

		List<IPolicyOperation> policyOperationList = ((ActionControlData) actionControl.getData()).getPoList();
		IPolicyOperation po0 = policyOperationList.get(0);
		
		List<IServicePolicy> servicePolicyList = ((ActionControlData) actionControl
				.getData()).getSpList();
		if (actionControl instanceof Button
				&& po0.getOperationKind().equals(OperationKind.complex))
			updateComplexOperationPreference(po0, servicePolicyList);
		else
			for (IPolicyOperation policyOperationItem : policyOperationList) {

				updateSelectionOperationPreference(actionControl, policyOperationItem);
			}

	}

	public boolean okToLeave() {
		return allErrors.size() == 0;

	}

	/**
	 * Saves value of enumeration, selection, and iconselection type operations
	 * to the preference store
	 * @param actionControl the action control containing the value to set for the preference
	 * @param po 
	 * @param sp
	 */
	private void updateSelectionOperationPreference(Control actionControl, IPolicyOperation po) {
		String selectedValue;
		
		// We are updating the state of a service policy.  We don't want this
		// update to trigger our state change listener.
		enableStateListener( false );
		
		if (actionControl instanceof Combo) {
			selectedValue = ((Combo) actionControl).getText();
			List<IStateEnumerationItem> enumItemList = ServicePolicyPlatform
					.getInstance().getStateEnumeration(po.getEnumerationId());
			for (IStateEnumerationItem enumItem : enumItemList) {
				if (enumItem.getLongName().equals(selectedValue)) {
					po.setStateItem(project, enumItem.getId());
					break;
				}
			}

		} else {
			if (((Button) actionControl).getSelection()) {
				po.setStateItem(project, "org.eclipse.wst.true"); //$NON-NLS-1$
			} else
				po.setStateItem(project, "org.eclipse.wst.false"); //$NON-NLS-1$

		}

		// Reenable our state change listener.
		enableStateListener( true );
	}

	
	private void addStateListener( IServicePolicy policy )
	{
	  if( stateChangePolicySet.contains( policy ) ) return;
	  
	  if( project == null )
	  {
	    policy.getPolicyState().addPolicyStateChangeListener( stateChangeListener, false );
	  }
	  else
	  {
	    policy.getPolicyState( project ).addPolicyStateChangeListener( stateChangeListener, false );
	  }
	  
	  stateChangePolicySet.add( policy );
	}
	
	private void removeStateListener( IServicePolicy policy )
	{
    if( stateChangePolicySet.contains( policy ) ) return;
    
    if( project == null )
    {
	    policy.getPolicyState().removePolicyStateChangeListener( stateChangeListener );
    }
    else
    {
      policy.getPolicyState( project ).removePolicyStateChangeListener( stateChangeListener );      
    }
    
	  stateChangePolicySet.remove( policy );
	}
	
	private void enableStateListener( boolean enabled )
	{
	  stateChangeEnabled = enabled;
	}
	
	/**
	 * Launches the complex operation for the list of service policies
	 * @param po a "complex" policy operation 
	 * @param sps a list of service policies to apply the operation to
	 */
	private void  updateComplexOperationPreference(IPolicyOperation po,
			List<IServicePolicy> sps) {
		//complex operations can result in added and deleted nodes, cache them until operation completed
		bComplexOpCompleted = false;
		listChildChangeEvents = new Vector<ChildChangeEvent>();
		try {
			po.launchOperation(sps);
		} catch (RuntimeException e) {
			//just want to make sure finally clause is executed so can update UI of additions/deletions
		} finally {
			bComplexOpCompleted =true;
			Hashtable<String, IServicePolicy> topLevelAdds = getHighestLevelChildren(listChildChangeEvents, true);
			for (ChildChangeEvent childChangeEventItem : listChildChangeEvents) {
				processChildChangeEvent(childChangeEventItem, topLevelAdds);
			}
			
		}
	}
	private Hashtable<String, IServicePolicy> getHighestLevelChildren (List<ChildChangeEvent> htChildChangeEvents, boolean forAddOnly) {
		Hashtable<String, IServicePolicy> toReturn = new Hashtable<String, IServicePolicy>();
		Iterator<ChildChangeEvent> elements = htChildChangeEvents.iterator();
		ChildChangeEvent next;
		Hashtable<String, IServicePolicy> allSps = new Hashtable<String, IServicePolicy>();
		while (elements.hasNext()) {
			next = elements.next();
			List<IServicePolicy> changedChildrenList = next.getChangedChildren();
			List<Boolean> addedList = next.getAdded();
			for (int i = 0; i < changedChildrenList.size(); i++) {
				if (forAddOnly && addedList.get(i).booleanValue() == true)
					allSps.put(changedChildrenList.get(i).getId(), changedChildrenList.get(i));
			}
		}
		Enumeration<IServicePolicy> servicePolicyElements = allSps.elements();
		IServicePolicy nextServicePolicyElement;
		while (servicePolicyElements.hasMoreElements()) {
			nextServicePolicyElement = servicePolicyElements.nextElement();
			if (nextServicePolicyElement.getParentPolicy() == null || !allSps.containsKey(nextServicePolicyElement.getParentPolicy().getId())) {
				toReturn.put(nextServicePolicyElement.getId(), nextServicePolicyElement);
			}
		}
		return toReturn;
	}
	public void dispose() {
		super.dispose();
		iconManager.dispose();
		
		for( IServicePolicy policy : stateChangePolicySet )
		{
		  IPolicyState state = project == null ? policy.getPolicyState() : policy.getPolicyState( project );
		  
		  state.removePolicyStateChangeListener( stateChangeListener );
		}
	}

	/**
	 * Create UI widgets for operations applicable to the list of service policies sp
	 * @param spList the list of service policies to create UI widgets, the UI widgets
	 * will be used to define operations/preferences to apply to the service policies in the list
	 */
	private void addActionButtons(List<IServicePolicy> spList) {
	  
		// remove existing action controls
		Control[] toRemove = operationsComposite.getChildren();
		for (int i = 0; i < toRemove.length; i++) {
			toRemove[i].dispose();
		}
		List<List<IPolicyOperation>> policyOperationListList = platformUI.getOperationsList(spList, (project == null));

		for (List<IPolicyOperation> policyOperationList : policyOperationListList) {
			if (policyOperationList.size() > 0) {
			if (policyOperationList.get(0).getOperationKind() == IPolicyOperation.OperationKind.complex) {
				addComplexOperationUI(policyOperationList, spList);
			} else
				addSelectionOperationUI(policyOperationList, spList);
			}

		}
		// just removed and added some controls so force composite
		// to re-layout it's controls
		operationsScrolledComposite.setMinSize(operationsComposite.computeSize(
				SWT.DEFAULT, SWT.DEFAULT));
		operationsComposite.layout();
	}
	/**
	 * Creates UI widgets for policy operations of enumeration, selection, and 
	 * iconselection types
	 * @param po the policy operation to create a UI widget for
	 * @param sp the service policies this operation will apply to
	 */
	private void addSelectionOperationUI(List<IPolicyOperation> pos, List<IServicePolicy> sps) {
		//use the first operation instance in the list for data
		IPolicyOperation po0 = pos.get(0);
		//IServicePolicy sp0 = pos.get(0).getServicePolicy();
		IDescriptor d = po0.getDescriptor();
		Control selectionControl;
		if (po0.getOperationKind() == IPolicyOperation.OperationKind.enumeration) {
			Label l = new Label(operationsComposite, SWT.NONE);
			l.setText(d.getLongName() + ":"); //$NON-NLS-1$
			Combo cb = new Combo(operationsComposite, SWT.DROP_DOWN
					| SWT.READ_ONLY);
			selectionControl = cb;
			cb.addSelectionListener(this);
			List<IStateEnumerationItem> enumItemList = ServicePolicyPlatform
					.getInstance().getStateEnumeration(po0.getEnumerationId());
			for (IStateEnumerationItem enumItem : enumItemList) {
				cb.add(enumItem.getLongName());
			}
			l.setEnabled(po0.isEnabled(sps));
			cb.setEnabled(po0.isEnabled(sps));
			if (cb.isEnabled())
				cb.setText(getEnumerationOperationCurrentSelection(po0));
		} else {
			// a selection or icon
			Button checkBox = new Button(operationsComposite, SWT.CHECK);
			selectionControl = checkBox;
			checkBox.addSelectionListener(this);
			GridData checkBoxGD = new GridData();
			checkBoxGD.horizontalSpan = 2;
			checkBox.setLayoutData(checkBoxGD);
			checkBox.setText(d.getLongName());
			checkBox.setEnabled(po0.isEnabled(sps));
			if (checkBox.isEnabled())
				checkBox
						.setSelection(getSelectionOperationCurrentSelection(po0));

		}

		selectionControl.setData(new ActionControlData(sps, pos));

	}
	/**
	 * @param sp a service policy with a selection or iconselection operation defined
	 * @return true if the operation is currently selected
	 */
	private boolean getSelectionOperationCurrentSelection(IPolicyOperation po) {
		return po.getStateItem(project).equals("org.eclipse.wst.true") ? true : false; //$NON-NLS-1$

	}

	/**
	 * @param sp a service policy with an enumeration operation defined
	 * @return the currently selected enumeration item
	 */
	private String getEnumerationOperationCurrentSelection(IPolicyOperation po) {
		String currentSelection = ""; //$NON-NLS-1$
		List<IStateEnumerationItem> enumItemList = ServicePolicyPlatform
		.getInstance().getStateEnumeration(po.getEnumerationId());
		for (IStateEnumerationItem enumItem : enumItemList) {
			if (enumItem.getId().equals(po.getStateItem(project))) {
				currentSelection = enumItem.getLongName();
				break;
			}
		}
		return currentSelection;
	}

	/**
	 * Creates UI widgets for policy operations of complex type
	 * @param po the policy operation to create a UI widget for
	 * @param sps the service policies this operation will apply to
	 */
	private void addComplexOperationUI(List<IPolicyOperation> pos,
			List<IServicePolicy> sps) {
		IPolicyOperation po0 = pos.get(0);
		IDescriptor d = po0.getDescriptor();
		Button pushButton = new Button(operationsComposite, SWT.PUSH);
		GridData pushButtonGD = new GridData();
		pushButtonGD.horizontalSpan = 2;
		pushButton.setLayoutData(pushButtonGD);
		pushButton.setText(d.getLongName());
		pushButton.addSelectionListener(this);
		pushButton.setData(new ActionControlData(sps, pos));
		pushButton.setEnabled(po0.isEnabled(sps));
  
	}

	/* (non-Javadoc)
	 * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
	 */  
	public void widgetDefaultSelected(SelectionEvent e) {

	}

	/**
	 * @return the error that should be shown, if there are multiple validation errors,
	 * return the validation error for a service policy that just changes state (often the
	 * selected service policy)
	 */
	public IStatus getError() {
		return error;
	}
	
	private class StateChangeListener implements IPolicyStateChangeListener
	{
    public void policyStateChange(IServicePolicy policy, String key, String oldValue, String newValue)
    {
      // We are not enabled for state change events so we will ignore this event.
      if( !stateChangeEnabled ) return;
      
      error = validateAllPolicies( policy );
      
      //inform listeners that a control has changed, as composite may be in error now
      listener.widgetSelected( null );
    }	  
	}
}
