/*******************************************************************************
 * Copyright (c) 2000, 2014 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Philippe Ombredanne - bug 84808
 *     William Mitsuda (wmitsuda@gmail.com) - Bug 153879 [Wizards] configurable size of cvs commit comment history
 *     Brock Janiczak <brockj@tpg.com.au> - Bug 161536 Warn user when committing resources with problem markers
 *******************************************************************************/

package org.eclipse.team.internal.ccvs.ui;

import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.*;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceStatus;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.jface.dialogs.*;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferenceConverter;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.osgi.service.debug.DebugOptions;
import org.eclipse.osgi.service.debug.DebugOptionsListener;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.team.core.TeamException;
import org.eclipse.team.core.history.IFileRevision;
import org.eclipse.team.internal.ccvs.core.*;
import org.eclipse.team.internal.ccvs.core.client.Command.KSubstOption;
import org.eclipse.team.internal.ccvs.core.connection.CVSRepositoryLocation;
import org.eclipse.team.internal.ccvs.ui.console.CVSOutputConsole;
import org.eclipse.team.internal.ccvs.ui.model.CVSAdapterFactory;
import org.eclipse.team.internal.ccvs.ui.repo.RepositoryManager;
import org.eclipse.team.internal.ccvs.ui.repo.RepositoryRoot;
import org.eclipse.team.internal.core.subscribers.ActiveChangeSetManager;
import org.eclipse.team.internal.ui.*;
import org.eclipse.ui.*;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;

/**
 * UI Plugin for CVS provider-specific workbench functionality.
 */
public class CVSUIPlugin extends AbstractUIPlugin {
	/**
	 * The id of the CVS plug-in
	 */
	public static final String ID = "org.eclipse.team.cvs.ui"; //$NON-NLS-1$
	public static final String DECORATOR_ID = "org.eclipse.team.cvs.ui.decorator"; //$NON-NLS-1$
	
	/**
	 * Property constant indicating the decorator configuration has changed. 
	 */
	public static final String P_DECORATORS_CHANGED = CVSUIPlugin.ID  + ".P_DECORATORS_CHANGED";	 //$NON-NLS-1$

	private ServiceRegistration debugRegistration;
	private Hashtable imageDescriptors = new Hashtable(20);
	private static List propertyChangeListeners = new ArrayList(5);
	
	/**
	 * The singleton plug-in instance
	 */
	private static CVSUIPlugin plugin;
	
	/**
	 * The CVS console
	 */
	private CVSOutputConsole console;
	
	/**
	 * The repository manager
	 */
	private RepositoryManager repositoryManager;

	/**
	 * CVSUIPlugin constructor
	 * 
	 * @param descriptor  the plugin descriptor
	 */
	public CVSUIPlugin() {
		super();
		plugin = this;
	}
	
	/**
	 * Returns the standard display to be used. The method first checks, if
	 * the thread calling this method has an associated display. If so, this
	 * display is returned. Otherwise the method returns the default display.
	 */
	public static Display getStandardDisplay() {
		Display display= Display.getCurrent();
		if (display == null) {
			display= Display.getDefault();
		}
		return display;		
	}
	
	/**
	 * Creates an image and places it in the image registry.
	 */
	protected void createImageDescriptor(String id) {
		URL url = FileLocator.find(CVSUIPlugin.getPlugin().getBundle(), new Path(ICVSUIConstants.ICON_PATH + id), null);
		ImageDescriptor desc = ImageDescriptor.createFromURL(url);
		imageDescriptors.put(id, desc);
	}
	
	/**
	 * Returns the active workbench page. Note that the active page may not be
	 * the one that the user perceives as active in some situations so this
	 * method of obtaining the activate page should only be used if no other
	 * method is available.
	 * 
	 * @return the active workbench page
	 */
	public static IWorkbenchPage getActivePage() {
		return TeamUIPlugin.getActivePage();
	}
	
	/**
	 * Register for changes made to Team properties.
	 */
	public static void addPropertyChangeListener(IPropertyChangeListener listener) {
		propertyChangeListeners.add(listener);
	}
	
	/**
	 * Remove a Team property changes.
	 */
	public static void removePropertyChangeListener(IPropertyChangeListener listener) {
		propertyChangeListeners.remove(listener);
	}
	
	/**
	 * Broadcast a Team property change.
	 */
	public static void broadcastPropertyChange(PropertyChangeEvent event) {
		for (Iterator it = propertyChangeListeners.iterator(); it.hasNext();) {
			IPropertyChangeListener listener = (IPropertyChangeListener)it.next();			
			listener.propertyChange(event);
		}
	}
	
	/**
	 * Run an operation involving the given resource. If an exception is thrown
	 * and the code on the status is IResourceStatus.OUT_OF_SYNC_LOCAL then
	 * the user will be prompted to refresh and try again. If they agree, then the
	 * supplied operation will be run again.
	 */
	public static void runWithRefresh(Shell parent, IResource[] resources, 
										IRunnableWithProgress runnable, IProgressMonitor monitor) 
	throws InvocationTargetException, InterruptedException {
		boolean firstTime = true;
		while(true) {
			try {
				runnable.run(monitor);
				return;
			} catch (InvocationTargetException e) {
				if (! firstTime) throw e;
				IStatus status = null;
				if (e.getTargetException() instanceof CoreException) {
					status = ((CoreException)e.getTargetException()).getStatus();
				} else if (e.getTargetException() instanceof TeamException) {
					status = ((TeamException)e.getTargetException()).getStatus();
				} else {
					throw e;
				}
				if (status.getCode() == IResourceStatus.OUT_OF_SYNC_LOCAL) {
					if (promptToRefresh(parent, resources, status)) {
						try {
							for (int i = 0; i < resources.length; i++) {
								resources[i].refreshLocal(IResource.DEPTH_INFINITE, null);
							}
						} catch (CoreException coreEx) {
							// Throw the original exception to the caller
							log(coreEx);
							throw e;
						}
						firstTime = false;
						// Fall through and the operation will be tried again
					} else {
						// User chose not to continue. Treat it as a cancel.
						throw new InterruptedException();
					}
				} else {
					throw e;
				}
			}
		}
	}
	
	private static boolean promptToRefresh(final Shell shell, final IResource[] resources, final IStatus status) {
		final boolean[] result = new boolean[] { false};
		Runnable runnable = () -> {
			Shell shellToUse = shell;
			if (shell == null) {
				shellToUse = new Shell(Display.getCurrent());
			}
			String question;
			if (resources.length == 1) {
				question = NLS.bind(CVSUIMessages.CVSUIPlugin_refreshQuestion,
						new String[] { status.getMessage(), resources[0].getFullPath().toString() });
			} else {
				question = NLS.bind(CVSUIMessages.CVSUIPlugin_refreshMultipleQuestion,
						new String[] { status.getMessage() });
			}
			result[0] = MessageDialog.openQuestion(shellToUse, CVSUIMessages.CVSUIPlugin_refreshTitle, question);
		};
		Display.getDefault().syncExec(runnable);
		return result[0];
	}
	
	/**
	 * Creates a busy cursor and runs the specified runnable.
	 * May be called from a non-UI thread.
	 * 
	 * @param parent the parent Shell for the dialog
	 * @param cancelable if true, the dialog will support cancelation
	 * @param runnable the runnable
	 * 
	 * @exception InvocationTargetException when an exception is thrown from the runnable
	 * @exception InterruptedException when the progress monitor is canceled
	 */
	public static void runWithProgress(Shell parent, boolean cancelable,
										final IRunnableWithProgress runnable) throws InvocationTargetException, InterruptedException {
		Utils.runWithProgress(parent, cancelable, runnable);
	}
	
	/**
	 * Returns the image descriptor for the given image ID.
	 * Returns null if there is no such image.
	 */
	public ImageDescriptor getImageDescriptor(String id) {
		return (ImageDescriptor)imageDescriptors.get(id);
	}
	
	/**
	 * Returns the singleton plug-in instance.
	 * 
	 * @return the plugin instance
	 */
	public static CVSUIPlugin getPlugin() {
		return plugin;
	}
	
	/**
	 * Returns the repository manager
	 * 
	 * @return the repository manager
	 */
	public synchronized RepositoryManager getRepositoryManager() {
		if (repositoryManager == null) {
			repositoryManager = new RepositoryManager();
			repositoryManager.startup();
		}
		return repositoryManager;
	}
	
	/**
	 * Initializes the table of images used in this plugin.
	 */
	private void initializeImages() {
		// objects
		createImageDescriptor(ICVSUIConstants.IMG_REPOSITORY); 
		createImageDescriptor(ICVSUIConstants.IMG_REFRESH);
		createImageDescriptor(ICVSUIConstants.IMG_REFRESH_ENABLED);
		createImageDescriptor(ICVSUIConstants.IMG_REFRESH_DISABLED);
		createImageDescriptor(ICVSUIConstants.IMG_LINK_WITH_EDITOR);
		createImageDescriptor(ICVSUIConstants.IMG_LINK_WITH_EDITOR_ENABLED);
		createImageDescriptor(ICVSUIConstants.IMG_COLLAPSE_ALL);
		createImageDescriptor(ICVSUIConstants.IMG_COLLAPSE_ALL_ENABLED);
		createImageDescriptor(ICVSUIConstants.IMG_NEWLOCATION);
		createImageDescriptor(ICVSUIConstants.IMG_CVSLOGO);
		createImageDescriptor(ICVSUIConstants.IMG_TAG);
		createImageDescriptor(ICVSUIConstants.IMG_MODULE);
		createImageDescriptor(ICVSUIConstants.IMG_CLEAR);
		createImageDescriptor(ICVSUIConstants.IMG_CLEAR_ENABLED);
		createImageDescriptor(ICVSUIConstants.IMG_CLEAR_DISABLED);
		createImageDescriptor(ICVSUIConstants.IMG_BRANCHES_CATEGORY);
		createImageDescriptor(ICVSUIConstants.IMG_VERSIONS_CATEGORY);
		createImageDescriptor(ICVSUIConstants.IMG_DATES_CATEGORY);
		createImageDescriptor(ICVSUIConstants.IMG_PROJECT_VERSION);
		createImageDescriptor(ICVSUIConstants.IMG_WIZBAN_MERGE);
		createImageDescriptor(ICVSUIConstants.IMG_WIZBAN_SHARE);
		createImageDescriptor(ICVSUIConstants.IMG_WIZBAN_DIFF);
		createImageDescriptor(ICVSUIConstants.IMG_WIZBAN_KEYWORD);
		createImageDescriptor(ICVSUIConstants.IMG_WIZBAN_NEW_LOCATION);
		createImageDescriptor(ICVSUIConstants.IMG_WIZBAN_IMPORT);
		createImageDescriptor(ICVSUIConstants.IMG_MERGEABLE_CONFLICT);
		createImageDescriptor(ICVSUIConstants.IMG_QUESTIONABLE);
		createImageDescriptor(ICVSUIConstants.IMG_MERGED);
		createImageDescriptor(ICVSUIConstants.IMG_EDITED);
		createImageDescriptor(ICVSUIConstants.IMG_NO_REMOTEDIR);
		createImageDescriptor(ICVSUIConstants.IMG_CVS_CONSOLE);
		createImageDescriptor(ICVSUIConstants.IMG_DATE);
		createImageDescriptor(ICVSUIConstants.IMG_CHANGELOG);
		createImageDescriptor(ICVSUIConstants.IMG_FILTER_HISTORY);
		createImageDescriptor(ICVSUIConstants.IMG_LOCALMODE);
		createImageDescriptor(ICVSUIConstants.IMG_LOCALREMOTE_MODE);
		createImageDescriptor(ICVSUIConstants.IMG_REMOTEMODE);
		createImageDescriptor(ICVSUIConstants.IMG_LOCALMODE_DISABLED);
		createImageDescriptor(ICVSUIConstants.IMG_LOCALREMOTE_MODE_DISABLED);
		createImageDescriptor(ICVSUIConstants.IMG_REMOTEMODE_DISABLED);
		createImageDescriptor(ICVSUIConstants.IMG_LOCALREVISION_TABLE);
		createImageDescriptor(ICVSUIConstants.IMG_REMOTEREVISION_TABLE);
		createImageDescriptor(ICVSUIConstants.IMG_COMPARE_VIEW);
		
		// special
		createImageDescriptor("glyphs/glyph1.gif");  //$NON-NLS-1$
		createImageDescriptor("glyphs/glyph2.gif");  //$NON-NLS-1$
		createImageDescriptor("glyphs/glyph3.gif");  //$NON-NLS-1$
		createImageDescriptor("glyphs/glyph4.gif");  //$NON-NLS-1$
		createImageDescriptor("glyphs/glyph5.gif");  //$NON-NLS-1$
		createImageDescriptor("glyphs/glyph6.gif");  //$NON-NLS-1$
		createImageDescriptor("glyphs/glyph7.gif");  //$NON-NLS-1$
		createImageDescriptor("glyphs/glyph8.gif");  //$NON-NLS-1$
	}
	/**
	 * Convenience method for logging statuses to the plugin log
	 * 
	 * @param status  the status to log
	 */
	public static void log(IStatus status) {
		getPlugin().getLog().log(status);
	}
	
	public static void log(CoreException e) {
		log(e.getStatus().getSeverity(), CVSUIMessages.simpleInternal, e); 
	}
	
	/**
	 * Log the given exception along with the provided message and severity indicator
	 */
	public static void log(int severity, String message, Throwable e) {
		log(new Status(severity, ID, 0, message, e));
	}
	
	// flags to tailor error reporting
	/**
	 * Use this flag if you are calling openError from a none UI thread. The
	 * flag is checked in openDialog method.
	 */
	public static final int PERFORM_SYNC_EXEC = 1;
	/**
	 * Use this flag to log all TeamExceptions and its descendants.
	 */
	public static final int LOG_TEAM_EXCEPTIONS = 2;
	/**
	 * Use this flag to log all CoreExceptions excluding TeamExceptions and its
	 * descendants.
	 */
	public static final int LOG_NONTEAM_CORE_EXCEPTIONS = 4;
	/**
	 * Use this flag to log an exception other than CoreException (e.g.
	 * IOException).
	 */
	public static final int LOG_OTHER_EXCEPTIONS = 8;
	/**
	 * Use this flag to log all CoreExceptions.
	 */
	public static final int LOG_CORE_EXCEPTIONS = LOG_TEAM_EXCEPTIONS
			| LOG_NONTEAM_CORE_EXCEPTIONS;
	/**
	 * Use this flag to log all exceptions different than TeamException and its
	 * descendant.
	 */
	public static final int LOG_NONTEAM_EXCEPTIONS = LOG_NONTEAM_CORE_EXCEPTIONS
			| LOG_OTHER_EXCEPTIONS;
	
	/**
	 * Convenience method for showing an error dialog 
	 * @param shell a valid shell or null
	 * @param exception the exception to be report
	 * @param title the title to be displayed
	 * @return IStatus the status that was displayed to the user
	 */
	public static IStatus openError(Shell shell, String title, String message, Throwable exception) {
		return openError(shell, title, message, exception, LOG_OTHER_EXCEPTIONS);
	}
	
	/**
	 * Convenience method for showing an error dialog 
	 * @param shell a valid shell or null
	 * @param exception the exception to be report
	 * @param title the title to be displayed
	 * @param flags customized attributes for the error handling
	 * @return IStatus the status that was displayed to the user
	 */
	public static IStatus openError(Shell providedShell, String title, String message, Throwable exception, int flags) {
		// Unwrap InvocationTargetExceptions
		if (exception instanceof InvocationTargetException) {
			Throwable target = ((InvocationTargetException)exception).getTargetException();
			// re-throw any runtime exceptions or errors so they can be handled by the workbench
			if (target instanceof RuntimeException) {
				throw (RuntimeException)target;
			}
			if (target instanceof Error) {
				throw (Error)target;
			} 
			return openError(providedShell, title, message, target, flags);
		}
		
		// Determine the status to be displayed (and possibly logged)
		IStatus status = null;
		boolean log = false;
		if (exception instanceof TeamException) {
			status = ((TeamException)exception).getStatus();
			log = ((flags & LOG_TEAM_EXCEPTIONS) > 0);
		} else if (exception instanceof CoreException) {
			status = ((CoreException)exception).getStatus();
			log = ((flags & LOG_NONTEAM_CORE_EXCEPTIONS) > 0);
		} else if (exception instanceof InterruptedException) {
			return new CVSStatus(IStatus.OK, CVSUIMessages.ok); 
		} else if (exception != null) {
			status = new CVSStatus(IStatus.ERROR, CVSUIMessages.internal, exception); 
			log = ((flags & LOG_OTHER_EXCEPTIONS) > 0);
			if (title == null) title = CVSUIMessages.internal; 
		}
		
		// Check for a build error and report it differently
		if (status.getCode() == IResourceStatus.BUILD_FAILED) {
			message = CVSUIMessages.buildError; 
			log = true;
		}
		
		// Check for multi-status with only one child
		if (status.isMultiStatus() && status.getChildren().length == 1) {
			status = status.getChildren()[0];
		}
		if (status.isOK()) return status;
		
		// Log if the user requested it
		if (log) CVSUIPlugin.log(status.getSeverity(), status.getMessage(), exception);

		return openDialog(providedShell, title, message, status, flags);
	}

	/**
	 * Convenience method for showing an error dialog
	 * 
	 * @param shell a valid shell or null
	 * @param status the status to be reported
	 * @param title the title to be displayed
	 * @param flags customized attributes for the error handling
	 * @return IStatus the status that was displayed to the user
	 */
	public static IStatus openError(Shell providedShell, String title,
			String message, IStatus status, int flags) {
		boolean log = false;

		// Check for a build error and report it differently
		if (status.getCode() == IResourceStatus.BUILD_FAILED) {
			message = CVSUIMessages.buildError;
			log = true;
		}

		// Check for multi-status with only one child
		if (status.isMultiStatus() && status.getChildren().length == 1) {
			status = status.getChildren()[0];
		}
		if (status.isOK())
			return status;

		// Log if the user requested it
		if (log)
			CVSUIPlugin.log(status);

		return openDialog(providedShell, title, message, status, flags);
	}

	private static IStatus openDialog(Shell providedShell, final String title,
			final String message, final IStatus status, int flags) {
		// Create a runnable that will display the error status
		final IOpenableInShell openable = shell -> {
			if (status.getSeverity() == IStatus.INFO && !status.isMultiStatus()) {
				MessageDialog.openInformation(shell, CVSUIMessages.information, status.getMessage());
			} else {
				ErrorDialog.openError(shell, title, message, status);
			}
		};
		openDialog(providedShell, openable, flags);

		// return the status we display
		return status;
	}

	/**
	 * Interface that allows a shell to be passed to an open method. The
	 * provided shell can be used without sync-execing, etc.
	 */
	public interface IOpenableInShell {
		public void open(Shell shell);
	}
	
	/**
	 * Open the dialog code provided in the IOpenableInShell, ensuring that 
	 * the provided shell is valid. This method will provide a shell to the
	 * IOpenableInShell if one is not provided to the method.
	 * 
	 * @param providedShell
	 * @param openable
	 * @param flags
	 */
	public static void openDialog(Shell providedShell, final IOpenableInShell openable, int flags) {
		// If no shell was provided, try to get one from the active window
		if (providedShell == null) {
			IWorkbenchWindow window = CVSUIPlugin.getPlugin().getWorkbench().getActiveWorkbenchWindow();
			if (window != null) {
				providedShell = window.getShell();
				// sync-exec when we do this just in case
				flags = flags | PERFORM_SYNC_EXEC;
			}
		}
		
		// Create a runnable that will display the error status
		final Shell shell = providedShell;
		Runnable outerRunnable = () -> {
			Shell displayShell;
			if (shell == null) {
				Display display = Display.getCurrent();
				displayShell = new Shell(display);
			} else {
				displayShell = shell;
			}
			openable.open(displayShell);
			if (shell == null) {
				displayShell.dispose();
			}
		};
		
		// Execute the above runnable as determined by the parameters
		if (shell == null || (flags & PERFORM_SYNC_EXEC) > 0) {
			Display display;
			if (shell == null) {
				display = Display.getCurrent();
				if (display == null) {
					display = Display.getDefault();
				}
			} else {
				display = shell.getDisplay();
			}
			display.syncExec(outerRunnable);
		} else {
			outerRunnable.run();
		}
	}
	
	
	/**
	 * Initializes the preferences for this plugin if necessary.
	 */
	@Override
	protected void initializeDefaultPluginPreferences() {
		IPreferenceStore store = getPreferenceStore();
		// Get the plugin preferences for CVS Core
		Preferences corePrefs = CVSProviderPlugin.getPlugin().getPluginPreferences();
		
		store.setDefault(ICVSUIConstants.PREF_REPOSITORIES_ARE_BINARY, false);
		store.setDefault(ICVSUIConstants.PREF_SHOW_COMMENTS, true);
		store.setDefault(ICVSUIConstants.PREF_WRAP_COMMENTS, true);
		store.setDefault(ICVSUIConstants.PREF_SHOW_TAGS, true);
		store.setDefault(ICVSUIConstants.PREF_SHOW_SEARCH, false);
		store.setDefault(ICVSUIConstants.PREF_REVISION_MODE, 0);
		store.setDefault(ICVSUIConstants.PREF_GROUPBYDATE_MODE, true);
		store.setDefault(ICVSUIConstants.PREF_HISTORY_VIEW_EDITOR_LINKING, false);
		store.setDefault(ICVSUIConstants.PREF_PRUNE_EMPTY_DIRECTORIES, CVSProviderPlugin.DEFAULT_PRUNE);
		store.setDefault(ICVSUIConstants.PREF_TIMEOUT, CVSProviderPlugin.DEFAULT_TIMEOUT);
		store.setDefault(ICVSUIConstants.PREF_CONSIDER_CONTENTS, true);
		store.setDefault(ICVSUIConstants.PREF_SYNCVIEW_REGEX_FILTER_PATTERN, ""); //default pattern is empty string //$NON-NLS-1$		
		store.setDefault(ICVSUIConstants.PREF_COMPRESSION_LEVEL, CVSProviderPlugin.DEFAULT_COMPRESSION_LEVEL);
		store.setDefault(ICVSUIConstants.PREF_TEXT_KSUBST, CVSProviderPlugin.DEFAULT_TEXT_KSUBST_OPTION.toMode());
		store.setDefault(ICVSUIConstants.PREF_USE_PLATFORM_LINEEND, true);
		store.setDefault(ICVSUIConstants.PREF_REPLACE_UNMANAGED, true);
		store.setDefault(ICVSUIConstants.PREF_CVS_RSH, CVSProviderPlugin.DEFAULT_CVS_RSH);
		store.setDefault(ICVSUIConstants.PREF_CVS_RSH_PARAMETERS, CVSProviderPlugin.DEFAULT_CVS_RSH_PARAMETERS);
		store.setDefault(ICVSUIConstants.PREF_CVS_SERVER, CVSProviderPlugin.DEFAULT_CVS_SERVER);
		store.setDefault(ICVSUIConstants.PREF_EXT_CONNECTION_METHOD_PROXY, "ext"); //$NON-NLS-1$
		store.setDefault(ICVSUIConstants.PREF_PROMPT_ON_CHANGE_GRANULARITY, true);
		store.setDefault(ICVSUIConstants.PREF_DETERMINE_SERVER_VERSION, true);
		store.setDefault(ICVSUIConstants.PREF_CONFIRM_MOVE_TAG, CVSProviderPlugin.DEFAULT_CONFIRM_MOVE_TAG);
		store.setDefault(ICVSUIConstants.PREF_DEBUG_PROTOCOL, false);
		store.setDefault(ICVSUIConstants.PREF_WARN_REMEMBERING_MERGES, true);
		store.setDefault(ICVSUIConstants.PREF_SHOW_COMPARE_REVISION_IN_DIALOG, false);
		store.setDefault(ICVSUIConstants.PREF_COMMIT_SET_DEFAULT_ENABLEMENT, false);
		store.setDefault(ICVSUIConstants.PREF_AUTO_REFRESH_TAGS_IN_TAG_SELECTION_DIALOG, false);
		store.setDefault(ICVSUIConstants.PREF_AUTO_SHARE_ON_IMPORT, true);
		store.setDefault(ICVSUIConstants.PREF_ENABLE_WATCH_ON_EDIT, false);
		store.setDefault(ICVSUIConstants.PREF_USE_PROJECT_NAME_ON_CHECKOUT, false);
		store.setDefault(ICVSUIConstants.PREF_COMMIT_FILES_DISPLAY_THRESHOLD, 1000);
		store.setDefault(ICVSUIConstants.PREF_COMMIT_COMMENTS_MAX_HISTORY, RepositoryManager.DEFAULT_MAX_COMMENTS);
		
		PreferenceConverter.setDefault(store, ICVSUIConstants.PREF_CONSOLE_COMMAND_COLOR, new RGB(0, 0, 0));
		PreferenceConverter.setDefault(store, ICVSUIConstants.PREF_CONSOLE_MESSAGE_COLOR, new RGB(0, 0, 255));
		PreferenceConverter.setDefault(store, ICVSUIConstants.PREF_CONSOLE_ERROR_COLOR, new RGB(255, 0, 0));
		store.setDefault(ICVSUIConstants.PREF_CONSOLE_SHOW_ON_MESSAGE, false);
		store.setDefault(ICVSUIConstants.PREF_CONSOLE_LIMIT_OUTPUT, true);	
		store.setDefault(ICVSUIConstants.PREF_CONSOLE_HIGH_WATER_MARK, 500000);	
		store.setDefault(ICVSUIConstants.PREF_CONSOLE_WRAP, false);	
		store.setDefault(ICVSUIConstants.PREF_CONSOLE_WIDTH, 80);
			
		store.setDefault(ICVSUIConstants.PREF_FILETEXT_DECORATION, CVSDecoratorConfiguration.DEFAULT_FILETEXTFORMAT);
		store.setDefault(ICVSUIConstants.PREF_FOLDERTEXT_DECORATION, CVSDecoratorConfiguration.DEFAULT_FOLDERTEXTFORMAT);
		store.setDefault(ICVSUIConstants.PREF_PROJECTTEXT_DECORATION, CVSDecoratorConfiguration.DEFAULT_PROJECTTEXTFORMAT);
		
		store.setDefault(ICVSUIConstants.PREF_FIRST_STARTUP, true);
		store.setDefault(ICVSUIConstants.PREF_ADDED_FLAG, CVSDecoratorConfiguration.DEFAULT_ADDED_FLAG);
		store.setDefault(ICVSUIConstants.PREF_DIRTY_FLAG, CVSDecoratorConfiguration.DEFAULT_DIRTY_FLAG);	
		store.setDefault(ICVSUIConstants.PREF_SHOW_ADDED_DECORATION, true);
		store.setDefault(ICVSUIConstants.PREF_SHOW_HASREMOTE_DECORATION, true);
		store.setDefault(ICVSUIConstants.PREF_SHOW_DIRTY_DECORATION, false);
		store.setDefault(ICVSUIConstants.PREF_SHOW_NEWRESOURCE_DECORATION, true);
		store.setDefault(ICVSUIConstants.PREF_CALCULATE_DIRTY, true);	
		store.setDefault(ICVSUIConstants.PREF_USE_FONT_DECORATORS, false);
		store.setDefault(ICVSUIConstants.PREF_PROMPT_ON_MIXED_TAGS, true);
		store.setDefault(ICVSUIConstants.PREF_PROMPT_ON_SAVING_IN_SYNC, true);
		store.setDefault(ICVSUIConstants.PREF_SAVE_DIRTY_EDITORS, ICVSUIConstants.OPTION_PROMPT);
		
		store.setDefault(ICVSUIConstants.PREF_ANNOTATE_PROMPTFORBINARY, MessageDialogWithToggle.PROMPT);
		store.setDefault(ICVSUIConstants.PREF_ALLOW_EMPTY_COMMIT_COMMENTS, MessageDialogWithToggle.PROMPT);
		store.setDefault(ICVSUIConstants.PREF_INCLUDE_CHANGE_SETS_IN_COMMIT, MessageDialogWithToggle.NEVER);
		store.setDefault(ICVSUIConstants.PREF_ALLOW_COMMIT_WITH_WARNINGS, MessageDialogWithToggle.ALWAYS);
		store.setDefault(ICVSUIConstants.PREF_ALLOW_COMMIT_WITH_ERRORS, MessageDialogWithToggle.PROMPT);
		
		store.setDefault(ICVSUIConstants.PREF_UPDATE_HANDLING, ICVSUIConstants.PREF_UPDATE_HANDLING_TRADITIONAL);
		store.setDefault(ICVSUIConstants.PREF_UPDATE_PREVIEW, ICVSUIConstants.PREF_UPDATE_PREVIEW_IN_SYNCVIEW);
		
		store.setDefault(ICVSUIConstants.PREF_ENABLE_MODEL_SYNC, true);
		store.setDefault(ICVSUIConstants.PREF_OPEN_COMPARE_EDITOR_FOR_SINGLE_FILE, true);
		
		// Set the watch/edit preferences defaults and values
		store.setDefault(ICVSUIConstants.PREF_CHECKOUT_READ_ONLY, corePrefs.getDefaultBoolean(CVSProviderPlugin.READ_ONLY));
		store.setDefault(ICVSUIConstants.PREF_EDIT_ACTION, ICVSUIConstants.PREF_EDIT_IN_BACKGROUND);
		store.setDefault(ICVSUIConstants.PREF_EDIT_PROMPT, ICVSUIConstants.PREF_EDIT_PROMPT_IF_EDITORS);
		store.setDefault(ICVSUIConstants.PREF_UPDATE_PROMPT, ICVSUIConstants.PREF_UPDATE_PROMPT_NEVER);
		// Ensure that the preference values in UI match Core
		store.setValue(ICVSUIConstants.PREF_CHECKOUT_READ_ONLY, corePrefs.getBoolean(CVSProviderPlugin.READ_ONLY));
		
		// Forward the values to the CVS plugin
		CVSProviderPlugin.getPlugin().setPruneEmptyDirectories(store.getBoolean(ICVSUIConstants.PREF_PRUNE_EMPTY_DIRECTORIES));
		CVSProviderPlugin.getPlugin().setTimeout(store.getInt(ICVSUIConstants.PREF_TIMEOUT));
		CVSProviderPlugin.getPlugin().setCvsRshCommand(store.getString(ICVSUIConstants.PREF_CVS_RSH));
		CVSProviderPlugin.getPlugin().setCvsRshParameters(store.getString(ICVSUIConstants.PREF_CVS_RSH_PARAMETERS));
		CVSProviderPlugin.getPlugin().setCvsServer(store.getString(ICVSUIConstants.PREF_CVS_SERVER));
		CVSRepositoryLocation.setExtConnectionMethodProxy(store.getString(ICVSUIConstants.PREF_EXT_CONNECTION_METHOD_PROXY));
		CVSProviderPlugin.getPlugin().setQuietness(CVSPreferencesPage.getQuietnessOptionFor(store.getInt(ICVSUIConstants.PREF_QUIETNESS)));
		CVSProviderPlugin.getPlugin().setCompressionLevel(store.getInt(ICVSUIConstants.PREF_COMPRESSION_LEVEL));
		CVSProviderPlugin.getPlugin().setReplaceUnmanaged(store.getBoolean(ICVSUIConstants.PREF_REPLACE_UNMANAGED));
		CVSProviderPlugin.getPlugin().setDefaultTextKSubstOption(KSubstOption.fromMode(store.getString(ICVSUIConstants.PREF_TEXT_KSUBST)));
		CVSProviderPlugin.getPlugin().setUsePlatformLineend(store.getBoolean(ICVSUIConstants.PREF_USE_PLATFORM_LINEEND));
		CVSProviderPlugin.getPlugin().setRepositoriesAreBinary(store.getBoolean(ICVSUIConstants.PREF_REPOSITORIES_ARE_BINARY));
		CVSProviderPlugin.getPlugin().setDetermineVersionEnabled(store.getBoolean(ICVSUIConstants.PREF_DETERMINE_SERVER_VERSION));
		CVSProviderPlugin.getPlugin().setDebugProtocol(CVSProviderPlugin.getPlugin().isDebugProtocol() || store.getBoolean(ICVSUIConstants.PREF_DEBUG_PROTOCOL));
		CVSProviderPlugin.getPlugin().setAutoshareOnImport(store.getBoolean(ICVSUIConstants.PREF_AUTO_SHARE_ON_IMPORT));
		
		// code to transfer CVS preference to Team preference
		if (store.getBoolean(ICVSUIConstants.PREF_SHOW_AUTHOR_IN_EDITOR)) {
			store.setValue(ICVSUIConstants.PREF_SHOW_AUTHOR_IN_EDITOR, false);
			IPreferenceStore teamStore = TeamUIPlugin.getPlugin().getPreferenceStore();
			if (teamStore.isDefault(IPreferenceIds.SHOW_AUTHOR_IN_COMPARE_EDITOR))
				teamStore.setValue(IPreferenceIds.SHOW_AUTHOR_IN_COMPARE_EDITOR, true);
		}
	}
	
	@Override
	public void start(BundleContext context) throws Exception {
		super.start(context);

		// register debug options listener
		Hashtable properties = new Hashtable(2);
		properties.put(DebugOptions.LISTENER_SYMBOLICNAME, ID);
		debugRegistration = context.registerService(DebugOptionsListener.class, Policy.DEBUG_OPTIONS_LISTENER, properties);

		initializeImages();
		
		CVSAdapterFactory factory = new CVSAdapterFactory();
		Platform.getAdapterManager().registerAdapters(factory, ICVSRemoteFile.class);
		Platform.getAdapterManager().registerAdapters(factory, ICVSRemoteFolder.class);
		Platform.getAdapterManager().registerAdapters(factory, ICVSRepositoryLocation.class);
		Platform.getAdapterManager().registerAdapters(factory, RepositoryRoot.class);
		
		try {
			console = new CVSOutputConsole();
		} catch (RuntimeException e) {
			// Don't let the console bring down the CVS UI
			log(IStatus.ERROR, "Errors occurred starting the CVS console", e); //$NON-NLS-1$
		}
		
		IPreferenceStore store = getPreferenceStore();
		if (store.getBoolean(ICVSUIConstants.PREF_FIRST_STARTUP)) {
			// If we enable the decorator in the XML, the CVS plugin will be loaded
			// on startup even if the user never uses CVS. Therefore, we enable the 
			// decorator on the first start of the CVS plugin since this indicates that 
			// the user has done something with CVS. Subsequent startups will load
			// the CVS plugin unless the user disables the decorator. In this case,
			// we will not re-enable since we only enable automatically on the first startup.
			PlatformUI.getWorkbench().getDecoratorManager().setEnabled(CVSLightweightDecorator.ID, true);
			store.setValue(ICVSUIConstants.PREF_FIRST_STARTUP, false);
		}

	}
	
	@Override
	public void stop(BundleContext context) throws Exception {
		try {
			// unregister debug options listener
			debugRegistration.unregister();
			debugRegistration = null;

			try {
				if (repositoryManager != null)
					repositoryManager.shutdown();
			} catch (TeamException e) {
				throw new CoreException(e.getStatus());
			}
			
			if (console != null)
				console.shutdown();
		} finally {
			super.stop(context);
		}
	}
	
	/**
	 * @return the CVS console
	 */
	public CVSOutputConsole getConsole() {
		return console;
	}
	
	public IEditorPart openEditor(ICVSRemoteFile file, IProgressMonitor monitor) throws InvocationTargetException {
		IWorkbench workbench = getWorkbench();
		IWorkbenchPage page = workbench.getActiveWorkbenchWindow().getActivePage();
		try {
			return Utils.openEditor(page, file.getAdapter(IFileRevision.class), monitor);
		} catch (CoreException e) {
			throw new InvocationTargetException(e);
		}
	}

	/**
	 * Helper method which access the preference store to determine if the 
	 * project name from the project description file (.project) should be used
	 * as the project name on checkout.
	 */
	public boolean isUseProjectNameOnCheckout() {
		return getPreferenceStore().getBoolean(ICVSUIConstants.PREF_USE_PROJECT_NAME_ON_CHECKOUT);
	}

	public ActiveChangeSetManager getChangeSetManager() {
		return CVSProviderPlugin.getPlugin().getChangeSetManager();
	}

	public org.osgi.service.prefs.Preferences getInstancePreferences() {
		return InstanceScope.INSTANCE.getNode(getBundle().getSymbolicName());
	}
}
