/*******************************************************************************
 * Copyright (c) 2000, 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.update.internal.ui.views;
import java.io.*;
import java.lang.reflect.*;
import java.net.*;
import java.util.*;

import org.eclipse.core.runtime.*;
import org.eclipse.jface.action.*;
import org.eclipse.jface.operation.*;
import org.eclipse.jface.resource.*;
import org.eclipse.jface.viewers.*;
import org.eclipse.swt.*;
import org.eclipse.swt.custom.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.branding.*;
import org.eclipse.ui.dialogs.*;
import org.eclipse.ui.help.*;
import org.eclipse.ui.part.*;
import org.eclipse.update.configuration.*;
import org.eclipse.update.core.*;
import org.eclipse.update.internal.operations.*;
import org.eclipse.update.internal.ui.*;
import org.eclipse.update.internal.ui.model.*;
import org.eclipse.update.internal.ui.parts.*;
import org.eclipse.update.operations.*;
import org.osgi.framework.*;
import org.eclipse.core.runtime.Path;


/**
 * Insert the type's description here.
 * @see ViewPart
 */
public class ConfigurationView
	implements
		IInstallConfigurationChangedListener,
		IConfiguredSiteChangedListener,
		ILocalSiteChangedListener {
	private TreeViewer treeViewer;
	private DrillDownAdapter drillDownAdapter;
	private Action collapseAllAction;
	private static final String STATE_SHOW_UNCONF = "ConfigurationView.showUnconf"; //$NON-NLS-1$
	private static final String STATE_SHOW_SITES = "ConfigurationView.showSites"; //$NON-NLS-1$
	private static final String STATE_SHOW_NESTED_FEATURES =
		"ConfigurationView.showNestedFeatures"; //$NON-NLS-1$

	private Action showSitesAction;
	private Action showNestedFeaturesAction;
	private ReplaceVersionAction swapVersionAction;
	private FeatureStateAction featureStateAction;
	private UninstallFeatureAction uninstallFeatureAction;
	private InstallOptionalFeatureAction installOptFeatureAction;
	private Action showUnconfFeaturesAction;
	private RevertConfigurationAction revertAction;
	private ShowActivitiesAction showActivitiesAction;
	private Action propertiesAction;
	private SiteStateAction siteStateAction;
	private Action installationHistoryAction;
	private Action newExtensionLocationAction;
	private FindUpdatesAction findUpdatesAction;
	private SashForm splitter;
	private ConfigurationPreview preview;
	private Hashtable previewTasks;

	private IUpdateModelChangedListener modelListener;
	private boolean refreshLock = false;
	private Image eclipseImage;
	private boolean initialized;
	private ConfigurationManagerWindow configurationWindow;

	class ConfigurationSorter extends ViewerSorter {
		public int category(Object obj) {
			// sites
			if (obj instanceof IConfiguredSiteAdapter) {
				IConfiguredSite csite =
					((IConfiguredSiteAdapter) obj).getConfiguredSite();
				if (csite.isProductSite())
					return 1;
				if (csite.isExtensionSite())
					return 2;
				return 3;
			}
			return super.category(obj);
		}
	}

	class LocalSiteProvider
		extends DefaultContentProvider
		implements ITreeContentProvider {
		public void inputChanged(
			Viewer viewer,
			Object oldInput,
			Object newInput) {
			if (newInput == null)
				return;
		}

		/**
		 * @see ITreeContentProvider#getChildren(Object)
		 */
		public Object[] getChildren(Object parent) {
			if (parent instanceof UpdateModel) {
				ILocalSite localSite = getLocalSite();
				return (localSite != null) ? new Object[] { localSite }
				: new Object[0];
			}

			if (parent instanceof ILocalSite) {
				Object[] csites = openLocalSite();
				if (showSitesAction.isChecked())
					return csites;
				ArrayList result = new ArrayList();
				boolean showUnconf = showUnconfFeaturesAction.isChecked();
				for (int i = 0; i < csites.length; i++) {
					IConfiguredSiteAdapter adapter =
						(IConfiguredSiteAdapter) csites[i];
					Object[] roots = getFeatures(adapter, !showUnconf);
					for (int j = 0; j < roots.length; j++) {
						result.add(roots[j]);
					}
				}
				return result.toArray();
			}

			if (parent instanceof IConfiguredSiteAdapter) {
				return getFeatures(
					(IConfiguredSiteAdapter) parent,
					!showUnconfFeaturesAction.isChecked());
			}
			if (parent instanceof ConfiguredFeatureAdapter
				&& showNestedFeaturesAction.isChecked()) {
				IFeatureAdapter[] nested =
					((ConfiguredFeatureAdapter) parent).getIncludedFeatures(
						null);
				if (showUnconfFeaturesAction.isChecked())
					return nested;
				ArrayList result = new ArrayList();
				for (int i = 0; i < nested.length; i++) {
					if (((ConfiguredFeatureAdapter) nested[i]).isConfigured())
						result.add(nested[i]);
				}
				return (IFeatureAdapter[]) result.toArray(
					new IFeatureAdapter[result.size()]);
			}
			return new Object[0];
		}

		public Object getParent(Object child) {
			return null;
		}
		public boolean hasChildren(Object parent) {
			if (parent instanceof ConfiguredFeatureAdapter) {
				if (!showNestedFeaturesAction.isChecked())
					return false;
				IFeatureAdapter[] features =
					((ConfiguredFeatureAdapter) parent).getIncludedFeatures(
						null);

				if (showUnconfFeaturesAction.isChecked())
					return features.length > 0;

				for (int i = 0; i < features.length; i++) {
					if (((ConfiguredFeatureAdapter) features[i])
						.isConfigured())
						return true;
				}
				return false;
			}
			if (parent instanceof ConfiguredSiteAdapter) {
				IConfiguredSite site =
					((ConfiguredSiteAdapter) parent).getConfiguredSite();
				if (site.isEnabled()) {
					if (!showUnconfFeaturesAction.isChecked())
						return site.getConfiguredFeatures().length > 0;
					return site.getFeatureReferences().length > 0;
				}
				return (showUnconfFeaturesAction.isChecked());
			}
			return true;
		}

		public Object[] getElements(Object input) {
			return getChildren(input);
		}
	}

	class LocalSiteLabelProvider extends LabelProvider {
		public String getText(Object obj) {
			if (obj instanceof ILocalSite) {
				IProduct product = Platform.getProduct();
				if (product != null)
					return product.getName();
				return UpdateUI.getString("ConfigurationView.current"); //$NON-NLS-1$
			}

			if (obj instanceof IConfiguredSiteAdapter) {
				IConfiguredSite csite =
					((IConfiguredSiteAdapter) obj).getConfiguredSite();
				ISite site = csite.getSite();
				return new File(site.getURL().getFile()).toString();
			}
			if (obj instanceof IFeatureAdapter) {
				try {
					IFeature feature = ((IFeatureAdapter) obj).getFeature(null);
					if (feature instanceof MissingFeature) {
						return UpdateUI.getFormattedMessage(
							"ConfigurationView.missingFeature", //$NON-NLS-1$
							feature.getLabel());
					}
					String version =
						feature
							.getVersionedIdentifier()
							.getVersion()
							.toString();
					String pending = ""; //$NON-NLS-1$
					if (OperationsManager.findPendingOperation(feature)
						!= null)
						pending = UpdateUI.getString("ConfigurationView.pending"); //$NON-NLS-1$
					return feature.getLabel() + " " + version + pending; //$NON-NLS-1$
				} catch (CoreException e) {
					return UpdateUI.getString("ConfigurationView.error"); //$NON-NLS-1$
				}
			}
			return super.getText(obj);
		}

		public Image getImage(Object obj) {
			UpdateLabelProvider provider =
				UpdateUI.getDefault().getLabelProvider();
			if (obj instanceof ILocalSite)
				return eclipseImage;

			if (obj instanceof ConfiguredFeatureAdapter)
				return getFeatureImage(
					provider,
					(ConfiguredFeatureAdapter) obj);

			if (obj instanceof IConfiguredSiteAdapter) {
				IConfiguredSite csite =
					((IConfiguredSiteAdapter) obj).getConfiguredSite();
				int flags =
					csite.isUpdatable() ? 0 : UpdateLabelProvider.F_LINKED;
				if (!csite.isEnabled())
					flags |= UpdateLabelProvider.F_UNCONFIGURED;
				return provider.get(
					provider.getLocalSiteDescriptor(csite),
					flags);
			}
			return null;
		}

		private Image getFeatureImage(
			UpdateLabelProvider provider,
			ConfiguredFeatureAdapter adapter) {
			try {
				IFeature feature = adapter.getFeature(null);
				if (feature instanceof MissingFeature) {
					if (((MissingFeature) feature).isOptional())
						return provider.get(
							UpdateUIImages.DESC_NOTINST_FEATURE_OBJ);
					return provider.get(
						UpdateUIImages.DESC_FEATURE_OBJ,
						UpdateLabelProvider.F_ERROR);
				}

				boolean efix = feature.isPatch();
				ImageDescriptor baseDesc =
					efix
						? UpdateUIImages.DESC_EFIX_OBJ
						: (adapter.isConfigured()
							? UpdateUIImages.DESC_FEATURE_OBJ
							: UpdateUIImages.DESC_UNCONF_FEATURE_OBJ);

				int flags = 0;
				if (efix && !adapter.isConfigured())
					flags |= UpdateLabelProvider.F_UNCONFIGURED;
				if (OperationsManager.findPendingOperation(feature) == null) {
					ILocalSite localSite = getLocalSite();
					if (localSite != null) {
						int code =
							getStatusCode(
								feature,
								localSite.getFeatureStatus(feature));
						switch (code) {
							case IFeature.STATUS_UNHAPPY :
								flags |= UpdateLabelProvider.F_ERROR;
								break;
							case IFeature.STATUS_AMBIGUOUS :
								flags |= UpdateLabelProvider.F_WARNING;
								break;
							default :
								if (adapter.isConfigured()
									&& adapter.isUpdated())
									flags |= UpdateLabelProvider.F_UPDATED;
								break;
						}
					}
				}
				return provider.get(baseDesc, flags);
			} catch (CoreException e) {
				return provider.get(
					UpdateUIImages.DESC_FEATURE_OBJ,
					UpdateLabelProvider.F_ERROR);
			}
		}
	}

	class PreviewTask implements IPreviewTask {
		private String name;
		private String desc;
		private IAction action;
		public PreviewTask(String name, String desc, IAction action) {
			this.name = name;
			this.desc = desc;
			this.action = action;
		}
		public IAction getAction() {
			return action;
		}
		public String getName() {
			if (name != null)
				return name;
			return action.getText();
		}
		public String getDescription() {
			return desc;
		}
		public void setDescription(String desc) {
			this.desc = desc;
		}
		public void run() {
			action.run();
		}
		public boolean isEnabled() {
			return action.isEnabled();
		}
	}

	public ConfigurationView(ConfigurationManagerWindow window) {
		UpdateUI.getDefault().getLabelProvider().connect(this);
		initializeImages();
		configurationWindow=window;
	}

	private void initializeImages() {
		ImageDescriptor edesc = UpdateUIImages.DESC_APP_OBJ;
		IProduct product = Platform.getProduct();
		if (product != null) {
			String windowImageURL = product.getProperty(IProductConstants.WINDOW_IMAGE);
			if (windowImageURL == null) {
				String windowImagesUrls = product.getProperty(IProductConstants.WINDOW_IMAGES);
				if (windowImagesUrls != null ) {
					StringTokenizer st = new StringTokenizer(windowImagesUrls, ","); //$NON-NLS-1$
					if (st.hasMoreTokens())
						windowImageURL = st.nextToken();
				}
			}
			if (windowImageURL != null)
				try {
					edesc = ImageDescriptor.createFromURL(new URL(windowImageURL));
				} catch (MalformedURLException e) {
					// must be a path relative to the product bundle
					Bundle productBundle = product.getDefiningBundle();
					if (productBundle != null) { 
						URL url = Platform.find(productBundle, new Path(windowImageURL));
						if (url != null)
							edesc = ImageDescriptor.createFromURL(url);
					}
				}
		}
		eclipseImage = UpdateUI.getDefault().getLabelProvider().get(edesc);
	}

	public void initProviders() {
		treeViewer.setContentProvider(new LocalSiteProvider());
		treeViewer.setLabelProvider(new LocalSiteLabelProvider());
		treeViewer.setInput(UpdateUI.getDefault().getUpdateModel());
		treeViewer.setSorter(new ConfigurationSorter());
		ILocalSite localSite = getLocalSite();
		if (localSite != null)
			localSite.addLocalSiteChangedListener(this);

		modelListener = new IUpdateModelChangedListener() {
			public void objectsAdded(Object parent, Object[] children) {
			}
			public void objectsRemoved(Object parent, Object[] children) {
			}
			public void objectChanged(final Object obj, String property) {
				if (refreshLock)
					return;
				Control control = getControl();
				if (!control.isDisposed()) {
					control.getDisplay().asyncExec(new Runnable() {
						public void run() {
							treeViewer.refresh();
							handleSelectionChanged(
								(IStructuredSelection) treeViewer
									.getSelection());
						}
					});
				}
			}
		};
		OperationsManager.addUpdateModelChangedListener(modelListener);
		WorkbenchHelp.setHelp(
			getControl(),
			"org.eclipse.update.ui.ConfigurationView"); //$NON-NLS-1$
	}

	private ILocalSite getLocalSite() {
		try {
			return SiteManager.getLocalSite();
		} catch (CoreException e) {
			UpdateUI.logException(e);
			return null;
		}
	}

	private Object[] openLocalSite() {
		final Object[][] bag = new Object[1][];
		BusyIndicator.showWhile(getControl().getDisplay(), new Runnable() {
			public void run() {
				ILocalSite localSite = getLocalSite();
				if (localSite == null)
					return;
				IInstallConfiguration config =
					getLocalSite().getCurrentConfiguration();
				IConfiguredSite[] sites = config.getConfiguredSites();
				Object[] result = new Object[sites.length];
				for (int i = 0; i < sites.length; i++) {
					result[i] = new ConfiguredSiteAdapter(config, sites[i]);
				}
				if (!initialized) {
					config.addInstallConfigurationChangedListener(
						ConfigurationView.this);
					initialized = true;
				}
				bag[0] = result;
			}
		});
		return bag[0];
	}

	public void dispose() {
		UpdateUI.getDefault().getLabelProvider().disconnect(this);
		if (initialized) {
			ILocalSite localSite = getLocalSite();
			if (localSite != null) {
				localSite.removeLocalSiteChangedListener(this);
				IInstallConfiguration config =
					localSite.getCurrentConfiguration();
				config.removeInstallConfigurationChangedListener(this);
			}
			initialized = false;
		}
		OperationsManager.removeUpdateModelChangedListener(modelListener);
		if (preview != null)
			preview.dispose();
		//super.dispose();
	}

	protected void makeActions() {
		collapseAllAction = new Action() {
			public void run() {
				treeViewer.getControl().setRedraw(false);
				treeViewer.collapseToLevel(
					treeViewer.getInput(),
					TreeViewer.ALL_LEVELS);
				treeViewer.getControl().setRedraw(true);
			}
		};
		collapseAllAction.setText(UpdateUI.getString("ConfigurationView.collapseLabel")); //$NON-NLS-1$
		collapseAllAction.setToolTipText(UpdateUI.getString("ConfigurationView.collapseTooltip")); //$NON-NLS-1$
		collapseAllAction.setImageDescriptor(UpdateUIImages.DESC_COLLAPSE_ALL);

		drillDownAdapter = new DrillDownAdapter(treeViewer);

		featureStateAction = new FeatureStateAction(this);

		siteStateAction = new SiteStateAction(getConfigurationWindow().getShell());

		revertAction = new RevertConfigurationAction(getConfigurationWindow().getShell(),UpdateUI.getString("ConfigurationView.revertLabel")); //$NON-NLS-1$
		WorkbenchHelp.setHelp(
			revertAction,
			"org.eclipse.update.ui.CofigurationView_revertAction"); //$NON-NLS-1$

		installationHistoryAction =
			new InstallationHistoryAction(getConfigurationWindow().getShell(),
				UpdateUI.getString("ConfigurationView.installHistory"), //$NON-NLS-1$
				UpdateUIImages.DESC_HISTORY_OBJ);
		installationHistoryAction.setToolTipText(installationHistoryAction.getText());
		
		newExtensionLocationAction =
			new NewExtensionLocationAction(getConfigurationWindow().getShell(),
				UpdateUI.getString("ConfigurationView.extLocation"), //$NON-NLS-1$
				UpdateUIImages.DESC_ESITE_OBJ);
		
		propertiesAction =
			new PropertyDialogAction(
				getConfigurationWindow().getShell(),
				treeViewer);
		WorkbenchHelp.setHelp(
			propertiesAction,
			"org.eclipse.update.ui.CofigurationView_propertiesAction"); //$NON-NLS-1$

		uninstallFeatureAction = new UninstallFeatureAction(getConfigurationWindow().getShell(), UpdateUI.getString("ConfigurationView.uninstall")); //$NON-NLS-1$

		installOptFeatureAction =
			new InstallOptionalFeatureAction(
				getControl().getShell(),
				UpdateUI.getString("ConfigurationView.install")); //$NON-NLS-1$

		swapVersionAction = new ReplaceVersionAction(getConfigurationWindow().getShell(), UpdateUI.getString("ConfigurationView.anotherVersion")); //$NON-NLS-1$

		findUpdatesAction =
			new FindUpdatesAction(getControl().getShell(), UpdateUI.getString("ConfigurationView.findUpdates")); //$NON-NLS-1$

		showActivitiesAction = new ShowActivitiesAction(getControl().getShell(), UpdateUI.getString("ConfigurationView.showActivitiesLabel")); //$NON-NLS-1$
		WorkbenchHelp.setHelp(
			showActivitiesAction,
			"org.eclipse.update.ui.CofigurationView_showActivitiesAction"); //$NON-NLS-1$

		makeShowUnconfiguredFeaturesAction();
		makeShowSitesAction();
		makeShowNestedFeaturesAction();
		makePreviewTasks();
		configurationWindow.setPropertiesActionHandler(propertiesAction);
	}

	private void makeShowNestedFeaturesAction() {
		final Preferences pref = UpdateUI.getDefault().getPluginPreferences();
		pref.setDefault(STATE_SHOW_NESTED_FEATURES, true);
		showNestedFeaturesAction = new Action() {
			public void run() {
				treeViewer.refresh();
				pref.setValue(
					STATE_SHOW_NESTED_FEATURES,
					showNestedFeaturesAction.isChecked());
			}
		};
		showNestedFeaturesAction.setText(UpdateUI.getString("ConfigurationView.showNestedFeatures")); //$NON-NLS-1$
		showNestedFeaturesAction.setImageDescriptor(
			UpdateUIImages.DESC_SHOW_HIERARCHY);
		showNestedFeaturesAction.setDisabledImageDescriptor(
			UpdateUIImages.DESC_SHOW_HIERARCHY_D);

		showNestedFeaturesAction.setChecked(
			pref.getBoolean(STATE_SHOW_NESTED_FEATURES));
		showNestedFeaturesAction.setToolTipText(UpdateUI.getString("ConfigurationView.showNestedTooltip")); //$NON-NLS-1$
	}

	private void makeShowSitesAction() {
		final Preferences pref = UpdateUI.getDefault().getPluginPreferences();
		pref.setDefault(STATE_SHOW_SITES, true);
		showSitesAction = new Action() {
			public void run() {
				treeViewer.refresh();
				pref.setValue(STATE_SHOW_SITES, showSitesAction.isChecked());
				UpdateUI.getDefault().savePluginPreferences();
			}
		};
		showSitesAction.setText(UpdateUI.getString("ConfigurationView.showInstall")); //$NON-NLS-1$
		showSitesAction.setImageDescriptor(UpdateUIImages.DESC_LSITE_OBJ);
		showSitesAction.setChecked(pref.getBoolean(STATE_SHOW_SITES));
		showSitesAction.setToolTipText(UpdateUI.getString("ConfigurationView.showInstallTooltip")); //$NON-NLS-1$
	}

	private void makeShowUnconfiguredFeaturesAction() {
		final Preferences pref = UpdateUI.getDefault().getPluginPreferences();
		pref.setDefault(STATE_SHOW_UNCONF, false);
		showUnconfFeaturesAction = new Action() {
			public void run() {
				pref.setValue(
					STATE_SHOW_UNCONF,
					showUnconfFeaturesAction.isChecked());
				UpdateUI.getDefault().savePluginPreferences();
				treeViewer.refresh();
			}
		};
		WorkbenchHelp.setHelp(
			showUnconfFeaturesAction,
			"org.eclipse.update.ui.CofigurationView_showUnconfFeaturesAction"); //$NON-NLS-1$
		showUnconfFeaturesAction.setText(UpdateUI.getString("ConfigurationView.showDisabled")); //$NON-NLS-1$
		showUnconfFeaturesAction.setImageDescriptor(
			UpdateUIImages.DESC_UNCONF_FEATURE_OBJ);
		showUnconfFeaturesAction.setChecked(pref.getBoolean(STATE_SHOW_UNCONF));
		showUnconfFeaturesAction.setToolTipText(UpdateUI.getString("ConfigurationView.showDisabledTooltip")); //$NON-NLS-1$
	}

	protected void fillActionBars(ToolBarManager tbm) {
		tbm.add(showSitesAction);
		tbm.add(showNestedFeaturesAction);
		tbm.add(showUnconfFeaturesAction);
		tbm.add(new Separator());
		drillDownAdapter.addNavigationActions(tbm);
		tbm.add(new Separator());
		tbm.add(collapseAllAction);
		tbm.add(new Separator());
		tbm.add(installationHistoryAction);
	}

	protected Object getSelectedObject() {
		ISelection selection = treeViewer.getSelection();
		if (selection instanceof IStructuredSelection
			&& !selection.isEmpty()) {
			IStructuredSelection ssel = (IStructuredSelection) selection;
			if (ssel.size() == 1)
				return ssel.getFirstElement();
		}
		return null;
	}

	protected void fillContextMenu(IMenuManager manager) {
		Object obj = getSelectedObject();

		if (obj instanceof ILocalSite) {
			manager.add(findUpdatesAction);
			manager.add(revertAction);
		} else if (obj instanceof IConfiguredSiteAdapter) {
			manager.add(siteStateAction);
		}

		if (obj instanceof ILocalSite
			|| obj instanceof IConfiguredSiteAdapter) {
			manager.add(new Separator());
			MenuManager mgr = new MenuManager(UpdateUI.getString("ConfigurationView.new")); //$NON-NLS-1$
			mgr.add(newExtensionLocationAction);
			manager.add(mgr);
			manager.add(new Separator());
		} else if (obj instanceof ConfiguredFeatureAdapter) {
			try {
				MenuManager mgr = new MenuManager(UpdateUI.getString("ConfigurationView.replaceWith")); //$NON-NLS-1$
				
				manager.add(findUpdatesAction);
				manager.add(new Separator());
				
				mgr.add(swapVersionAction);
				manager.add(mgr);

				manager.add(featureStateAction);

				IFeature feature =
					((ConfiguredFeatureAdapter) obj).getFeature(null);
				if (feature instanceof MissingFeature) {
					manager.add(installOptFeatureAction);
				} else {
					manager.add(uninstallFeatureAction);
				}
				manager.add(new Separator());

			} catch (CoreException e) {
			}
		}

		drillDownAdapter.addNavigationActions(manager);

		if (obj instanceof ILocalSite) {
			manager.add(new Separator());
			manager.add(installationHistoryAction);
		}

		if (obj instanceof IFeatureAdapter
			|| obj instanceof ILocalSite
			|| obj instanceof IConfiguredSiteAdapter) {
			manager.add(new Separator());
			manager.add(propertiesAction);
		}
	}

	public void installSiteAdded(IConfiguredSite csite) {
		asyncRefresh();
	}
	public void installSiteRemoved(IConfiguredSite site) {
		asyncRefresh();
	}
	public void featureInstalled(IFeature feature) {
		asyncRefresh();
	}
	public void featureRemoved(IFeature feature) {
		asyncRefresh();
	}
	public void featureConfigured(IFeature feature) {
	}

	public void featureUnconfigured(IFeature feature) {
	}

	public void currentInstallConfigurationChanged(IInstallConfiguration configuration) {
		asyncRefresh();
	}

	public void installConfigurationRemoved(IInstallConfiguration configuration) {
		asyncRefresh();
	}

	private void asyncRefresh() {
		Display display = SWTUtil.getStandardDisplay();
		if (display == null)
			return;
		if (getControl().isDisposed())
			return;
		display.asyncExec(new Runnable() {
			public void run() {
				if (!getControl().isDisposed())
					treeViewer.refresh();
			}
		});
	}

	private Object[] getFeatures(
		final IConfiguredSiteAdapter siteAdapter,
		final boolean configuredOnly) {
		final IConfiguredSite csite = siteAdapter.getConfiguredSite();
		final Object[][] bag = new Object[1][];
		refreshLock = true;

		IRunnableWithProgress op = new IRunnableWithProgress() {
			public void run(IProgressMonitor monitor) {
				ArrayList result = new ArrayList();
				IFeatureReference[] refs;

				if (configuredOnly)
					refs = csite.getConfiguredFeatures();
				else {
					ISite site = csite.getSite();
					refs = site.getFeatureReferences();
				}
				monitor.beginTask(
					UpdateUI.getString("ConfigurationView.loading"), //$NON-NLS-1$
					refs.length);

				for (int i = 0; i < refs.length; i++) {
					IFeatureReference ref = refs[i];
					IFeature feature;
					try {
						monitor.subTask(ref.getURL().toString());
						feature = ref.getFeature(null);
					} catch (CoreException e) {
						feature =
							new MissingFeature(ref.getSite(), ref.getURL());
					}
					monitor.worked(1);
					result.add(
						new ConfiguredFeatureAdapter(
							siteAdapter,
							feature,
							csite.isConfigured(feature),
							false,
							false));
				}
				monitor.done();
				bag[0] = getRootFeatures(result);
			}
		};

		try {
			if (configurationWindow.getShell().isVisible())
				configurationWindow.run(true, false, op);
			else
				op.run(new NullProgressMonitor());
		} catch (InterruptedException e) {
		} catch (InvocationTargetException e) {
		} finally {
			refreshLock = false;
		}
		return bag[0];
	}

	private Object[] getRootFeatures(ArrayList list) {
		ArrayList children = new ArrayList();
		ArrayList result = new ArrayList();
		try {
			for (int i = 0; i < list.size(); i++) {
				ConfiguredFeatureAdapter cf =
					(ConfiguredFeatureAdapter) list.get(i);
				IFeature feature = cf.getFeature(null);
				if (feature != null)
					addChildFeatures(
						feature,
						children,
						cf.isConfigured());
			}
			for (int i = 0; i < list.size(); i++) {
				ConfiguredFeatureAdapter cf =
					(ConfiguredFeatureAdapter) list.get(i);
				IFeature feature = cf.getFeature(null);
				if (feature != null
					&& isChildFeature(feature, children) == false)
					result.add(cf);
			}
		} catch (CoreException e) {
			return list.toArray();
		}
		return result.toArray();
	}

	private void addChildFeatures(
		IFeature feature,
		ArrayList children,
		boolean configured) {
		try {
			IIncludedFeatureReference[] included =
				feature.getIncludedFeatureReferences();
			for (int i = 0; i < included.length; i++) {
				IFeature childFeature;
				try {
					childFeature =
						included[i].getFeature(null);
				} catch (CoreException e) {
					childFeature = new MissingFeature(included[i]);
				}
				children.add(childFeature);
			}
		} catch (CoreException e) {
			UpdateUI.logException(e);
		}
	}

	private boolean isChildFeature(IFeature feature, ArrayList children) {
		for (int i = 0; i < children.size(); i++) {
			IFeature child = (IFeature) children.get(i);
			if (feature
				.getVersionedIdentifier()
				.equals(child.getVersionedIdentifier()))
				return true;
		}
		return false;
	}

	protected void handleDoubleClick(DoubleClickEvent e) {
		if (e.getSelection() instanceof IStructuredSelection) {
			IStructuredSelection ssel = (IStructuredSelection) e.getSelection();
			Object obj = ssel.getFirstElement();
			if (obj!=null)
				propertiesAction.run();
		}
	}

	public void createPartControl(Composite parent) {
		splitter = new SashForm(parent, SWT.HORIZONTAL);
		splitter.setLayoutData(new GridData(GridData.FILL_BOTH));
		Composite leftContainer = createLineContainer(splitter);
		Composite rightContainer = createLineContainer(splitter);
		createTreeViewer(leftContainer);
		makeActions();
		createVerticalLine(leftContainer);
		createVerticalLine(rightContainer);
		preview = new ConfigurationPreview(this);
		preview.createControl(rightContainer);
		preview.getControl().setLayoutData(
			new GridData(GridData.FILL_BOTH));
		splitter.setWeights(new int[] { 2, 3 });
		fillActionBars(getConfigurationWindow().getToolBarManager());

		treeViewer.expandToLevel(2);
	}

	private void createTreeViewer(Composite parent) {
		treeViewer =
			new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
		treeViewer.getControl().setLayoutData(new GridData(GridData.FILL_BOTH));
		treeViewer.setUseHashlookup(true);
		initProviders();

		MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$
		menuMgr.setRemoveAllWhenShown(true);
		menuMgr.addMenuListener(new IMenuListener() {
			public void menuAboutToShow(IMenuManager manager) {
				manager.add(new GroupMarker("additions")); //$NON-NLS-1$
				fillContextMenu(manager);
			}
		});

		treeViewer.getControl().setMenu(
			menuMgr.createContextMenu(treeViewer.getControl()));

		treeViewer
			.addSelectionChangedListener(new ISelectionChangedListener() {
			public void selectionChanged(SelectionChangedEvent event) {
				handleSelectionChanged(event);
			}
		});

		treeViewer.addDoubleClickListener(new IDoubleClickListener() {
			public void doubleClick(DoubleClickEvent event) {
				handleDoubleClick(event);
			}
		});

	}

	public TreeViewer getTreeViewer() {
		return treeViewer;
	}

	private Composite createLineContainer(Composite parent) {
		Composite container = new Composite(parent, SWT.NULL);
		GridLayout layout = new GridLayout();
		layout.numColumns = 2;
		layout.marginWidth = layout.marginHeight = 0;
		layout.horizontalSpacing = 0;
		container.setLayout(layout);
		return container;
	}

	private void createVerticalLine(Composite parent) {
		Label line = new Label(parent, SWT.SEPARATOR | SWT.VERTICAL);
		GridData gd = new GridData(GridData.VERTICAL_ALIGN_FILL);
		gd.widthHint = 1;
		line.setLayoutData(gd);
	}

	public Control getControl() {
		return splitter;
	}

	private int getStatusCode(IFeature feature, IStatus status) {
		int code = status.getCode();
		if (code == IFeature.STATUS_UNHAPPY) {
			if (status.isMultiStatus()) {
				IStatus[] children = status.getChildren();
				for (int i = 0; i < children.length; i++) {
					IStatus child = children[i];
					if (child.isMultiStatus()
						|| child.getCode() != IFeature.STATUS_DISABLED)
						return code;
				}
				// If we are here, global status is unhappy
				// because one or more included features
				// is disabled.
				if (UpdateUtils.hasObsoletePatches(feature)) {
					// The disabled included features
					// are old patches that are now
					// subsumed by better versions of
					// the features they were designed to
					// patch.
					return IFeature.STATUS_HAPPY;
				}
			}
		}
		return code;
	}

	protected void handleSelectionChanged(IStructuredSelection ssel) {
		Object obj = ssel.getFirstElement();
		if (obj instanceof IFeatureAdapter) {
			try {
				propertiesAction.setEnabled(true);
				
				ConfiguredFeatureAdapter adapter = (ConfiguredFeatureAdapter) obj;
				IFeature feature = adapter.getFeature(null);
				
				boolean missing = feature instanceof MissingFeature;
				boolean enable = !missing && ((adapter.isOptional() || !adapter.isIncluded()));

				featureStateAction.setFeature(adapter);
				featureStateAction.setEnabled(enable);
				
				uninstallFeatureAction.setFeature(adapter);
				uninstallFeatureAction.setEnabled(enable && uninstallFeatureAction.canUninstall());
				if (adapter.isConfigured())
					setDescriptionOnTask(uninstallFeatureAction, adapter,UpdateUI.getString("ConfigurationView.uninstallDesc2"));
				else
					setDescriptionOnTask(uninstallFeatureAction, adapter,UpdateUI.getString("ConfigurationView.uninstallDesc"));

				if (enable && adapter.isConfigured()) {
					IFeature[] features = UpdateUtils.getInstalledFeatures(feature, false);
					swapVersionAction.setEnabled(features.length > 1);
					if (features.length > 1) {
						swapVersionAction.setCurrentFeature(feature);
						swapVersionAction.setFeatures(features);
					}
					findUpdatesAction.setEnabled(true);
					findUpdatesAction.setFeature(feature);
				} else {
					swapVersionAction.setEnabled(false);
					findUpdatesAction.setEnabled(false);
				}

				if (missing) {
					MissingFeature mf = (MissingFeature) feature;
					installOptFeatureAction.setEnabled(
						mf.isOptional() && mf.getOriginatingSiteURL() != null);
					installOptFeatureAction.setFeature(mf);
				} else {
					installOptFeatureAction.setEnabled(false);
				}
			} catch (CoreException ex) {
				UpdateUI.logException(ex);
			}
		}
		if (obj instanceof ILocalSite) {
			propertiesAction.setEnabled(true);
			findUpdatesAction.setEnabled(true);
			findUpdatesAction.setFeature(null);
			ILocalSite site = getLocalSite();
			revertAction.setEnabled(site != null && site.getConfigurationHistory().length > 1);
		} else if (obj instanceof IConfiguredSiteAdapter) {
			siteStateAction.setSite(
				((IConfiguredSiteAdapter) obj).getConfiguredSite());
			siteStateAction.setEnabled(true);
		}
		preview.setSelection(ssel);
	}

	protected void handleSelectionChanged(SelectionChangedEvent e) {
		handleSelectionChanged(((IStructuredSelection) e.getSelection()));
	}

	private void setDescriptionOnTask(IAction action, ConfiguredFeatureAdapter adapter, String desc) {
		IPreviewTask[] tasks = getPreviewTasks(adapter);
		if (tasks == null)
			return;
		for (int i=0; i<tasks.length; i++)
			if (tasks[i].getAction() == action)
				tasks[i].setDescription(desc);
	}
	
	private void makePreviewTasks() {
		previewTasks = new Hashtable();
		Class key;
		ArrayList array = new ArrayList();
		// local site tasks
		key = ILocalSite.class;
		array.add(
			new PreviewTask(
				UpdateUI.getString("ConfigurationView.updateLabel"), //$NON-NLS-1$
				UpdateUI.getString("ConfigurationView.updateDesc"), //$NON-NLS-1$
				findUpdatesAction));
		array.add(
			new PreviewTask(
				UpdateUI.getString("ConfigurationView.installHistLabel"), //$NON-NLS-1$
				UpdateUI.getString("ConfigurationView.installHistDesc"), //$NON-NLS-1$
				installationHistoryAction));
		array.add(
			new PreviewTask(
				UpdateUI.getString("ConfigurationView.activitiesLabel"), //$NON-NLS-1$
				UpdateUI.getString("ConfigurationView.activitiesDesc"), //$NON-NLS-1$
				showActivitiesAction));
		array.add(
				new PreviewTask(
					UpdateUI.getString("ConfigurationView.extLocLabel"), //$NON-NLS-1$
					UpdateUI.getString("ConfigurationView.extLocDesc"), //$NON-NLS-1$
					newExtensionLocationAction));
		array.add(
				new PreviewTask(
					UpdateUI.getString("ConfigurationView.revertPreviousLabel"), //$NON-NLS-1$
					UpdateUI.getString("ConfigurationView.revertPreviousDesc"), //$NON-NLS-1$
					revertAction));

		previewTasks.put(key, array.toArray(new IPreviewTask[array.size()]));

		// configured site tasks
		array.clear();
		key = IConfiguredSiteAdapter.class;
		array.add(
			new PreviewTask(
				null,
				UpdateUI.getString("ConfigurationView.enableLocDesc"), //$NON-NLS-1$
				siteStateAction));
		array.add(
			new PreviewTask(
				UpdateUI.getString("ConfigurationView.extLocLabel"), //$NON-NLS-1$
				UpdateUI.getString("ConfigurationView.extLocDesc"), //$NON-NLS-1$
				newExtensionLocationAction));
		array.add(
			new PreviewTask(
				UpdateUI.getString("ConfigurationView.propertiesLabel"), //$NON-NLS-1$
				UpdateUI.getString("ConfigurationView.installPropDesc"), //$NON-NLS-1$
				propertiesAction));
		previewTasks.put(key, array.toArray(new IPreviewTask[array.size()]));

		// feature adapter tasks
		array.clear();
		key = IFeatureAdapter.class;
		array.add(
				new PreviewTask(
					UpdateUI.getString("ConfigurationView.scanLabel"), //$NON-NLS-1$
					UpdateUI.getString("ConfigurationView.scanDesc"), //$NON-NLS-1$
					findUpdatesAction));
		array.add(
			new PreviewTask(
				UpdateUI.getString("ConfigurationView.replaceVersionLabel"), //$NON-NLS-1$
				UpdateUI.getString("ConfigurationView.replaceVersionDesc"), //$NON-NLS-1$
				swapVersionAction));
		array.add(
			new PreviewTask(
				null,
				UpdateUI.getString("ConfigurationView.enableFeatureDesc"), //$NON-NLS-1$
				featureStateAction));
		array.add(
			new PreviewTask(
				UpdateUI.getString("ConfigurationView.installOptionalLabel"), //$NON-NLS-1$
				UpdateUI.getString("ConfigurationView.installOptionalDesc"), //$NON-NLS-1$
				installOptFeatureAction));
		array.add(
			new PreviewTask(
				UpdateUI.getString("ConfigurationView.uninstallLabel"), //$NON-NLS-1$
				UpdateUI.getString("ConfigurationView.uninstallDesc"), //$NON-NLS-1$
				uninstallFeatureAction));
		array.add(
			new PreviewTask(
				UpdateUI.getString("ConfigurationView.featurePropLabel"), //$NON-NLS-1$
				UpdateUI.getString("ConfigurationView.featurePropDesc"), //$NON-NLS-1$
				propertiesAction));
		previewTasks.put(key, array.toArray(new IPreviewTask[array.size()]));
	}

	public IPreviewTask[] getPreviewTasks(Object object) {
		IPreviewTask[] tasks = null;

		if (object instanceof IFeatureAdapter)
			tasks = (IPreviewTask[]) previewTasks.get(IFeatureAdapter.class);
		if (object instanceof ILocalSite)
			tasks = (IPreviewTask[]) previewTasks.get(ILocalSite.class);
		if (object instanceof IConfiguredSiteAdapter)
			tasks =
				(IPreviewTask[]) previewTasks.get(IConfiguredSiteAdapter.class);
		return (tasks != null) ? tasks : new IPreviewTask[0];
	}

	ConfigurationManagerWindow getConfigurationWindow(){
		return configurationWindow;
	}

}
