/*******************************************************************************
 * Copyright (c) 2000, 2007 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
 *******************************************************************************/
package org.eclipse.update.internal.ui.wizards;

import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.DialogPage;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
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.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.PropertyDialogAction;
import org.eclipse.ui.forms.HyperlinkSettings;
import org.eclipse.ui.forms.events.HyperlinkAdapter;
import org.eclipse.ui.forms.events.HyperlinkEvent;
import org.eclipse.ui.forms.widgets.ScrolledFormText;
import org.eclipse.update.core.ICategory;
import org.eclipse.update.core.IFeature;
import org.eclipse.update.core.IFeatureReference;
import org.eclipse.update.core.IImport;
import org.eclipse.update.core.IIncludedFeatureReference;
import org.eclipse.update.core.IPluginEntry;
import org.eclipse.update.core.ISiteFeatureReference;
import org.eclipse.update.core.IURLEntry;
import org.eclipse.update.core.Utilities;
import org.eclipse.update.core.VersionedIdentifier;
import org.eclipse.update.internal.core.ExtendedSite;
import org.eclipse.update.internal.core.UpdateCore;
import org.eclipse.update.internal.core.UpdateManagerUtils;
import org.eclipse.update.internal.operations.FeatureStatus;
import org.eclipse.update.internal.operations.OperationValidator;
import org.eclipse.update.internal.operations.UpdateUtils;
import org.eclipse.update.internal.operations.OperationValidator.InternalImport;
import org.eclipse.update.internal.operations.OperationValidator.RequiredFeaturesResult;
import org.eclipse.update.internal.ui.UpdateUI;
import org.eclipse.update.internal.ui.UpdateUIImages;
import org.eclipse.update.internal.ui.UpdateUIMessages;
import org.eclipse.update.internal.ui.model.FeatureReferenceAdapter;
import org.eclipse.update.internal.ui.model.SimpleFeatureAdapter;
import org.eclipse.update.internal.ui.model.SiteBookmark;
import org.eclipse.update.internal.ui.model.SiteCategory;
import org.eclipse.update.internal.ui.parts.DefaultContentProvider;
import org.eclipse.update.internal.ui.parts.SWTUtil;
import org.eclipse.update.internal.ui.parts.SharedLabelProvider;
import org.eclipse.update.operations.IInstallFeatureOperation;
import org.eclipse.update.operations.IUpdateModelChangedListener;
import org.eclipse.update.operations.OperationsManager;
import org.eclipse.update.search.IUpdateSearchSite;
import org.eclipse.update.search.UpdateSearchRequest;

public class ReviewPage	extends BannerPage {

	private Label label;
	private ArrayList jobs;
	private Label counterLabel;
	private IStatus validationStatus;
	private Collection problematicFeatures = new HashSet();
	// feature that was recently selected or null
	private IFeature newlySelectedFeature;
	// 
	private FeatureStatus lastDisplayedStatus;
	private PropertyDialogAction propertiesAction;
	private ScrolledFormText descLabel;
	private Button statusButton;
	private Button moreInfoButton;
	private Button propertiesButton;
	private Button selectRequiredFeaturesButton;
	private Button filterCheck;
	private Button filterOlderVersionCheck;
	private ContainmentFilter filter = new ContainmentFilter();
	private LatestVersionFilter olderVersionFilter = new LatestVersionFilter();
	private UpdateSearchRequest searchRequest;
	//private int LABEL_ORDER = 1;
	//private int VERSION_ORDER = 1;
	//private int PROVIDER_ORDER = 1;
    private ContainerCheckedTreeViewer treeViewer;
    private boolean initialized;
    private boolean isUpdateSearch;
  
    
    class TreeContentProvider extends DefaultContentProvider implements
            ITreeContentProvider {

        public Object[] getElements(Object parent) {
            return getSites();
        }

        public Object[] getChildren(final Object parent) {
            if (parent instanceof SiteBookmark) {
                SiteBookmark bookmark = (SiteBookmark) parent;
                bookmark.getSite(null); // triggers catalog creation
                Object[] children = bookmark.getCatalog(true,null);
                ArrayList nonEmptyCategories = new ArrayList(children.length);
                for (int i=0; i<children.length; i++)
                    if (hasChildren(children[i]))
                        nonEmptyCategories.add(children[i]);
                return nonEmptyCategories.toArray();
            } else if (parent instanceof SiteCategory) {
                SiteCategory category = (SiteCategory)parent;
                //return category.getChildren();
                Object[] children = category.getChildren();
                ArrayList list = new ArrayList(children.length);
                for (int i=0; i<children.length; i++) {
                    if (children[i] instanceof FeatureReferenceAdapter) {
                        try {
                            IInstallFeatureOperation job = findJob((FeatureReferenceAdapter)children[i]);
                            if (job != null)
                                list.add(job);
                        } catch (CoreException e) {
                            UpdateCore.log(e.getStatus());
                        }
                    }
                }
                return list.toArray();
            }
            return new Object[0];
        }

        public Object getParent(Object element) {
            if (element instanceof SiteCategory)
                return ((SiteCategory) element).getBookmark();
            if (element instanceof IInstallFeatureOperation) {
                IFeature f = ((IInstallFeatureOperation)element).getFeature();
                ISiteFeatureReference fr = f.getSite().getFeatureReference(f);
                ICategory[] categories = fr.getCategories();
//                if (categories != null && categories.length > 0)
//                    return categories[0];
                SiteBookmark[] sites = (SiteBookmark[])((ITreeContentProvider)treeViewer.getContentProvider()).getElements(null);
                for (int i=0; i<sites.length; i++) {
                	try {
                		if (sites[i].getSite(false, null).getURL() != f.getSite().getSiteContentProvider().getURL()) {
                		    // if the site has mirrors check if this is from the mirror that user selected
                			if (sites[i].getSite(false, null) instanceof ExtendedSite) {
                				ExtendedSite site = (ExtendedSite)sites[i].getSite(false, null);
                				IURLEntry siteMirror = site.getSelectedMirror();
                				if (siteMirror != null && siteMirror.getURL().toExternalForm().equals(f.getSite().getSiteContentProvider().getURL().toExternalForm())) { 
                					// this is the site so proceed with the loop
                				} else {
                					continue;
                				}
                			} else {
                				continue;
                			}
                		}
                	} catch (CoreException ce) {
                		return null;
                	}
                    Object[] children = sites[i].getCatalog(true, null);
                    for (int j = 0; j<children.length; j++) {
                        if (!(children[j] instanceof SiteCategory))
                            continue;
                        for (int c=0; c < categories.length; c++)
                            if (categories[c].getName().equals(((SiteCategory)children[j]).getName()))
                                return children[j];
                    }
                }
            }

            return null;
        }

        public boolean hasChildren(Object element) {
            return (element instanceof SiteBookmark || (
                    element instanceof SiteCategory && getChildren(element).length > 0));
        }

        private SiteBookmark[] getSites() {
            if (searchRequest == null)
                return new SiteBookmark[0];
            else if (searchRequest.getScope().getSearchSites() == null ||
                searchRequest.getScope().getSearchSites().length == 0) {
                // this is an update search, so see if there are any jobs first,
                // and get their sites
                if (jobs != null) {
                    ArrayList sitesList = new ArrayList(jobs.size());
                    for (int i = 0; i < jobs.size(); i++) {
                        IInstallFeatureOperation op = (IInstallFeatureOperation) jobs
                                .get(i);
                        // we need a label for the site, so try to get it from the old
                        // feature update url
                        String label = null;
                        IFeature[] existingFeatures = UpdateUtils
                                .getInstalledFeatures(op.getFeature(), true);
                        if (existingFeatures != null
                                && existingFeatures.length > 0) {
                            IURLEntry entry = op.getFeature()
                                    .getUpdateSiteEntry();
                            label = entry.getAnnotation();
                        }
                        if (label == null)
                            label = op.getFeature().getSite().getURL().toExternalForm();
                                    
                        SiteBookmark bookmark = new SiteBookmark(label,
                                op.getFeature().getSite().getURL(), false);
                        if (sitesList.contains(bookmark))
                            continue;
                        else
                            sitesList.add(bookmark);
                        
                    }
                    if (!sitesList.isEmpty())
                        return (SiteBookmark[]) sitesList
                                .toArray(new SiteBookmark[sitesList.size()]);
                }
                return new SiteBookmark[0];
            } else {
                // search for features
                IUpdateSearchSite[] sites = searchRequest.getScope().getSearchSites();
                SiteBookmark[] siteBookmarks = new SiteBookmark[sites.length];
                for (int i = 0; i < sites.length; i++)
                    siteBookmarks[i] = new SiteBookmark(sites[i].getLabel(),
                            sites[i].getURL(), false);
                return siteBookmarks;
            }
        }
    }

    class TreeLabelProvider extends SharedLabelProvider {

        public Image getImage(Object obj) {
            if (obj instanceof SiteBookmark)
                return UpdateUI.getDefault().getLabelProvider().get(
                        UpdateUIImages.DESC_SITE_OBJ);
            if (obj instanceof SiteCategory)
                return UpdateUI.getDefault().getLabelProvider().get(
                        UpdateUIImages.DESC_CATEGORY_OBJ);
            if (obj instanceof IInstallFeatureOperation) {
                IFeature feature = ((IInstallFeatureOperation) obj).getFeature();
                boolean patch = feature.isPatch();
                
                //boolean problematic=problematicFeatures.contains(feature) && treeViewer.getChecked(obj);
                boolean featureIsProblematic = isFeatureProblematic(feature);
                boolean problematic = treeViewer.getChecked(obj) && featureIsProblematic;
                
                if (!problematic && featureIsProblematic) {
                	Object parent = ((TreeContentProvider)treeViewer.getContentProvider()).getParent(obj);
                	problematic = treeViewer.getChecked(parent) && !treeViewer.getGrayed(parent);
                }
                
                if (patch) {
                    return get(UpdateUIImages.DESC_EFIX_OBJ, problematic? F_ERROR : 0);
                } else {
                    return get(UpdateUIImages.DESC_FEATURE_OBJ, problematic? F_ERROR : 0);
                }
            }
            return super.getImage(obj);

        }

        public String getText(Object obj) {
            if (obj instanceof SiteBookmark) 
                return ((SiteBookmark) obj).getLabel();
            /*
            if (obj instanceof SiteCategory)
                return obj.toString();
                */
            if (obj instanceof IInstallFeatureOperation) {
                IInstallFeatureOperation job = (IInstallFeatureOperation) obj;
                IFeature feature = job.getFeature();
                return feature.getLabel() + " " + feature //$NON-NLS-1$
                            .getVersionedIdentifier()
                            .getVersion()
                            .toString();
            }
            return super.getText(obj);
        }
    }

    class ModelListener implements IUpdateModelChangedListener {
        public void objectChanged(Object object, String property) {
            treeViewer.refresh();
            checkItems();
        }

        public void objectsAdded(Object parent, Object[] children) {
            treeViewer.refresh();
            checkItems();
        }

        public void objectsRemoved(Object parent, Object[] children) {
            treeViewer.refresh();
            checkItems();
        }
        
        private void checkItems() {
            TreeItem[] items = treeViewer.getTree().getItems();
            for (int i = 0; i < items.length; i++) {
                SiteBookmark bookmark = (SiteBookmark) items[i].getData();
                treeViewer.setChecked(bookmark, bookmark.isSelected());
                String[] ignoredCats = bookmark.getIgnoredCategories();
                treeViewer.setGrayed(bookmark, ignoredCats.length > 0
                        && bookmark.isSelected());
            }
        }
    }

	class ContainmentFilter extends ViewerFilter {
		
		private IInstallFeatureOperation[] selectedJobs;
		
		public boolean select(Viewer viewer, Object parent, Object element) {
            if (element instanceof IInstallFeatureOperation) {
                return !isContained((IInstallFeatureOperation) element) || isSelected( selectedJobs, (IInstallFeatureOperation)element);
            } else if ( (element instanceof SiteCategory) || (element instanceof SiteBookmark)){
            	Object[] children = ((ITreeContentProvider)((ContainerCheckedTreeViewer)viewer).getContentProvider()).getChildren(element);
            	for ( int i = 0; i < children.length; i++) {
            		if (select(viewer, element, children[i])) {
            			return true;
            		}
            	}
            	return false;
            }
        
            return true;
		}
		
		private boolean isContained(IInstallFeatureOperation job) {
			VersionedIdentifier vid = job.getFeature().getVersionedIdentifier();

			for (int i = 0; i < jobs.size(); i++) {
				IInstallFeatureOperation candidate = (IInstallFeatureOperation) jobs.get(i);
				if (candidate.equals(job))
					continue;
				IFeature feature = candidate.getFeature();
				if (includes(feature, vid,null))
					return true;
			}
			return false;
		}
		private boolean includes(IFeature feature, VersionedIdentifier vid, ArrayList cycleCandidates) {
			try {
				if (cycleCandidates == null)
					cycleCandidates = new ArrayList();
				if (cycleCandidates.contains(feature))
					throw Utilities.newCoreException(NLS.bind(UpdateUIMessages.InstallWizard_ReviewPage_cycle, feature.getVersionedIdentifier().toString()), null);
				else
					cycleCandidates.add(feature);
				IFeatureReference[] irefs =
					feature.getIncludedFeatureReferences();
				for (int i = 0; i < irefs.length; i++) {
					IFeatureReference iref = irefs[i];
					IFeature ifeature = UpdateUtils.getIncludedFeature(feature, iref);
					VersionedIdentifier ivid =
						ifeature.getVersionedIdentifier();
					if (ivid.equals(vid))
						return true;
					if (includes(ifeature, vid, cycleCandidates))
						return true;
				}
				return false;
			} catch (CoreException e) {
				return false;
			} finally {
				// after this feature has been DFS-ed, it is no longer a cycle candidate
				cycleCandidates.remove(feature);
			}
		}


		public IInstallFeatureOperation[] getSelectedJobs() {
			return selectedJobs;
		}
		

		public void setSelectedJobs(IInstallFeatureOperation[] selectedJobs) {
			this.selectedJobs = selectedJobs;
		}

	
	}

	class LatestVersionFilter extends ViewerFilter {
		
		private IInstallFeatureOperation[] selectedJobs;
		
		public boolean select(Viewer viewer, Object parent, Object element) {
						
            if (element instanceof IInstallFeatureOperation) {
                return isLatestVersion((IInstallFeatureOperation) element) || isSelected( selectedJobs, (IInstallFeatureOperation)element);
            } else if ( (element instanceof SiteCategory) || (element instanceof SiteBookmark)){
            	Object[] children = ((ITreeContentProvider)((ContainerCheckedTreeViewer)viewer).getContentProvider()).getChildren(element);
            	for ( int i = 0; i < children.length; i++) {
            		if (select(viewer, element, children[i])) {
            			return true;
            		}
            	}
                return false;
            }
            
            return true;
		}
		
		private boolean isLatestVersion(IInstallFeatureOperation job) {
			IFeature feature = job.getFeature();
			for (int i = 0; i < jobs.size(); i++) {
				IInstallFeatureOperation candidateJob = (IInstallFeatureOperation) jobs.get(i);
				if (candidateJob.equals(job))
					continue;
				IFeature candidate = candidateJob.getFeature();
				if (feature.getSite() != job.getFeature().getSite())
					continue;
				if (!feature.getVersionedIdentifier().getIdentifier().equals(candidate.getVersionedIdentifier().getIdentifier()))
					continue;
				if (!feature.getVersionedIdentifier().getVersion().isGreaterOrEqualTo(candidate.getVersionedIdentifier().getVersion()))
					return false;
			}
			return true;
		}
		
		public IInstallFeatureOperation[] getSelectedJobs() {
			return selectedJobs;
		}
		
		public void setSelectedJobs(IInstallFeatureOperation[] selectedJobs) {
			this.selectedJobs = selectedJobs;
		}
		
		
	}
	
	class FeaturePropertyDialogAction extends PropertyDialogAction {
		private IStructuredSelection selection;

		public FeaturePropertyDialogAction(
			Shell shell,
			ISelectionProvider provider) {
			super(shell, provider);
		}

		public IStructuredSelection getStructuredSelection() {
			return selection;
		}

		public void selectionChanged(IStructuredSelection selection) {
			this.selection = selection;
		}

	}
	/**
	 * Constructor for ReviewPage2
	 */
	public ReviewPage(boolean isUpdateSearch, UpdateSearchRequest searchRequest, ArrayList jobs) {
		super("Review"); //$NON-NLS-1$
        this.isUpdateSearch = isUpdateSearch;
        this.jobs = jobs;
        if (this.jobs==null) this.jobs = new ArrayList();
        this.searchRequest = searchRequest;
        
		setTitle(UpdateUIMessages.InstallWizard_ReviewPage_title); 
		setDescription(UpdateUIMessages.InstallWizard_ReviewPage_desc); 
		UpdateUI.getDefault().getLabelProvider().connect(this);
		setBannerVisible(false);
	}

	public void dispose() {
		UpdateUI.getDefault().getLabelProvider().disconnect(this);
		super.dispose();
	}

	public void setVisible(boolean visible) {
		super.setVisible(visible);
		
		// when searching for updates, only nested patches can be shown.
		// when searching for features, features and patches can be shown
		String filterText = filterCheck.getText();
		String filterFeatures = UpdateUIMessages.InstallWizard_ReviewPage_filterFeatures; 
		String filterPatches = UpdateUIMessages.InstallWizard_ReviewPage_filterPatches; 

		if (isUpdateSearch && filterText.equals(filterFeatures))
			filterCheck.setText(filterPatches);
		else if ( !isUpdateSearch && filterText.equals(filterPatches))
			filterCheck.setText(filterFeatures);
		
		if (visible && !initialized) {
            initialized = true;
//			jobs.clear();

//			setDescription(UpdateUI.getString("InstallWizard.ReviewPage.searching")); //$NON-NLS-1$;
//			label.setText(UpdateUI.getString("")); //$NON-NLS-1$

			getShell().getDisplay().asyncExec(new Runnable() {
				public void run() {
//					searchRunner.runSearch();
					performPostSearchProcessing();
				}
			});
		}
	}

	private void performPostSearchProcessing() {
		BusyIndicator.showWhile(getShell().getDisplay(), new Runnable() {
			public void run() {
				if (treeViewer != null) {
//                    treeViewer.refresh();
//                    treeViewer.getTree().layout(true);
					if (isUpdateSearch) {
						selectTrueUpdates();
					}
				}
				pageChanged();
				
				int totalCount = jobs != null ? jobs.size(): 0;
				if(totalCount >0) {
					setDescription(UpdateUIMessages.InstallWizard_ReviewPage_desc); 
					label.setText(UpdateUIMessages.InstallWizard_ReviewPage_label); 
				} else {
					if (isUpdateSearch)
						setDescription(UpdateUIMessages.InstallWizard_ReviewPage_zeroUpdates); 
					else
						setDescription(UpdateUIMessages.InstallWizard_ReviewPage_zeroFeatures); 
					label.setText(""); //$NON-NLS-1$
				}
			}
		});
	}
	
	private void selectTrueUpdates() {
		ArrayList trueUpdates = new ArrayList();
		for (int i=0; i<jobs.size(); i++) {
			IInstallFeatureOperation job = (IInstallFeatureOperation)jobs.get(i);
			if (!UpdateUtils.isPatch(job.getFeature()))
				trueUpdates.add(job);
		}
		treeViewer.setCheckedElements(trueUpdates.toArray()); 
		validateSelection(new NullProgressMonitor());
	}	

	/**
	 * @see DialogPage#createControl(Composite)
	 */
	public Control createContents(Composite parent) {
		Composite client = new Composite(parent, SWT.NULL);
		GridLayout layout = new GridLayout();
		layout.numColumns = 2;
		layout.marginWidth = layout.marginHeight = 0;
		client.setLayout(layout);
		label = new Label(client, SWT.NULL);
		label.setText(UpdateUIMessages.InstallWizard_ReviewPage_label); 
		GridData gd = new GridData();
		gd.horizontalSpan = 2;
		label.setLayoutData(gd);

        createTreeViewer(client);

		Composite comp = new Composite(client, SWT.NONE);
		layout = new GridLayout();
		layout.marginWidth = layout.marginHeight = 0;
		comp.setLayout(layout);
		comp.setLayoutData(new GridData(GridData.FILL_VERTICAL));
				
		Composite buttonContainer = new Composite(comp, SWT.NULL);
		gd = new GridData(GridData.FILL_VERTICAL);
		buttonContainer.setLayoutData(gd);
		layout = new GridLayout();
		layout.marginWidth = 0;
		layout.marginHeight = 0; //30?
		buttonContainer.setLayout(layout);
		buttonContainer.setLayoutData(new GridData(GridData.FILL_BOTH));

		Button button = new Button(buttonContainer, SWT.PUSH);
		button.setText(UpdateUIMessages.InstallWizard_ReviewPage_deselectAll); 
		gd =
			new GridData(
				GridData.HORIZONTAL_ALIGN_FILL
					| GridData.VERTICAL_ALIGN_BEGINNING);
		button.setLayoutData(gd);
		SWTUtil.setButtonDimensionHint(button);
		button.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				handleDeselectAll();
			}
		});

		moreInfoButton = new Button(buttonContainer, SWT.PUSH);
		moreInfoButton.setText(UpdateUIMessages.InstallWizard_ReviewPage_moreInfo); 
		gd =
			new GridData(
				GridData.HORIZONTAL_ALIGN_FILL
					| GridData.VERTICAL_ALIGN_BEGINNING);
		moreInfoButton.setLayoutData(gd);
		SWTUtil.setButtonDimensionHint(moreInfoButton);
		moreInfoButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				handleMoreInfo();
			}
		});
		moreInfoButton.setEnabled(false);
		
		
		propertiesButton = new Button(buttonContainer, SWT.PUSH);
		propertiesButton.setText(UpdateUIMessages.InstallWizard_ReviewPage_properties); 
		gd =
			new GridData(
				GridData.HORIZONTAL_ALIGN_FILL
					| GridData.VERTICAL_ALIGN_BEGINNING);
		propertiesButton.setLayoutData(gd);
		SWTUtil.setButtonDimensionHint(propertiesButton);
		propertiesButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				handleProperties();
			}
		});
		propertiesButton.setEnabled(false);

		selectRequiredFeaturesButton = new Button(buttonContainer, SWT.PUSH);
		selectRequiredFeaturesButton.setText(UpdateUIMessages.InstallWizard_ReviewPage_selectRequired);
		gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL
				| GridData.VERTICAL_ALIGN_BEGINNING);
		selectRequiredFeaturesButton.setLayoutData(gd);
		SWTUtil.setButtonDimensionHint(selectRequiredFeaturesButton);
		selectRequiredFeaturesButton
				.addSelectionListener(new SelectionAdapter() {
					public void widgetSelected(SelectionEvent e) {
						BusyIndicator.showWhile(e.display, new Runnable() {
							public void run() {
								selectRequiredFeatures();
								updateItemCount();
							}
						});
					}
				});

		statusButton = new Button(buttonContainer, SWT.PUSH);
		statusButton.setText(UpdateUIMessages.InstallWizard_ReviewPage_showStatus); 
		gd =
			new GridData(
				GridData.HORIZONTAL_ALIGN_FILL
					| GridData.VERTICAL_ALIGN_BEGINNING);
		statusButton.setLayoutData(gd);
		SWTUtil.setButtonDimensionHint(statusButton);
		statusButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				showStatus();
			}
		});

		//new Label(client, SWT.NULL);

		counterLabel = new Label(client, SWT.NULL);
		gd = new GridData();
		gd.horizontalSpan = 2;
		counterLabel.setLayoutData(gd);

		filterOlderVersionCheck = new Button(client, SWT.CHECK);
		filterOlderVersionCheck.setText(UpdateUIMessages.InstallWizard_ReviewPage_filterOlderFeatures); 
		filterOlderVersionCheck.setSelection(true);
		treeViewer.addFilter(olderVersionFilter);
		filterOlderVersionCheck.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {

				IInstallFeatureOperation[] jobs = getSelectedJobs();
				
				if (filterOlderVersionCheck.getSelection())
					treeViewer.addFilter(olderVersionFilter);
				else 
					treeViewer.removeFilter(olderVersionFilter);
				
				olderVersionFilter.setSelectedJobs(jobs);				
				pageChanged(jobs);
			}
		});
		gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
		gd.horizontalSpan = 2;
		filterOlderVersionCheck.setLayoutData(gd);
		
		filterCheck = new Button(client, SWT.CHECK);
		filterCheck.setText(UpdateUIMessages.InstallWizard_ReviewPage_filterFeatures); 
		filterCheck.setSelection(false);
		//tableViewer.addFilter(filter);
		filterCheck.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				
				IInstallFeatureOperation[] jobs = getSelectedJobs();
				
				if (filterCheck.getSelection()) {
					// make sure model is local
					if (downloadIncludedFeatures()) {
						treeViewer.addFilter(filter);
					} else {
						filterCheck.setSelection(false);
					}
				} else {
					treeViewer.removeFilter(filter);
				}
				
				filter.setSelectedJobs(jobs);
				
				pageChanged(jobs);
			}
		});
		gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
		gd.horizontalSpan = 2;
		filterCheck.setLayoutData(gd);
		
		pageChanged();

		PlatformUI.getWorkbench().getHelpSystem().setHelp(client, "org.eclipse.update.ui.MultiReviewPage2"); //$NON-NLS-1$

		Dialog.applyDialogFont(parent);

		return client;
	}

    private void createTreeViewer(final Composite parent) {
        SashForm sform = new SashForm(parent, SWT.VERTICAL);
        GridData gd = new GridData(GridData.FILL_BOTH);
        gd.widthHint = 250;
        gd.heightHint =100;
        sform.setLayoutData(gd);
        
        treeViewer = new ContainerCheckedTreeViewer(sform, SWT.H_SCROLL | SWT.V_SCROLL
                | SWT.BORDER);
        treeViewer.getTree().setLayoutData(new GridData(GridData.FILL_BOTH));
        treeViewer.setContentProvider(new TreeContentProvider());
        treeViewer.setLabelProvider(new TreeLabelProvider());
        treeViewer.setInput(UpdateUI.getDefault().getUpdateModel());

        treeViewer
            .addSelectionChangedListener(new ISelectionChangedListener() {
            public void selectionChanged(SelectionChangedEvent e) {
                handleSelectionChanged((IStructuredSelection) e.getSelection());
            }
        });
        
        treeViewer.addCheckStateListener(new ICheckStateListener() {
            public void checkStateChanged(CheckStateChangedEvent event) {
    			/*
				 * validateSelection(); Object site =
				 * getSite(event.getElement()); ArrayList descendants = new
				 * ArrayList(); collectDescendants(site, descendants); Object[]
				 * nodes = new Object[descendants.size()]; for (int i = 0; i <
				 * nodes.length; i++) nodes[i] = descendants.get(i);
				 * treeViewer.update(nodes, null); updateItemCount();
				 */
				try {
					getContainer().run(true, true,
							getCheckStateOperation(event, parent.getDisplay()));
					getContainer().updateButtons();
					updateStatusButton();
				} catch (InvocationTargetException e) {
					UpdateUI.logException(e);
				} catch (InterruptedException e) {
					UpdateUI.logException(e);
				}
            }
        });
        
      descLabel = new ScrolledFormText(sform, true);
      descLabel.setText(""); //$NON-NLS-1$
      descLabel.setBackground(parent.getBackground());
      HyperlinkSettings settings = new HyperlinkSettings(parent.getDisplay());
      descLabel.getFormText().setHyperlinkSettings(settings);
      descLabel.getFormText().addHyperlinkListener(new HyperlinkAdapter() {
    	  public void linkActivated(HyperlinkEvent e) {
    		  Object href = e.getHref();
    		  if (href==null)
    			  return;
    		  try {
    			  URL url = new URL(href.toString());
    			  PlatformUI.getWorkbench().getBrowserSupport().getExternalBrowser().openURL(url);
    		  }
    		  catch (PartInitException ex) {
    			  UpdateUI.logException(ex);
    		  }
    		  catch (MalformedURLException ex) {
    			  UpdateUI.logException(ex);
    		  }
    	  }
      });
      
      gd = new GridData(SWT.FILL, SWT.FILL, true, true);
      gd.horizontalSpan = 1;
      descLabel.setLayoutData(gd);
      
      sform.setWeights(new int[] {10, 2});
    }
    
	private IRunnableWithProgress getCheckStateOperation(
			final CheckStateChangedEvent event, final Display display) {
		return new IRunnableWithProgress() {
			public void run(IProgressMonitor monitor) {
				monitor.beginTask(UpdateUIMessages.ReviewPage_validating,
						IProgressMonitor.UNKNOWN);
				validateSelection(monitor);
				if (monitor.isCanceled()) {
					undoStateChange(event);
					monitor.done();
					return;
				}
				Object site = getSite(event.getElement());
				ArrayList descendants = new ArrayList();
				collectDescendants(site, descendants, monitor);
				final Object[] nodes = new Object[descendants.size()];
				if (monitor.isCanceled()) {
					undoStateChange(event);
					monitor.done();
					return;
				}
				for (int i = 0; i < nodes.length; i++)
					nodes[i] = descendants.get(i);
				display.syncExec(new Runnable() {
					public void run() {
						treeViewer.update(nodes, null);
						updateItemCount();
					}
				});
				monitor.done();
			}
		};
	}
	
	private void undoStateChange(final CheckStateChangedEvent e) {
		treeViewer.getControl().getDisplay().syncExec(new Runnable() {
			public void run() {
				treeViewer.setChecked(e.getElement(), !e.getChecked());
			}
		});
	}
    
    private void handleSelectionChanged(IStructuredSelection ssel) {
        
        Object item = ssel.getFirstElement();
        String description = null;
        if (item instanceof SiteBookmark) {
            description = ((SiteBookmark)item).getDescription();
        } else if (item instanceof SiteCategory) {
            IURLEntry descEntry = ((SiteCategory)item).getCategory().getDescription();
            if (descEntry != null)
                description = descEntry.getAnnotation();
        } else if (item instanceof IInstallFeatureOperation) {
            jobSelected(ssel);
            return;
        }

        if (description == null)
            description = ""; //$NON-NLS-1$
        //descLabel.setText(UpdateManagerUtils.getWritableXMLString(description), false, true);
        updateDescription(description);
        propertiesButton.setEnabled(false);
        moreInfoButton.setEnabled(false);
    }

/*	
	private void fillContextMenu(IMenuManager manager) {
		if (treeViewer.getSelection().isEmpty()) return;
		Action action = new Action(UpdateUIMessages.InstallWizard_ReviewPage_prop) { 
			public void run() {
				handleProperties();
			}
		};
		manager.add(action);
	}
*/

	private void jobSelected(IStructuredSelection selection) {
		IInstallFeatureOperation job = (IInstallFeatureOperation) selection.getFirstElement();
		IFeature feature = job != null ? job.getFeature() : null;
		IURLEntry descEntry = feature != null ? feature.getDescription() : null;
		String desc = null;
		if (descEntry != null)
			desc = descEntry.getAnnotation();
		if (desc == null)
			desc = ""; //$NON-NLS-1$
		//descLabel.setText(UpdateManagerUtils.getWritableXMLString(desc));
		updateDescription(desc);
		propertiesButton.setEnabled(feature != null);
		moreInfoButton.setEnabled(job != null && getMoreInfoURL(job) != null);
	}
	
	private void updateDescription(String text) {
		descLabel.getFormText().setText(UpdateManagerUtils.getWritableXMLString(text), false, true);
		descLabel.reflow(true);
	}
	
	private void pageChanged() {
		pageChanged(this.getSelectedJobs());
	}
	
	private void pageChanged( IInstallFeatureOperation[] jobsSelected) {
	
		if (jobsSelected.length == 0) {
			lastDisplayedStatus = null;
			setErrorMessage(null);
			setPageComplete(false);
			setValidationStatus(null);
			problematicFeatures.clear();
		}
		treeViewer.setCheckedElements(jobsSelected);
		//validateSelection();
        treeViewer.refresh();
        treeViewer.setCheckedElements(jobsSelected);
        updateItemCount();
	}
	
	private void setValidationStatus(IStatus newValidationStatus) {
		this.validationStatus = newValidationStatus;
		updateStatusButton();
	}
	
	private void updateStatusButton() {
		statusButton.getDisplay().syncExec(new Runnable() {
			public void run() {
				boolean newState = validationStatus != null && validationStatus.getSeverity() != IStatus.OK;
				statusButton.setEnabled(newState);
			}
		});
	}
	
	private void updateItemCount() {
		updateItemCount(-1, -1);
	}
	
	private int getSelectedJobsUniqueCount() {
		Object[] checkedElements = getSelectedJobs();
		Set set = new HashSet();
		for (int i=0; i<checkedElements.length; i++) {
			IInstallFeatureOperation job = (IInstallFeatureOperation)checkedElements[i];
			IFeature feature = job.getFeature();
			if (set.contains(feature))
				continue;
			set.add(feature);
		}
		return set.size();
	}

	private void updateItemCount(int checkedCount, int totalCount) {
		if (checkedCount == -1) {
			checkedCount = getSelectedJobsUniqueCount();
		}
		if (totalCount == -1) {
			totalCount = jobs.size();
		}
		String total = "" + totalCount; //$NON-NLS-1$
		String selected = "" + checkedCount; //$NON-NLS-1$
		counterLabel.setText(
			NLS.bind(UpdateUIMessages.InstallWizard_ReviewPage_counter, (new String[] { selected, total })));	
        counterLabel.getParent().layout();
	}

//	private void handleSelectAll(boolean select) {
//		treeViewer.setAllChecked(select);
////		 make sure model is local (download using progress monitor from container)
//		downloadIncludedFeatures(); 
//			
//		treeViewer.getControl().getDisplay().asyncExec(new Runnable() {
//			public void run() {
//				pageChanged();
//			}
//		});
//	}

//  private void handleSelectAll(boolean select) {
//  treeViewer.setAllChecked(select);
////     make sure model is local (download using progress monitor from container)
//  downloadIncludedFeatures(); 
//      
//  treeViewer.getControl().getDisplay().asyncExec(new Runnable() {
//      public void run() {
//          pageChanged();
//      }
//  });
//}

   private void handleDeselectAll() {
        //treeViewer.setCheckedElements(new Object[0]);
         IInstallFeatureOperation[] selectedJobs = getSelectedJobs();
         for( int i = 0; i < selectedJobs.length; i++)
        	 treeViewer.setChecked( selectedJobs[i], false);
        // make sure model is local (download using progress monitor from
        // container)
//        downloadIncludedFeatures();

        treeViewer.getControl().getDisplay().asyncExec(new Runnable() {
            public void run() {
                pageChanged();
            }
        });
}
    
	private void handleProperties() {
		final IStructuredSelection selection =
			(IStructuredSelection) treeViewer.getSelection();

		final IInstallFeatureOperation job =
			(IInstallFeatureOperation) selection.getFirstElement();
		if (propertiesAction == null) {
			propertiesAction =
				new FeaturePropertyDialogAction(getShell(), treeViewer);
		}

		BusyIndicator
			.showWhile(treeViewer.getControl().getDisplay(), new Runnable() {
			public void run() {
				SimpleFeatureAdapter adapter =
					new SimpleFeatureAdapter(job.getFeature());
				propertiesAction.selectionChanged(
					new StructuredSelection(adapter));
				propertiesAction.run();
			}
		});
	}

	private String getMoreInfoURL(IInstallFeatureOperation job) {
		IURLEntry desc = job.getFeature().getDescription();
		if (desc != null) {
			URL url = desc.getURL();
			return (url == null) ? null : url.toString();
		}
		return null;
	}

	private void handleMoreInfo() {
		IStructuredSelection selection =
			(IStructuredSelection) treeViewer.getSelection();
		final IInstallFeatureOperation selectedJob =
			(IInstallFeatureOperation) selection.getFirstElement();
		BusyIndicator
			.showWhile(treeViewer.getControl().getDisplay(), new Runnable() {
			public void run() {
				String urlName = getMoreInfoURL(selectedJob);
				UpdateUI.showURL(urlName);
			}
		});
	}

	private IStatus selectRequiredFeatures() {
		
		IInstallFeatureOperation[] jobs = getSelectedJobs();
		RequiredFeaturesResult requiredFeaturesResult = ((OperationValidator)OperationsManager
				.getValidator()).getRequiredFeatures(jobs);
		setValidationStatus(requiredFeaturesResult.getStatus());
		Set requiredFeatures = requiredFeaturesResult.getRequiredFeatures();
		problematicFeatures.clear();
		
		Iterator requiredFeaturesIterator = requiredFeatures.iterator();
		ArrayList toBeInstalled = new ArrayList();
		
		while (requiredFeaturesIterator.hasNext()) {
			IImport requiredFeature = ((InternalImport)requiredFeaturesIterator.next()).getImport();

			IInstallFeatureOperation currentFeatureSelected = null;
			TreeItem[] items = treeViewer.getTree().getItems();
			for (int i = 0; i < items.length; i++) {
				TreeItem[] siteRootContent = items[i].getItems();
				for (int j = 0; j < siteRootContent.length; j++) {
					if (siteRootContent[j].getData() instanceof SiteCategory) {
						
						if ( !treeViewer.getChecked(siteRootContent[j].getData())) {
							// this category has not been checked at all so we have to create its features
							treeViewer.createChildren(siteRootContent[j]);
						}
						TreeItem[] features = siteRootContent[j].getItems();
						if ((features.length > 0) && (features[0].getData() == null)) {
							// this category has been checked but not visited yet so restore the features in it
							treeViewer.createChildren(siteRootContent[j]);
							treeViewer.updateChildrenItems(siteRootContent[j]);
							features = siteRootContent[j].getItems();
						}
						
						for (int k = 0; k < features.length; k++) {
							currentFeatureSelected = decideOnFeatureSelection(
									requiredFeature,
									(IInstallFeatureOperation) features[k]
											.getData(), currentFeatureSelected);
						}
					} else if (siteRootContent[j].getData() instanceof IInstallFeatureOperation) {
						currentFeatureSelected = decideOnFeatureSelection(
								requiredFeature,
								(IInstallFeatureOperation) siteRootContent[j]
										.getData(), currentFeatureSelected);
					}
				}
			}

			if (currentFeatureSelected != null)
				toBeInstalled.add(currentFeatureSelected);
		}

		if (!toBeInstalled.isEmpty()) {
			Iterator toBeInstalledIterator = toBeInstalled.iterator();
			while (toBeInstalledIterator.hasNext()) {
				IInstallFeatureOperation current = (IInstallFeatureOperation)toBeInstalledIterator.next();
				treeViewer.setChecked(current, true);			
			}
			return selectRequiredFeatures();
		} else {
			problematicFeatures.clear();
			if (validationStatus != null) {
				IStatus[] status = validationStatus.getChildren();
				for (int i = 0; i < status.length; i++) {
					IStatus singleStatus = status[i];
					if (isSpecificStatus(singleStatus)) {
						IFeature f = ((FeatureStatus) singleStatus)
								.getFeature();
						problematicFeatures.add(f);
					}
				}
			}

			setPageComplete(validationStatus == null
					|| validationStatus.getSeverity() == IStatus.WARNING);

			lastDisplayedStatus = null;
			updateWizardMessage();
			
			treeViewer.update(getSelectedJobs(), null);
			return validationStatus;
		}
	}

	public IInstallFeatureOperation[] getSelectedJobs() {      
        Object[] selected = treeViewer.getCheckedElements();
        ArrayList selectedJobs = new ArrayList(selected.length);
        for (int i=0; i<selected.length; i++)
            if (selected[i] instanceof IInstallFeatureOperation)
                selectedJobs.add(selected[i]);
        return (IInstallFeatureOperation[])selectedJobs.toArray(new IInstallFeatureOperation[selectedJobs.size()]);
	}
	
	public void validateSelection(IProgressMonitor monitor) {
		IInstallFeatureOperation[] jobs;

		final IInstallFeatureOperation[][] bag = new IInstallFeatureOperation[1][];
		treeViewer.getControl().getDisplay().syncExec(new Runnable() {
			public void run() {
				bag[0] = getSelectedJobs();
			}
		});
		if (monitor.isCanceled()) return;
		jobs = bag[0];
		setValidationStatus(OperationsManager.getValidator()
				.validatePendingChanges(jobs));
		problematicFeatures.clear();
		if (monitor.isCanceled()) return;
		if (validationStatus != null) {
			IStatus[] status = validationStatus.getChildren();
			for (int i = 0; i < status.length; i++) {
				IStatus singleStatus = status[i];
				if (isSpecificStatus(singleStatus)) {
					IFeature f = ((FeatureStatus) singleStatus).getFeature();
					problematicFeatures.add(f);
				}
			}
		}
		if (monitor.isCanceled())
				return;
		treeViewer.getControl().getDisplay().syncExec(new Runnable() {
			public void run() {
				setPageComplete(validationStatus == null
						|| validationStatus.getSeverity() == IStatus.WARNING);
/*
				statusButton.setEnabled(validationStatus != null
						&& validationStatus.getSeverity() != IStatus.OK);
						*/

				updateWizardMessage();
			}
		});
	}

	private void showStatus() {
		if (validationStatus != null) {
			new StatusDialog().open();
		}

	}
	/**
	 * Check whether status is relevant to show for
	 * a specific feature or is a other problem
	 * @param status
	 * @return true if status is FeatureStatus with
	 * specified feature and certain error codes
	 */
	private boolean isSpecificStatus(IStatus status){
		if(!(status instanceof FeatureStatus)){
			return false;
		}
		if(status.getSeverity()!=IStatus.ERROR){
			return false;
		}
		FeatureStatus featureStatus = (FeatureStatus) status;
		if(featureStatus.getFeature()==null){
			return false;
		}
		return 0!= (featureStatus.getCode()
				& FeatureStatus.CODE_CYCLE
				+ FeatureStatus.CODE_ENVIRONMENT
				+ FeatureStatus.CODE_EXCLUSIVE
				+ FeatureStatus.CODE_OPTIONAL_CHILD
				+ FeatureStatus.CODE_PREREQ_FEATURE
				+ FeatureStatus.CODE_PREREQ_PLUGIN);
	}
	/**
	 * Update status in the wizard status area
	 */
	private void updateWizardMessage() {
		
		if (validationStatus == null) {
			lastDisplayedStatus=null;
			setErrorMessage(null);
		} else if (validationStatus.getSeverity() == IStatus.WARNING) {
			lastDisplayedStatus=null;
			setErrorMessage(null);
			setMessage(validationStatus.getMessage(), IMessageProvider.WARNING);
		} else {
			// 1.  Feature selected, creating a problem for it, show status for it
			if(newlySelectedFeature !=null){
				IStatus[] status = validationStatus.getChildren();
				for(int s =0; s< status.length; s++){
					if(isSpecificStatus(status[s])){
						FeatureStatus featureStatus = (FeatureStatus)status[s];
						if(newlySelectedFeature.equals(featureStatus.getFeature())){
							lastDisplayedStatus=featureStatus;
							setErrorMessage(featureStatus.getMessage());
							return;
						}
					}
				}
			}
			
			// 2.  show old status if possible (it is still valid)
			if(lastDisplayedStatus !=null){
				IStatus[] status = validationStatus.getChildren();
				for(int i=0; i<status.length; i++){
					if(lastDisplayedStatus.equals(status[i])){
						//lastDisplayedStatus=lastDisplayedStatus;
						//setErrorMessage(status[i].getMessage());
						return;
					}
				}
				lastDisplayedStatus = null;
			}
			
			// 3.  pick the first problem that is specific to some feature
			IStatus[] status = validationStatus.getChildren();
			for(int s =0; s< status.length; s++){
				if(isSpecificStatus(status[s])){
					lastDisplayedStatus = (FeatureStatus)status[s];
					setErrorMessage(status[s].getMessage());
					return;
				}
			}
				
			// 4.  display the first problem (no problems specify a feature)
			if(status.length>0){
				IStatus singleStatus=status[0];
				setErrorMessage(singleStatus.getMessage());
			}else{
			// 5. not multi or empty multi status
				setErrorMessage(UpdateUIMessages.InstallWizard_ReviewPage_invalid_long); 
			}
		}
	}

	class StatusDialog extends ErrorDialog {
//		Button detailsButton;
		public StatusDialog() {
			super(getContainer().getShell(), UpdateUIMessages.InstallWizard_ReviewPage_invalid_short, null, 
					validationStatus, IStatus.OK | IStatus.INFO
							| IStatus.WARNING | IStatus.ERROR);
		}
//		protected Button createButton(
//				Composite parent,
//				int id,
//				String label,
//				boolean defaultButton) {
//			Button b = super.createButton(parent, id, label, defaultButton);
//			if(IDialogConstants.DETAILS_ID == id){
//				detailsButton = b;
//			}
//			return b;
//		}
		public void create() {
			super.create();
			buttonPressed(IDialogConstants.DETAILS_ID);
//			if(detailsButton!=null){
//				detailsButton.dispose();
//			}
		}
	}

	/**
	 * @return true, if completed, false if canceled by the user
	 */
	private boolean downloadIncludedFeatures() {
		try {
			Downloader downloader = new Downloader(jobs);
			getContainer().run(true, true, downloader);
			return !downloader.isCanceled();
		} catch (InvocationTargetException ite) {
		} catch (InterruptedException ie) {
		}
		return true;
	}
	/**
	 * Runnable to resolve included feature references.
	 */
	class Downloader implements IRunnableWithProgress {
		boolean canceled = false;
		/**
		 * List of IInstallFeatureOperation
		 */
		ArrayList operations;
		public Downloader(ArrayList installOperations) {
			operations = installOperations;
		}
		public boolean isCanceled() {
			return canceled;
		}
		public void run(IProgressMonitor monitor)
				throws InvocationTargetException, InterruptedException {
			for (int i = 0; i < operations.size(); i++) {
				IInstallFeatureOperation candidate = (IInstallFeatureOperation) operations
						.get(i);
				IFeature feature = candidate.getFeature();
				try {
					IFeatureReference[] irefs = feature
							.getRawIncludedFeatureReferences();
					for (int f = 0; f < irefs.length; f++) {
						if (monitor.isCanceled()) {
							canceled = true;
							return;
						}
						IFeatureReference iref = irefs[f];
						iref.getFeature(monitor);
					}
				} catch (CoreException e) {
				}
			}
			if (monitor.isCanceled()) {
				canceled = true;
			}
		}
	}
    
    private IInstallFeatureOperation findJob(FeatureReferenceAdapter feature)
            throws CoreException {
        if (jobs == null)
            return null;
        for (int i = 0; i < jobs.size(); i++)
            if (((IInstallFeatureOperation) jobs.get(i)).getFeature()
                    .getVersionedIdentifier().equals(feature.getFeatureReference()
                    .getVersionedIdentifier()))
                return (IInstallFeatureOperation) jobs.get(i);

        return null;
    }
    
    private Object getSite(Object object) {
        ITreeContentProvider provider = (ITreeContentProvider)treeViewer.getContentProvider();
        while (object != null && !(object instanceof SiteBookmark)) {
            object = provider.getParent(object);
        }
        return object;
    }
    
	private void collectDescendants(Object root, ArrayList list,
			IProgressMonitor monitor) {
		ITreeContentProvider provider = (ITreeContentProvider) treeViewer
				.getContentProvider();
		Object[] children = provider.getChildren(root);
		if (children != null && children.length > 0)
			for (int i = 0; i < children.length; i++) {
				if (monitor.isCanceled())
					return;
				list.add(children[i]);
				collectDescendants(children[i], list, monitor);
			}
	}

	
	public boolean isFeatureGood(IImport requiredFeature, IFeature feature) {
		return isFeatureGood(requiredFeature, feature, new ArrayList());
	}
	
	public boolean isFeatureGood(IImport prereq, IFeature feature, List visitedFeatures) {

		if (prereq.getKind() == IImport.KIND_FEATURE) { 
			if ((!prereq.getVersionedIdentifier().getIdentifier().equals(
					feature.getVersionedIdentifier().getIdentifier()))) {
				IIncludedFeatureReference[] iifr = null;
				try {
					iifr = feature.getIncludedFeatureReferences();
				} catch (CoreException e) {
					UpdateUI.logException(e);
					//	if we can not get included features then they can not satisfy requirement, so just ignore them
					return false;
				}
				if (iifr == null) {
					return false;
				}
				
				for(int i = 0; i < iifr.length; i++) {
					IFeature current;
					try {
						current = UpdateUtils.getIncludedFeature(feature, iifr[i]);
					} catch (CoreException e) {
						// if we can not get feature then it can not satisfy requirement, so just ignore it
						UpdateUI.logException(e);
						continue;
					}
					if (!visitedFeatures.contains(current)) {
						visitedFeatures.add(current);
						if (isFeatureGood(prereq, current, visitedFeatures)) {
							return true;
						}
					}
				}
				
				return false;
			}

			int rule = (prereq.getRule() != IImport.RULE_NONE) ? prereq.getRule() : IImport.RULE_COMPATIBLE;

			switch (rule) {
			case IImport.RULE_PERFECT: return feature.getVersionedIdentifier().getVersion().isPerfect(
								prereq.getVersionedIdentifier()
								.getVersion());
			case IImport.RULE_EQUIVALENT:
						return feature.getVersionedIdentifier().getVersion()
						.isEquivalentTo(
								prereq.getVersionedIdentifier()
								.getVersion());
			case IImport.RULE_COMPATIBLE:
				return feature.getVersionedIdentifier().getVersion()
						.isCompatibleWith(
								prereq.getVersionedIdentifier()
								.getVersion());
			case IImport.RULE_GREATER_OR_EQUAL:
						return feature.getVersionedIdentifier().getVersion()
						.isGreaterOrEqualTo(
								prereq.getVersionedIdentifier()
								.getVersion());
			}

			return false;
		} else {
			if ((prereq.getKind() == IImport.KIND_PLUGIN)) { 
				return checkIfFeatureHasPlugin( prereq, feature);
			}
			return false;
		}
	}
	
	private boolean checkIfFeatureHasPlugin(IImport requiredFeature, IFeature feature)  {
		
		IPluginEntry[] plugins = feature.getPluginEntries();
		try {			
			List includedPlugins = getPluginEntriesFromIncludedFeatures(feature, new ArrayList(), new ArrayList());
			includedPlugins.addAll(Arrays.asList(plugins));
			plugins = (IPluginEntry[])includedPlugins.toArray( new IPluginEntry[includedPlugins.size()]);
		} catch( CoreException ce) {
			UpdateUI.logException(ce);
			// ignore this plugins can not sutisfy requirement anyways
		}
		if (plugins == null) {
			return false;
		}
		
		for(int i = 0; i < plugins.length; i++) {
			if (isMatch(plugins[i].getVersionedIdentifier(), requiredFeature.getVersionedIdentifier(), requiredFeature.getIdRule())) {
				return true;
			}
		}
		
		return false;
	}

	private List getPluginEntriesFromIncludedFeatures(IFeature feature, List plugins, List visitedFeatures) throws CoreException {
		IIncludedFeatureReference[] iifr = feature.getIncludedFeatureReferences();
		for(int i = 0; i < iifr.length; i++) {
			IFeature current = UpdateUtils.getIncludedFeature( feature, iifr[i]);
			if (!visitedFeatures.contains(current)) {
				IPluginEntry[] pluginEntries = current.getPluginEntries();
				plugins.addAll(Arrays.asList(pluginEntries));
				visitedFeatures.add(current);
				getPluginEntriesFromIncludedFeatures(current, plugins, visitedFeatures);
			}
		}
		
		return plugins;
	}

	// vid1 = feature
	// vid2 = requiredFeature
	private boolean isMatch( VersionedIdentifier vid1, VersionedIdentifier vid2, int rule) {
		
		if (!vid1.getIdentifier().equals(vid2.getIdentifier())) {
			return false;
		}
		if ( vid2.getVersion().getMajorComponent() == 0 && vid2.getVersion().getMinorComponent() == 0 && vid2.getVersion().getServiceComponent() == 0 ) {
			//version is ignored
			return true;
		}
		switch (rule) {
		case IImport.RULE_PERFECT:
			return vid1.getVersion().isPerfect(vid2.getVersion());
		case IImport.RULE_EQUIVALENT:
			return vid1.getVersion().isEquivalentTo(vid2.getVersion());
		case IImport.RULE_COMPATIBLE:
			return vid1.getVersion().isCompatibleWith(vid2.getVersion());
		case IImport.RULE_GREATER_OR_EQUAL:
			return vid1.getVersion().isGreaterOrEqualTo(vid2.getVersion());
		}
		return false;
	}

	public boolean isFeatureBetter(IInstallFeatureOperation feature,
			IInstallFeatureOperation currentFeatureSelected) {

		if (currentFeatureSelected == null)
			return true;
		// If the feature is the same, pick the newer one
		if (currentFeatureSelected.getFeature().getVersionedIdentifier().getIdentifier().equals(
				feature.getFeature().getVersionedIdentifier().getIdentifier())) {
			return !currentFeatureSelected.getFeature().getVersionedIdentifier()
			.getVersion().isGreaterOrEqualTo(
					feature.getFeature().getVersionedIdentifier()
							.getVersion());			
		}
		else {
			// Different features.
			// Pick a feature with smaller number of plug-ins
			NullProgressMonitor monitor = new NullProgressMonitor();
			int currentNumber = getTotalNumberOfPluginEntries(currentFeatureSelected.getFeature(), monitor);
			int newNumber = getTotalNumberOfPluginEntries(feature.getFeature(), monitor);
			return newNumber<currentNumber;
		}
	}
	
	private int getTotalNumberOfPluginEntries(IFeature feature, IProgressMonitor monitor) {
		int count = 0;
		try {
			count = feature.getPluginEntryCount();
			IIncludedFeatureReference [] irefs = feature.getIncludedFeatureReferences();
			for (int i=0; i<irefs.length; i++) {
				IFeature child = irefs[i].getFeature(monitor);
				count += getTotalNumberOfPluginEntries(child, monitor);
			}
		}
		catch (CoreException e) {
		}
		return count;
	}

	public IInstallFeatureOperation decideOnFeatureSelection(
			IImport requiredFeature, IInstallFeatureOperation feature,
			IInstallFeatureOperation currentFeatureSelected) {

		if (isFeatureGood(requiredFeature, feature.getFeature()) && isFeatureBetter(feature, currentFeatureSelected)) {
				return feature;
		} else {
			return currentFeatureSelected;
		}
	}
	
	private boolean isFeatureProblematic(IFeature feature) {
		
		if ( problematicFeatures.contains(feature) )
			return true;
		
		IImport[] iimports = feature.getImports();
		
		for(int i = 0; i < iimports.length; i++) {
			Iterator problematicFeatures = this.problematicFeatures.iterator();
			while(problematicFeatures.hasNext()) {
				if (iimports[i].getVersionedIdentifier().equals( ((IFeature)problematicFeatures.next()).getVersionedIdentifier()) ) {
					return true;
				}
			}
		}
		try {
			Iterator includedFeatures = OperationValidator.computeFeatureSubtree(feature, null, null, false, new ArrayList(), null ).iterator();
			while (includedFeatures.hasNext()) {
				Iterator problematicFeatures = this.problematicFeatures.iterator();		
				VersionedIdentifier currentIncludedFeaturesVI = ((IFeature)includedFeatures.next()).getVersionedIdentifier();
				while (problematicFeatures.hasNext()) {
					Object currentProblematicFeatures = problematicFeatures.next();
					if (currentProblematicFeatures instanceof IFeature) {
						VersionedIdentifier currentProblematicFeaturesVI = ((IFeature)currentProblematicFeatures).getVersionedIdentifier();						
						if (currentProblematicFeaturesVI.equals( currentIncludedFeaturesVI) ) {
							return true;
						}
					}
				}
			}
		} catch (CoreException ce) {
		}
 		return false;
	}
	
	private boolean isSelected( IInstallFeatureOperation[] selectedJobs, IInstallFeatureOperation iInstallFeatureOperation) {
		
		if (selectedJobs == null)
			return false;
		
		for( int i = 0; i < selectedJobs.length; i++) {
			
			if (iInstallFeatureOperation.getFeature().getVersionedIdentifier().equals(selectedJobs[i].getFeature().getVersionedIdentifier()) &&
				iInstallFeatureOperation.getFeature().getSite().getURL().equals(selectedJobs[i].getFeature().getSite().getURL())) {
				return true;
			}
		}
		
		return false;
	}
}
