/*******************************************************************************
 * 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
 *******************************************************************************/
package org.eclipse.team.internal.ccvs.core;
 
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;

import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.jsch.core.IJSchService;
import org.eclipse.osgi.service.debug.DebugOptions;
import org.eclipse.osgi.service.debug.DebugOptionsListener;
import org.eclipse.osgi.util.NLS;
import org.eclipse.team.core.Team;
import org.eclipse.team.core.TeamException;
import org.eclipse.team.internal.ccvs.core.client.*;
import org.eclipse.team.internal.ccvs.core.client.Command.KSubstOption;
import org.eclipse.team.internal.ccvs.core.client.Command.QuietOption;
import org.eclipse.team.internal.ccvs.core.client.listeners.IConsoleListener;
import org.eclipse.team.internal.ccvs.core.mapping.CVSActiveChangeSetCollector;
import org.eclipse.team.internal.ccvs.core.resources.FileModificationManager;
import org.eclipse.team.internal.ccvs.core.util.*;
import org.eclipse.team.internal.core.subscribers.ActiveChangeSetManager;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.osgi.util.tracker.ServiceTracker;

public class CVSProviderPlugin extends Plugin {
	
	// preference names
	public static final String READ_ONLY = "cvs.read.only"; //$NON-NLS-1$
	public static final String ENABLE_WATCH_ON_EDIT = "cvs.watch.on.edit"; //$NON-NLS-1$

	// external command to run for ext connection method
	public static final String DEFAULT_CVS_RSH = "ssh"; //$NON-NLS-1$
	// external command parameters
	public static final String DEFAULT_CVS_RSH_PARAMETERS = "-l {user} {host}"; //$NON-NLS-1$
	// remote command to run for ext connection method
	public static final String DEFAULT_CVS_SERVER = "cvs"; //$NON-NLS-1$
	// determines if empty directories received from the server should be pruned.
	public static final boolean DEFAULT_PRUNE = true;
	// determines if the user is prompted for confirmation before moving tags during a tag operation.
	public static final boolean DEFAULT_CONFIRM_MOVE_TAG = true;
	// determines if new directories should be discovered during update.
	public static final boolean DEFAULT_FETCH = true;
	// communication timeout with the server
	public static final int DEFAULT_TIMEOUT = 60;
	// file transfer compression level (0 - 9)
	public static final int DEFAULT_COMPRESSION_LEVEL = 0;
	// default text keyword substitution mode
	public static final KSubstOption DEFAULT_TEXT_KSUBST_OPTION = Command.KSUBST_TEXT_EXPAND;

	// cvs plugin extension points and ids
	public static final String ID = "org.eclipse.team.cvs.core"; //$NON-NLS-1$
	
	public static final QualifiedName CVS_WORKSPACE_SUBSCRIBER_ID = new QualifiedName("org.eclipse.team.cvs.ui.cvsworkspace-participant", "syncparticipant"); //$NON-NLS-1$ //$NON-NLS-2$
	public static final String PT_AUTHENTICATOR = "authenticator"; //$NON-NLS-1$
	public static final String PT_CONNECTIONMETHODS = "connectionmethods"; //$NON-NLS-1$
	public static final String PT_FILE_MODIFICATION_VALIDATOR = "filemodificationvalidator"; //$NON-NLS-1$
	
	private QuietOption quietness;
	private int compressionLevel = DEFAULT_COMPRESSION_LEVEL;
	private KSubstOption defaultTextKSubstOption = DEFAULT_TEXT_KSUBST_OPTION;
	private boolean usePlatformLineend = true;
	private int communicationsTimeout = DEFAULT_TIMEOUT;
	private boolean pruneEmptyDirectories = DEFAULT_PRUNE;
	private boolean fetchAbsentDirectories = DEFAULT_FETCH;
	private boolean replaceUnmanaged = true;
	private boolean repositoriesAreBinary = false;
	private String cvsRshCommand = DEFAULT_CVS_RSH;
	private String cvsRshParameters = DEFAULT_CVS_RSH_PARAMETERS;
	private String cvsServer = DEFAULT_CVS_SERVER;
	private boolean determineVersionEnabled = true;
	
	private static volatile CVSProviderPlugin instance;
	
	// CVS specific resource delta listeners
	private BuildCleanupListener addDeleteMoveListener;
	private FileModificationManager fileModificationManager;
	private SyncFileChangeListener metaFileSyncListener;

	private static final String REPOSITORIES_STATE_FILE = ".cvsProviderState"; //$NON-NLS-1$
	// version numbers for the state file (a positive number indicates version 1)
	private static final int REPOSITORIES_STATE_FILE_VERSION_2 = -1;
	private static List decoratorEnablementListeners = new ArrayList();
	
	private CVSWorkspaceSubscriber cvsWorkspaceSubscriber;
	
	/**
	 * The identifier for the CVS nature
	 * (value <code>"org.eclipse.team.cvs.core.nature"</code>).
	 * The presence of this nature on a project indicates that it is 
	 * CVS-capable.
	 *
	 * @see org.eclipse.core.resources.IProject#hasNature
	 */
	private static final String NATURE_ID = ID + ".cvsnature"; //$NON-NLS-1$

	// File used to idicate if the workbench was shut down properly or not
	private static final String CRASH_INDICATION_FILE  = ".running"; //$NON-NLS-1$
	private boolean crash;

	private boolean autoShareOnImport;
	private boolean useProxy;

	public static final String PROXY_TYPE_HTTP = "HTTP"; //$NON-NLS-1$
	public static final String PROXY_TYPE_SOCKS5 = "SOCKS5"; //$NON-NLS-1$
	public static final String HTTP_DEFAULT_PORT = "80"; //$NON-NLS-1$
	public static final String SOCKS5_DEFAULT_PORT = "1080"; //$NON-NLS-1$
	
	private String proxyType;
	private String proxyHost;
	private String proxyPort;
	private boolean useProxyAuth;
	
	private CVSActiveChangeSetCollector changeSetManager;
	private ServiceRegistration debugRegistration;
	private ServiceTracker tracker;

	private static final String INFO_PROXY_USER = "org.eclipse.team.cvs.core.proxy.user"; //$NON-NLS-1$ 
	private static final String INFO_PROXY_PASS = "org.eclipse.team.cvs.core.proxy.pass"; //$NON-NLS-1$ 

	private static final URL FAKE_URL;
	static {
		URL temp = null;
		try {
			temp = new URL("http://org.eclipse.team.cvs.proxy.auth");//$NON-NLS-1$ 
		} catch (MalformedURLException e) {
			// Should never fail
		}
		FAKE_URL = temp;
	}
	
	
	public synchronized CVSWorkspaceSubscriber getCVSWorkspaceSubscriber() {
		if (cvsWorkspaceSubscriber == null) {
			cvsWorkspaceSubscriber = new CVSWorkspaceSubscriber(
					CVS_WORKSPACE_SUBSCRIBER_ID, 
					CVSMessages.CVSProviderPlugin_20); 
		}
		return cvsWorkspaceSubscriber;
	}

	/**
	 * Constructor for CVSProviderPlugin.
	 * @param descriptor
	 */
	public CVSProviderPlugin() {
		super();
		instance = this;
	}
	
	/**
	 * Convenience method for logging CoreExceptions to the plugin log
	 */
	public static void log(CoreException e) {
		log(e.getStatus().getSeverity(), e.getMessage(), 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));
	}
	
	/**
	 * Log the given status. Do not use this method for the IStatus from a CoreException.
	 * Use<code>log(CoreException)</code> instead so the stack trace is not lost.
	 */
	public static void log(IStatus status) {
		getPlugin().getLog().log(status);
	}

	/**
	 * Returns the singleton plug-in instance.
	 * 
	 * @return the plugin instance
	 */
	public static CVSProviderPlugin getPlugin() {
		return instance;
	}
	
	/**
	 * Answers the repository provider type id for the cvs plugin
	 */
	public static String getTypeId() {
		return NATURE_ID;
	}
	
	/**
	 * Sets the file transfer compression level. (if supported)
	 * Valid levels are: 0 (disabled), 1 (worst/fastest) - 9 (best/slowest)
	 */
	public void setCompressionLevel(int level) {
		compressionLevel = level;
	}

	/**
	 * Gets the file transfer compression level.
	 */
	public int getCompressionLevel() {
		return compressionLevel;
	}
	
	/**
	 * Sets the default keyword substitution mode for text files.
	 */
	public void setDefaultTextKSubstOption(KSubstOption ksubst) {
		defaultTextKSubstOption = ksubst;
	}


	/**
	 * Gets the default keyword substitution mode for text files.
	 */
	public KSubstOption getDefaultTextKSubstOption() {
		return defaultTextKSubstOption;
	}

	/**
	 * Should the CVS adapter prune empty directories
	 */
	public boolean getPruneEmptyDirectories() {
		return pruneEmptyDirectories;
	}

	/**
	 * Set whether the CVS adapter should prune empty directories
	 */
	public void setPruneEmptyDirectories(boolean prune) {
		pruneEmptyDirectories = prune;
	}

	/**
	 * Get the communications timeout value in seconds
	 */
	public int getTimeout() {
		return communicationsTimeout;
	}
	
	/**
	 * Set the timeout value for communications to a value in seconds.
	 * The value must be greater than or equal 0. If is it 0, there is no timeout.
	 */
	public void setTimeout(int timeout) {
		this.communicationsTimeout = Math.max(0, timeout);
	}
	
	/**
	 * Set the quietness option to use with cvs commands.
	 * Can be "", "-q" or "-Q"
	 */
	public void setQuietness(QuietOption option) {
			this.quietness = option;
	}

	/**
	 * Get the quietness option for commands
	 */
	public QuietOption getQuietness() {
		return quietness;
	}
	
	/**
	 * Set the console listener for commands.
	 * @param consoleListener the listener
	 */
	public void setConsoleListener(IConsoleListener consoleListener) {
		ConsoleListeners.getInstance().addListener(consoleListener);
	}
	
	@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);

		// load the state which includes the known repositories
		loadOldState();
		crash = createCrashFile();
		
		// Initialize CVS change listeners. Note that the report type is important.
		IWorkspace workspace = ResourcesPlugin.getWorkspace();
		addDeleteMoveListener = new BuildCleanupListener();
		fileModificationManager = new FileModificationManager();
		metaFileSyncListener = new SyncFileChangeListener();
		workspace.addResourceChangeListener(addDeleteMoveListener, IResourceChangeEvent.POST_BUILD);
		workspace.addResourceChangeListener(metaFileSyncListener, IResourceChangeEvent.POST_CHANGE);
		workspace.addResourceChangeListener(fileModificationManager, IResourceChangeEvent.POST_CHANGE);
		
		getCVSWorkspaceSubscriber();
		
		// Must load the change set manager on startup since it listens to deltas
		getChangeSetManager();
		
		tracker = new ServiceTracker(getBundle().getBundleContext(), IJSchService.class.getName(), null);
		tracker.open();
	}
	
	@Override
	public void stop(BundleContext context) throws Exception {
		try {
			// unregister debug options listener
			debugRegistration.unregister();
			debugRegistration = null;

			savePluginPreferences();
			
			// remove listeners
			IWorkspace workspace = ResourcesPlugin.getWorkspace();
			workspace.removeResourceChangeListener(metaFileSyncListener);
			workspace.removeResourceChangeListener(fileModificationManager);
			workspace.removeResourceChangeListener(addDeleteMoveListener);
			
			// remove all of this plugin's save participants. This is easier than having
			// each class that added itself as a participant to have to listen to shutdown.
			workspace.removeSaveParticipant(this);
			
			getChangeSetManager().dispose();
			
			tracker.close();
			
			deleteCrashFile();
		} finally {
			super.stop(context);
		}
	}
		
	@Override
	protected void initializeDefaultPluginPreferences(){
		Preferences store = getPluginPreferences();
		store.setDefault(READ_ONLY, false);
		store.setDefault(ENABLE_WATCH_ON_EDIT, false);
	}
	
	/**
	 * Gets the cvsRshCommand.
	 * @return Returns a String
	 */
	public String getCvsRshCommand() {
		return cvsRshCommand;
	}

	/**
	 * Sets the cvsRshCommand.
	 * @param cvsRshCommand The cvsRshCommand to set
	 */
	public void setCvsRshCommand(String cvsRshCommand) {
		this.cvsRshCommand = cvsRshCommand;
	}

	/**
	 * Returns the cvsRshParameters.
	 * @return String
	 */
	public String getCvsRshParameters() {
		return cvsRshParameters;
	}

	/**
	 * Sets the cvsRshParameters.
	 * @param cvsRshParameters The cvsRshParameters to set
	 */
	public void setCvsRshParameters(String cvsRshParameters) {
		this.cvsRshParameters = cvsRshParameters;
	}
	
	/**
	 * Gets the cvsServer.
	 * @return Returns a String
	 */
	public String getCvsServer() {
		return cvsServer;
	}

	/**
	 * Sets the cvsServer.
	 * @param cvsServer The cvsServer to set
	 */
	public void setCvsServer(String cvsServer) {
		this.cvsServer = cvsServer;
	}

	/**
	 * Gets the etchAbsentDirectories.
	 * @return Returns a boolean
	 */
	public boolean getFetchAbsentDirectories() {
		return fetchAbsentDirectories;
	}

	public boolean getRepositoriesAreBinary() {
		return repositoriesAreBinary;
	}
	
	/**
	 * Sets the fetchAbsentDirectories.
	 * @param etchAbsentDirectories The etchAbsentDirectories to set
	 */
	public void setFetchAbsentDirectories(boolean fetchAbsentDirectories) {
		this.fetchAbsentDirectories = fetchAbsentDirectories;
	}
	
	public void setRepositoriesAreBinary(boolean binary) {
		repositoriesAreBinary = binary;
	}
	
	public static void broadcastDecoratorEnablementChanged(final boolean enabled) {
		ICVSDecoratorEnablementListener[] listeners;
		synchronized(decoratorEnablementListeners) {
			listeners = (ICVSDecoratorEnablementListener[]) decoratorEnablementListeners.toArray(new ICVSDecoratorEnablementListener[decoratorEnablementListeners.size()]);
		}
		for (int i = 0; i < listeners.length; i++) {
			final ICVSDecoratorEnablementListener listener = listeners[i];
			ISafeRunnable code = new ISafeRunnable() {
				public void run() throws Exception {
					listener.decoratorEnablementChanged(enabled);
				}
				public void handleException(Throwable e) {
					// don't log the exception....it is already being logged in Platform#run
				}
			};
			Platform.run(code);
		}
	}
	
	/**
	 * Gets the replaceUnmanaged.
	 * @return Returns a boolean
	 */
	public boolean isReplaceUnmanaged() {
		return replaceUnmanaged;
	}

	/**
	 * Sets the replaceUnmanaged.
	 * @param replaceUnmanaged The replaceUnmanaged to set
	 */
	public void setReplaceUnmanaged(boolean replaceUnmanaged) {
		this.replaceUnmanaged = replaceUnmanaged;
	}

		
	/**
	 * Register to receive notification of repository creation and disposal
	 */
	public void addRepositoryListener(ICVSListener listener) {
		KnownRepositories.getInstance().addRepositoryListener(listener);
	}
	
	/**
	 * Register to receive notification of enablement of sync info decoration requirements. This
	 * can be useful for providing lazy initialization of caches that are only required for decorating
	 * resource with CVS information.
	 */
	public void addDecoratorEnablementListener(ICVSDecoratorEnablementListener listener) {
		synchronized(decoratorEnablementListeners) {
			decoratorEnablementListeners.add(listener);
		}
	}
	
	/**
	 * De-register a listener
	 */
	public void removeRepositoryListener(ICVSListener listener) {
		KnownRepositories.getInstance().removeRepositoryListener(listener);
	}
	
	/**
	 * De-register the decorator enablement listener. 
	 */
	public void removeDecoratorEnablementListener(ICVSDecoratorEnablementListener listener) {
		synchronized(decoratorEnablementListeners) {
			decoratorEnablementListeners.remove(listener);
		}
	}
	
	/** 
	 * Return a list of the know repository locations. This is left
	 * here to isolate the RelEng tools plugin from changes in CVS core.
	 */
	public ICVSRepositoryLocation[] getKnownRepositories() {
		return KnownRepositories.getInstance().getRepositories();
	}

	private void loadOldState() {
		try {
			IPath pluginStateLocation = CVSProviderPlugin.getPlugin().getStateLocation().append(REPOSITORIES_STATE_FILE);
			File file = pluginStateLocation.toFile();
			if (file.exists()) {
				try {
					DataInputStream dis = new DataInputStream(new FileInputStream(file));
					readOldState(dis);
					dis.close();
					// The file is no longer needed as the state is
					// persisted in the user settings
					file.delete();
				} catch (IOException e) {
					throw new TeamException(new Status(IStatus.ERROR, CVSProviderPlugin.ID, TeamException.UNABLE, CVSMessages.CVSProvider_ioException, e));  
				}
			}
		} catch (TeamException e) {
			Util.logError(CVSMessages.CVSProvider_errorLoading, e);
		}
	}
	
	private void readOldState(DataInputStream dis) throws IOException, CVSException {
		KnownRepositories instance = KnownRepositories.getInstance();
		int count = dis.readInt();
		if (count >= 0) {
			// this is the version 1 format of the state file
			for (int i = 0; i < count; i++) {
				ICVSRepositoryLocation location = instance.getRepository(dis.readUTF());
				instance.addRepository(location, false /* no need to broadcast on startup */);
			}
		} else if (count == REPOSITORIES_STATE_FILE_VERSION_2) {
			count = dis.readInt();
			for (int i = 0; i < count; i++) {
				ICVSRepositoryLocation location = instance.getRepository(dis.readUTF());
				instance.addRepository(location, false /* no need to broadcast on startup */);
				// Read the next field which is no longer used
				dis.readUTF();
			}
		} else {
			Util.logError(NLS.bind(CVSMessages.CVSProviderPlugin_unknownStateFileVersion, new String[] { Integer.valueOf(count).toString() }), null); 
		}
	}
		
	public static boolean isText(IFile file) {
		if (CVSProviderPlugin.getPlugin().getRepositoriesAreBinary()) return false;
		return Team.getFileContentManager().getType(file) == Team.TEXT;
	}
	
	/**
	 * Gets the determineVersionEnabled.
	 * @return boolean
	 */
	public boolean isDetermineVersionEnabled() {
		return determineVersionEnabled;
	}

	/**
	 * Sets the determineVersionEnabled.
	 * @param determineVersionEnabled The determineVersionEnabled to set
	 */
	public void setDetermineVersionEnabled(boolean determineVersionEnabled) {
		this.determineVersionEnabled = determineVersionEnabled;
	}
	
	/**
	 * Returns the fileModificationManager.
	 * @return FileModificationManager
	 */
	public FileModificationManager getFileModificationManager() {
		return fileModificationManager;
	}

	/**
	 * @return boolean
	 */
	public boolean isWatchEditEnabled() {
		return getPluginPreferences().getBoolean(CVSProviderPlugin.READ_ONLY);
	}

	public void setDebugProtocol(boolean value) {
		Policy.DEBUG_CVS_PROTOCOL = value;		
	}
	
	public boolean isDebugProtocol() {
		return Policy.DEBUG_CVS_PROTOCOL;
	}

	/*
	 * Create the crash indicator file. This method returns true if the file
	 * already existed, indicating that a crash occurred on the last invokation of
	 * the platform.
	 */
	private boolean createCrashFile() {
		IPath pluginStateLocation = CVSProviderPlugin.getPlugin().getStateLocation();
		File crashFile = pluginStateLocation.append(CRASH_INDICATION_FILE).toFile();
		if (crashFile.exists()) {
			return true;
		}
		try {
			crashFile.createNewFile();
		} catch (IOException e) {
			CVSProviderPlugin.log(IStatus.ERROR, e.getMessage(), e);
		}
		return false;
	}
	
	private void deleteCrashFile() {
		IPath pluginStateLocation = CVSProviderPlugin.getPlugin().getStateLocation();
		File crashFile = pluginStateLocation.append(CRASH_INDICATION_FILE).toFile();
		crashFile.delete();
	}
	
	public boolean crashOnLastRun() {
		return crash;
	}
	
	/**
	 * Return the CVS preferences node in the instance scope
	 */
	public org.osgi.service.prefs.Preferences getInstancePreferences() {
		return InstanceScope.INSTANCE.getNode(getBundle().getSymbolicName());
	}
	
	/**
	 * @return Returns the usePlatformLineend.
	 */
	public boolean isUsePlatformLineend() {
		return usePlatformLineend;
	}
	/**
	 * @param usePlatformLineend The usePlatformLineend to set.
	 */
	public void setUsePlatformLineend(boolean usePlatformLineend) {
		this.usePlatformLineend = usePlatformLineend;
	}

	public void setAutoshareOnImport(boolean autoShareOnImport) {
		this.autoShareOnImport = autoShareOnImport;
	}

	public boolean isAutoshareOnImport() {
		return autoShareOnImport;
	}

	/**
	 * @return Returns the watchOnEdit.
	 */
	public boolean isWatchOnEdit() {
		return getPluginPreferences().getBoolean(CVSProviderPlugin.ENABLE_WATCH_ON_EDIT);
	}
	
	// proxy configuration
	
	public void setUseProxy(boolean useProxy) {
		this.useProxy = useProxy;
	}

	public boolean isUseProxy() {
		return this.useProxy;
	}

	public void setProxyType(String proxyType) {
		this.proxyType = proxyType;
	}
	
	public String getProxyType() {
		return this.proxyType;
	}

	public void setProxyHost(String proxyHost) {
		this.proxyHost = proxyHost;
	}
	
	public String getProxyHost() {
		return this.proxyHost;
	}

	public void setProxyPort(String proxyPort) {
		this.proxyPort = proxyPort;
	}
	
	public String getProxyPort() {
		return this.proxyPort;
	}

	public void setUseProxyAuth(boolean useProxyAuth) {
		this.useProxyAuth = useProxyAuth;
	}

	public boolean isUseProxyAuth() {
		return this.useProxyAuth;
	}
	
	public String getProxyUser() {
		Object user = getAuthInfo().get(INFO_PROXY_USER);
		return user==null ? "" : (String) user; //$NON-NLS-1$
	}
	
	public String getProxyPassword() {
		Object pass = getAuthInfo().get(INFO_PROXY_PASS);
		return pass==null ? "" : (String) pass; //$NON-NLS-1$
	}
	
	private Map getAuthInfo() {
		// Retrieve username and password from keyring.
		Map authInfo = Platform.getAuthorizationInfo(FAKE_URL, "proxy", ""); //$NON-NLS-1$ //$NON-NLS-2$
		return authInfo!=null ? authInfo : Collections.EMPTY_MAP;
	}

	public void setProxyAuth(String proxyUser, String proxyPass) {
		Map authInfo = getAuthInfo();
		if (authInfo.size()==0) {
			authInfo = new java.util.HashMap(4);
		}
		if (proxyUser != null) {
			authInfo.put(INFO_PROXY_USER, proxyUser);
		}
		if (proxyPass != null) {
			authInfo.put(INFO_PROXY_PASS, proxyPass);
		}
		try {
			Platform.addAuthorizationInfo(FAKE_URL, "proxy", "", authInfo);  //$NON-NLS-1$ //$NON-NLS-2$
		} catch (CoreException e) {
			// We should probably wrap the CoreException here!
			CVSProviderPlugin.log(e);
		}
	}
	
	public synchronized ActiveChangeSetManager getChangeSetManager() {
		if (changeSetManager == null) {
			changeSetManager = new CVSActiveChangeSetCollector(CVSProviderPlugin.getPlugin().getCVSWorkspaceSubscriber());
		}
		return changeSetManager;
	}
	
	public IJSchService getJSchService() {
		return (IJSchService)tracker.getService();
	}
	
}
