Changed prefs and organized imports to eliminate * imports
diff --git a/providers/bundles/org.eclipse.ecf.provider.filetransfer/.settings/org.eclipse.jdt.ui.prefs b/providers/bundles/org.eclipse.ecf.provider.filetransfer/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..b8ffea2
--- /dev/null
+++ b/providers/bundles/org.eclipse.ecf.provider.filetransfer/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,57 @@
+#Fri Mar 27 09:21:40 PDT 2009
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+formatter_profile=_core
+formatter_settings_version=11
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=;
+org.eclipse.jdt.ui.ondemandthreshold=99
+org.eclipse.jdt.ui.staticondemandthreshold=99
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=true
+sp_cleanup.add_missing_deprecated_annotations=true
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=true
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=true
+sp_cleanup.always_use_parentheses_in_expressions=false
+sp_cleanup.always_use_this_for_non_static_field_access=false
+sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.correct_indentation=false
+sp_cleanup.format_source_code=true
+sp_cleanup.make_local_variable_final=false
+sp_cleanup.make_parameters_final=false
+sp_cleanup.make_private_fields_final=true
+sp_cleanup.make_variable_declarations_final=true
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.on_save_use_additional_actions=false
+sp_cleanup.organize_imports=true
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_trailing_whitespaces=false
+sp_cleanup.remove_trailing_whitespaces_all=true
+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_casts=true
+sp_cleanup.remove_unnecessary_nls_tags=false
+sp_cleanup.remove_unused_imports=false
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=true
+sp_cleanup.remove_unused_private_members=false
+sp_cleanup.remove_unused_private_methods=true
+sp_cleanup.remove_unused_private_types=true
+sp_cleanup.sort_members=false
+sp_cleanup.sort_members_all=false
+sp_cleanup.use_blocks=false
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_this_for_non_static_field_access=false
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+sp_cleanup.use_this_for_non_static_method_access=false
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
diff --git a/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/internal/provider/filetransfer/Activator.java b/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/internal/provider/filetransfer/Activator.java
new file mode 100644
index 0000000..a4383b7
--- /dev/null
+++ b/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/internal/provider/filetransfer/Activator.java
@@ -0,0 +1,662 @@
+/****************************************************************************
+ * Copyright (c) 2006, 2007 Composent, Inc. 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:
+ *    Composent, Inc. - initial API and implementation
+ *****************************************************************************/
+package org.eclipse.ecf.internal.provider.filetransfer;
+
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Set;
+import org.eclipse.core.net.proxy.IProxyService;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IAdapterManager;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionDelta;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.IRegistryChangeEvent;
+import org.eclipse.core.runtime.IRegistryChangeListener;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.ecf.core.util.LogHelper;
+import org.eclipse.ecf.core.util.PlatformHelper;
+import org.eclipse.ecf.filetransfer.service.IRemoteFileSystemBrowser;
+import org.eclipse.ecf.filetransfer.service.IRemoteFileSystemBrowserFactory;
+import org.eclipse.ecf.filetransfer.service.IRetrieveFileTransfer;
+import org.eclipse.ecf.filetransfer.service.IRetrieveFileTransferFactory;
+import org.eclipse.ecf.filetransfer.service.ISendFileTransfer;
+import org.eclipse.ecf.filetransfer.service.ISendFileTransferFactory;
+import org.eclipse.ecf.provider.filetransfer.retrieve.MultiProtocolRetrieveAdapter;
+import org.eclipse.osgi.util.NLS;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.log.LogService;
+import org.osgi.service.url.AbstractURLStreamHandlerService;
+import org.osgi.service.url.URLConstants;
+import org.osgi.service.url.URLStreamHandlerService;
+import org.osgi.util.tracker.ServiceTracker;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator implements BundleActivator {
+
+	private static final String CLASS_ATTR = "class"; //$NON-NLS-1$
+	private static final String PRIORITY_ATTR = "priority"; //$NON-NLS-1$
+	private static final int DEFAULT_PRIORITY = 100;
+	private static final String PROTOCOL_ATTR = "protocol"; //$NON-NLS-1$
+	private static final String[] jvmSchemes = new String[] {Messages.FileTransferNamespace_Http_Protocol, Messages.FileTransferNamespace_Ftp_Protocol, Messages.FileTransferNamespace_File_Protocol, Messages.FileTransferNamespace_Jar_Protocol, Messages.FileTransferNamespace_Https_Protocol, Messages.FileTransferNamespace_Mailto_Protocol, Messages.FileTransferNamespace_Gopher_Protocol};
+
+	private static final String URL_HANDLER_PROTOCOL_NAME = "url.handler.protocol"; //$NON-NLS-1$
+
+	private static final String URLSTREAM_HANDLER_SERVICE_NAME = "org.osgi.service.url.URLStreamHandlerService"; //$NON-NLS-1$
+
+	// The plug-in ID
+	public static final String PLUGIN_ID = "org.eclipse.ecf.provider.filetransfer"; //$NON-NLS-1$
+
+	private static final String RETRIEVE_FILETRANSFER_PROTOCOL_FACTORY_EPOINT_NAME = "retrieveFileTransferProtocolFactory"; //$NON-NLS-1$
+
+	private static final String RETRIEVE_FILETRANSFER_PROTOCOL_FACTORY_EPOINT = PLUGIN_ID + "." //$NON-NLS-1$
+			+ RETRIEVE_FILETRANSFER_PROTOCOL_FACTORY_EPOINT_NAME;
+
+	private static final String SEND_FILETRANSFER_PROTOCOL_FACTORY_EPOINT_NAME = "sendFileTransferProtocolFactory"; //$NON-NLS-1$
+
+	private static final String SEND_FILETRANSFER_PROTOCOL_FACTORY_EPOINT = PLUGIN_ID + "." //$NON-NLS-1$
+			+ SEND_FILETRANSFER_PROTOCOL_FACTORY_EPOINT_NAME;
+
+	private static final String BROWSE_FILETRANSFER_PROTOCOL_FACTORY_EPOINT_NAME = "browseFileTransferProtocolFactory"; //$NON-NLS-1$
+
+	private static final String BROWSE_FILETRANSFER_PROTOCOL_FACTORY_EPOINT = PLUGIN_ID + "." //$NON-NLS-1$
+			+ BROWSE_FILETRANSFER_PROTOCOL_FACTORY_EPOINT_NAME;
+
+	// The shared instance
+	private static Activator plugin;
+
+	private BundleContext context = null;
+
+	private ServiceRegistration fileTransferServiceRegistration;
+
+	private ServiceTracker logServiceTracker = null;
+	private ServiceTracker extensionRegistryTracker = null;
+
+	private Map retrieveFileTransferProtocolMap = null;
+
+	private Map sendFileTransferProtocolMap = null;
+
+	private Map browseFileTransferProtocolMap = null;
+
+	private ServiceTracker adapterManagerTracker = null;
+
+	private ServiceTracker proxyServiceTracker = null;
+
+	private IURLConnectionModifier urlConnectionModifier = null;
+
+	private IRegistryChangeListener registryChangeListener = new IRegistryChangeListener() {
+
+		public void registryChanged(IRegistryChangeEvent event) {
+			final IExtensionDelta retrieveDelta[] = event.getExtensionDeltas(PLUGIN_ID, RETRIEVE_FILETRANSFER_PROTOCOL_FACTORY_EPOINT_NAME);
+			for (int i = 0; i < retrieveDelta.length; i++) {
+				switch (retrieveDelta[i].getKind()) {
+					case IExtensionDelta.ADDED :
+						addRetrieveExtensions(retrieveDelta[i].getExtension().getConfigurationElements());
+						break;
+					case IExtensionDelta.REMOVED :
+						removeRetrieveExtensions(retrieveDelta[i].getExtension().getConfigurationElements());
+						break;
+				}
+			}
+			final IExtensionDelta sendDelta[] = event.getExtensionDeltas(PLUGIN_ID, SEND_FILETRANSFER_PROTOCOL_FACTORY_EPOINT_NAME);
+			for (int i = 0; i < sendDelta.length; i++) {
+				switch (sendDelta[i].getKind()) {
+					case IExtensionDelta.ADDED :
+						addSendExtensions(sendDelta[i].getExtension().getConfigurationElements());
+						break;
+					case IExtensionDelta.REMOVED :
+						removeSendExtensions(sendDelta[i].getExtension().getConfigurationElements());
+						break;
+				}
+			}
+			final IExtensionDelta browseDelta[] = event.getExtensionDeltas(PLUGIN_ID, BROWSE_FILETRANSFER_PROTOCOL_FACTORY_EPOINT_NAME);
+			for (int i = 0; i < browseDelta.length; i++) {
+				switch (browseDelta[i].getKind()) {
+					case IExtensionDelta.ADDED :
+						addBrowseExtensions(browseDelta[i].getExtension().getConfigurationElements());
+						break;
+					case IExtensionDelta.REMOVED :
+						removeBrowseExtensions(browseDelta[i].getExtension().getConfigurationElements());
+						break;
+				}
+			}
+		}
+
+	};
+
+	/**
+	 * The constructor
+	 */
+	public Activator() {
+		//
+	}
+
+	protected LogService getLogService() {
+		if (logServiceTracker == null) {
+			logServiceTracker = new ServiceTracker(this.context, LogService.class.getName(), null);
+			logServiceTracker.open();
+		}
+		return (LogService) logServiceTracker.getService();
+	}
+
+	public IProxyService getProxyService() {
+		try {
+			if (proxyServiceTracker == null) {
+				proxyServiceTracker = new ServiceTracker(this.context, IProxyService.class.getName(), null);
+				proxyServiceTracker.open();
+			}
+			return (IProxyService) proxyServiceTracker.getService();
+		} catch (Exception e) {
+			logNoProxyWarning(e);
+		} catch (NoClassDefFoundError e) {
+			logNoProxyWarning(e);
+		}
+		return null;
+	}
+
+	public static void logNoProxyWarning(Throwable e) {
+		getDefault().log(new Status(IStatus.WARNING, Activator.PLUGIN_ID, IStatus.ERROR, "Warning: Platform proxy API not available", e)); //$NON-NLS-1$
+	}
+
+	public void log(IStatus status) {
+		final LogService logService = getLogService();
+		if (logService != null) {
+			logService.log(LogHelper.getLogCode(status), LogHelper.getLogMessage(status), status.getException());
+		}
+	}
+
+	public Bundle getBundle() {
+		if (context == null)
+			return null;
+		return context.getBundle();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext)
+	 */
+	public void start(BundleContext ctxt) throws Exception {
+		plugin = this;
+		this.context = ctxt;
+
+		// initialize the default url connection modifier for ssl
+		try {
+			Class urlConnectionModifierClass = Class.forName("org.eclipse.ecf.internal.provider.filetransfer.ssl.ECFURLConnectionModifier"); //$NON-NLS-1$
+			urlConnectionModifier = (IURLConnectionModifier) urlConnectionModifierClass.newInstance();
+			urlConnectionModifier.init(ctxt);
+		} catch (ClassNotFoundException e) {
+			// will occur if fragment is not installed or not on proper execution environment
+		} catch (Throwable t) {
+			log(new Status(IStatus.ERROR, getDefault().getBundle().getSymbolicName(), "Unexpected Error in Activator.start", t)); //$NON-NLS-1$
+		}
+
+		fileTransferServiceRegistration = ctxt.registerService(IRetrieveFileTransferFactory.class.getName(), new IRetrieveFileTransferFactory() {
+			public IRetrieveFileTransfer newInstance() {
+				return new MultiProtocolRetrieveAdapter();
+			}
+		}, null);
+		this.extensionRegistryTracker = new ServiceTracker(ctxt, IExtensionRegistry.class.getName(), null);
+		this.extensionRegistryTracker.open();
+		final IExtensionRegistry registry = getExtensionRegistry();
+		if (registry != null) {
+			registry.addRegistryChangeListener(registryChangeListener);
+		}
+		// Can't be lazy about this, as schemes need to be registered with
+		// platform
+		loadProtocolHandlers();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext)
+	 */
+	public void stop(BundleContext ctxt) throws Exception {
+		plugin = null;
+		this.context = null;
+		final IExtensionRegistry registry = getExtensionRegistry();
+		if (registry != null) {
+			registry.removeRegistryChangeListener(registryChangeListener);
+		}
+
+		if (urlConnectionModifier != null) {
+			urlConnectionModifier.dispose();
+			urlConnectionModifier = null;
+		}
+		if (extensionRegistryTracker != null) {
+			extensionRegistryTracker.close();
+			extensionRegistryTracker = null;
+		}
+		if (fileTransferServiceRegistration != null) {
+			fileTransferServiceRegistration.unregister();
+			fileTransferServiceRegistration = null;
+		}
+		if (adapterManagerTracker != null) {
+			adapterManagerTracker.close();
+			adapterManagerTracker = null;
+		}
+		if (proxyServiceTracker != null) {
+			proxyServiceTracker.close();
+			proxyServiceTracker = null;
+		}
+		this.context = null;
+		if (this.retrieveFileTransferProtocolMap != null) {
+			this.retrieveFileTransferProtocolMap.clear();
+			this.retrieveFileTransferProtocolMap = null;
+		}
+		if (this.sendFileTransferProtocolMap != null) {
+			this.sendFileTransferProtocolMap.clear();
+			this.sendFileTransferProtocolMap = null;
+		}
+		if (this.browseFileTransferProtocolMap != null) {
+			this.browseFileTransferProtocolMap.clear();
+			this.browseFileTransferProtocolMap = null;
+		}
+	}
+
+	/**
+	 * Returns the shared instance
+	 * 
+	 * @return the shared instance
+	 */
+	public synchronized static Activator getDefault() {
+		if (plugin == null) {
+			plugin = new Activator();
+		}
+		return plugin;
+	}
+
+	public String[] getPlatformSupportedSchemes() {
+		final ServiceTracker handlers = new ServiceTracker(context, URLSTREAM_HANDLER_SERVICE_NAME, null);
+		handlers.open();
+		final ServiceReference[] refs = handlers.getServiceReferences();
+		final Set protocols = new HashSet();
+		if (refs != null)
+			for (int i = 0; i < refs.length; i++) {
+				final Object protocol = refs[i].getProperty(URL_HANDLER_PROTOCOL_NAME);
+				if (protocol instanceof String)
+					protocols.add(protocol);
+				else if (protocol instanceof String[]) {
+					final String[] ps = (String[]) protocol;
+					for (int j = 0; j < ps.length; j++)
+						protocols.add(ps[j]);
+				}
+			}
+		handlers.close();
+		for (int i = 0; i < jvmSchemes.length; i++)
+			protocols.add(jvmSchemes[i]);
+		return (String[]) protocols.toArray(new String[] {});
+	}
+
+	public IExtensionRegistry getExtensionRegistry() {
+		if (extensionRegistryTracker == null) {
+			this.extensionRegistryTracker = new ServiceTracker(context, IExtensionRegistry.class.getName(), null);
+			this.extensionRegistryTracker.open();
+		}
+		return (IExtensionRegistry) extensionRegistryTracker.getService();
+	}
+
+	static class ProtocolFactory implements Comparable {
+		Object factory;
+		int priority = 0;
+		String id;
+
+		public ProtocolFactory(Object factory, int priority, String id) {
+			this.factory = factory;
+			this.priority = priority;
+			this.id = id;
+		}
+
+		public Object getFactory() {
+			return factory;
+		}
+
+		public String getID() {
+			return id;
+		}
+
+		/* (non-Javadoc)
+		 * @see java.lang.Comparable#compareTo(java.lang.Object)
+		 */
+		public int compareTo(Object another) {
+			if (!(another instanceof ProtocolFactory))
+				return -1;
+			ProtocolFactory other = (ProtocolFactory) another;
+			if (this.priority == other.priority)
+				return 0;
+			return (this.priority < other.priority) ? -1 : 1;
+		}
+	}
+
+	private int getPriority(IConfigurationElement configElement, String warning, String protocol) {
+		// Get priority for new entry, if optional priority attribute specified
+		final String priorityString = configElement.getAttribute(PRIORITY_ATTR);
+		int priority = DEFAULT_PRIORITY;
+		if (priorityString != null) {
+			try {
+				priority = new Integer(priorityString).intValue();
+				// Make sure that any negative values are reset to 0 (highest priority)
+				priority = (priority < 0) ? 0 : priority;
+			} catch (NumberFormatException e) {
+				// Give warning
+				Activator.getDefault().log(new Status(IStatus.WARNING, PLUGIN_ID, IStatus.WARNING, NLS.bind("{0} for {1} from {2} has invalid priority {3}. Priority will be set to {4}", new Object[] {warning, protocol, configElement.getDeclaringExtension().getContributor().getName(), priorityString, String.valueOf(DEFAULT_PRIORITY)}), null)); //$NON-NLS-1$
+			}
+		}
+		return priority;
+	}
+
+	void addRetrieveExtensions(IConfigurationElement[] configElements) {
+		String[] existingSchemes = getPlatformSupportedSchemes();
+		for (int i = 0; i < configElements.length; i++) {
+			final String protocol = configElements[i].getAttribute(PROTOCOL_ATTR);
+			if (protocol == null || "".equals(protocol)) //$NON-NLS-1$
+				return;
+			String CONTRIBUTION_WARNING = "File retrieve contribution"; //$NON-NLS-1$
+			try {
+				// First create factory clazz 
+				final IRetrieveFileTransferFactory clazz = (IRetrieveFileTransferFactory) configElements[i].createExecutableExtension(CLASS_ATTR);
+				// Get priority for new entry, if optional priority attribute specified
+				int priority = getPriority(configElements[i], CONTRIBUTION_WARNING, protocol);
+				String contributorName = configElements[i].getDeclaringExtension().getContributor().getName();
+				// Now create new ProtocolFactory
+				ProtocolFactory newProtocolFactory = new ProtocolFactory(clazz, priority, contributorName);
+				// Then look for any existing protocol factories under same protocol
+				synchronized (retrieveFileTransferProtocolMap) {
+					ProtocolFactory oldProtocolFactory = (ProtocolFactory) retrieveFileTransferProtocolMap.get(protocol);
+					// If found, choose between them based upon comparing their priority
+					if (oldProtocolFactory != null) {
+						// Now, compare priorities and pic winner
+						int result = oldProtocolFactory.compareTo(newProtocolFactory);
+						if (result < 0) {
+							// Existing one has higher priority, so we provide warning and return (leaving existing one as the handler)
+							Activator.getDefault().log(new Status(IStatus.WARNING, PLUGIN_ID, IStatus.WARNING, NLS.bind("{0} for protocol {1} from {2} will be ignored.  Existing protocol factory has higher priority.", new Object[] {CONTRIBUTION_WARNING, protocol, contributorName}), null)); //$NON-NLS-1$
+							continue;
+						} else if (result == 0) {
+							// Warn that we are using new one because they have the same priority.
+							Activator.getDefault().log(new Status(IStatus.WARNING, PLUGIN_ID, IStatus.WARNING, NLS.bind("{0} for protocol {1} from {2} will be used in preference to existing handler.  Both have same priority={3}.", new Object[] {CONTRIBUTION_WARNING, protocol, contributorName, new Integer(priority)}), null)); //$NON-NLS-1$
+						} else if (result > 0) {
+							// Warn that we are using new one because it has higher priority.
+							Activator.getDefault().log(new Status(IStatus.WARNING, PLUGIN_ID, IStatus.WARNING, NLS.bind("{0} for protocol {1} from {2} will be used in preference to existing handler.  New handler has higher priority={3}<{4}.", new Object[] {CONTRIBUTION_WARNING, protocol, contributorName, new Integer(priority), new Integer(oldProtocolFactory.priority)}), null)); //$NON-NLS-1$
+						}
+					}
+					if (!isSchemeRegistered(protocol, existingSchemes))
+						registerScheme(protocol);
+					// Finally, put clazz in map with protocol as key
+					retrieveFileTransferProtocolMap.put(protocol, newProtocolFactory);
+				}
+			} catch (final CoreException e) {
+				Activator.getDefault().log(new Status(IStatus.ERROR, PLUGIN_ID, IStatus.ERROR, NLS.bind("Error loading from {0} extension point", RETRIEVE_FILETRANSFER_PROTOCOL_FACTORY_EPOINT), e)); //$NON-NLS-1$
+			}
+		}
+	}
+
+	void removeRetrieveExtensions(IConfigurationElement[] configElements) {
+		for (int i = 0; i < configElements.length; i++) {
+			final String protocol = configElements[i].getAttribute(PROTOCOL_ATTR);
+			if (protocol == null || "".equals(protocol)) //$NON-NLS-1$
+				return;
+			synchronized (retrieveFileTransferProtocolMap) {
+				ProtocolFactory protocolFactory = (ProtocolFactory) retrieveFileTransferProtocolMap.get(protocol);
+				if (protocolFactory != null) {
+					// If the contributor that is leaving is the one responsible for the protocol factory then remove
+					if (configElements[i].getContributor().getName().equals(protocolFactory.getID())) {
+						retrieveFileTransferProtocolMap.remove(protocol);
+					}
+				}
+			}
+		}
+	}
+
+	void addSendExtensions(IConfigurationElement[] configElements) {
+		String[] existingSchemes = getPlatformSupportedSchemes();
+		for (int i = 0; i < configElements.length; i++) {
+			final String protocol = configElements[i].getAttribute(PROTOCOL_ATTR);
+			if (protocol == null || "".equals(protocol)) //$NON-NLS-1$
+				return;
+			String CONTRIBUTION_WARNING = "File send contribution"; //$NON-NLS-1$
+			try {
+				// First create factory clazz 
+				final ISendFileTransferFactory clazz = (ISendFileTransferFactory) configElements[i].createExecutableExtension(CLASS_ATTR);
+				// Get priority for new entry, if optional priority attribute specified
+				int priority = getPriority(configElements[i], CONTRIBUTION_WARNING, protocol);
+				String contributorName = configElements[i].getDeclaringExtension().getContributor().getName();
+				// Now create new ProtocolFactory
+				ProtocolFactory newProtocolFactory = new ProtocolFactory(clazz, priority, contributorName);
+				// Then look for any existing protocol factories under same protocol
+				synchronized (sendFileTransferProtocolMap) {
+					ProtocolFactory oldProtocolFactory = (ProtocolFactory) sendFileTransferProtocolMap.get(protocol);
+					// If found, choose between them based upon comparing their priority
+					if (oldProtocolFactory != null) {
+						// Now, compare priorities and pic winner
+						int result = oldProtocolFactory.compareTo(newProtocolFactory);
+						if (result < 0) {
+							// Existing one has higher priority, so we provide warning and return (leaving existing one as the handler)
+							Activator.getDefault().log(new Status(IStatus.WARNING, PLUGIN_ID, IStatus.WARNING, NLS.bind("{0} for protocol {1} from {2} will be ignored.  Existing protocol factory has higher priority.", new Object[] {CONTRIBUTION_WARNING, protocol, contributorName}), null)); //$NON-NLS-1$
+							continue;
+						} else if (result == 0) {
+							// Warn that we are using new one because they have the same priority.
+							Activator.getDefault().log(new Status(IStatus.WARNING, PLUGIN_ID, IStatus.WARNING, NLS.bind("{0} for protocol {1} from {2} will be used in preference to existing handler.  Both have same priority={3}.", new Object[] {CONTRIBUTION_WARNING, protocol, contributorName, new Integer(priority)}), null)); //$NON-NLS-1$
+						} else if (result > 0) {
+							// Warn that we are using new one because it has higher priority.
+							Activator.getDefault().log(new Status(IStatus.WARNING, PLUGIN_ID, IStatus.WARNING, NLS.bind("{0} for protocol {1} from {2} will be used in preference to existing handler.  New handler has higher priority={3}<{4}.", new Object[] {CONTRIBUTION_WARNING, protocol, contributorName, new Integer(priority), new Integer(oldProtocolFactory.priority)}), null)); //$NON-NLS-1$
+						}
+					}
+					if (!isSchemeRegistered(protocol, existingSchemes))
+						registerScheme(protocol);
+					// Finally, put clazz in map with protocol as key
+					sendFileTransferProtocolMap.put(protocol, newProtocolFactory);
+				}
+			} catch (final CoreException e) {
+				Activator.getDefault().log(new Status(IStatus.ERROR, PLUGIN_ID, IStatus.ERROR, NLS.bind("Error loading from {0} extension point", SEND_FILETRANSFER_PROTOCOL_FACTORY_EPOINT), e)); //$NON-NLS-1$
+			}
+		}
+	}
+
+	void removeSendExtensions(IConfigurationElement[] configElements) {
+		for (int i = 0; i < configElements.length; i++) {
+			final String protocol = configElements[i].getAttribute(PROTOCOL_ATTR);
+			if (protocol == null || "".equals(protocol)) //$NON-NLS-1$
+				return;
+			synchronized (sendFileTransferProtocolMap) {
+				ProtocolFactory protocolFactory = (ProtocolFactory) sendFileTransferProtocolMap.get(protocol);
+				if (protocolFactory != null) {
+					// If the contributor that is leaving is the one responsible for the protocol factory then remove
+					if (configElements[i].getContributor().getName().equals(protocolFactory.getID())) {
+						sendFileTransferProtocolMap.remove(protocol);
+					}
+				}
+			}
+		}
+	}
+
+	void addBrowseExtensions(IConfigurationElement[] configElements) {
+		String[] existingSchemes = getPlatformSupportedSchemes();
+		for (int i = 0; i < configElements.length; i++) {
+			final String protocol = configElements[i].getAttribute(PROTOCOL_ATTR);
+			if (protocol == null || "".equals(protocol)) //$NON-NLS-1$
+				return;
+			String CONTRIBUTION_WARNING = "File browse contribution"; //$NON-NLS-1$
+			try {
+				// First create factory clazz 
+				final IRemoteFileSystemBrowserFactory clazz = (IRemoteFileSystemBrowserFactory) configElements[i].createExecutableExtension(CLASS_ATTR);
+				// Get priority for new entry, if optional priority attribute specified
+				int priority = getPriority(configElements[i], CONTRIBUTION_WARNING, protocol);
+				String contributorName = configElements[i].getDeclaringExtension().getContributor().getName();
+				// Now create new ProtocolFactory
+				ProtocolFactory newProtocolFactory = new ProtocolFactory(clazz, priority, contributorName);
+				synchronized (browseFileTransferProtocolMap) {
+					// Then look for any existing protocol factories under same protocol
+					ProtocolFactory oldProtocolFactory = (ProtocolFactory) browseFileTransferProtocolMap.get(protocol);
+					// If found, choose between them based upon comparing their priority
+					if (oldProtocolFactory != null) {
+						// Now, compare priorities and pic winner
+						int result = oldProtocolFactory.compareTo(newProtocolFactory);
+						if (result < 0) {
+							// Existing one has higher priority, so we provide warning and return (leaving existing one as the handler)
+							Activator.getDefault().log(new Status(IStatus.WARNING, PLUGIN_ID, IStatus.WARNING, NLS.bind("{0} for protocol {1} from {2} will be ignored.  Existing protocol factory has higher priority.", new Object[] {CONTRIBUTION_WARNING, protocol, contributorName}), null)); //$NON-NLS-1$
+							continue;
+						} else if (result == 0) {
+							// Warn that we are using new one because they have the same priority.
+							Activator.getDefault().log(new Status(IStatus.WARNING, PLUGIN_ID, IStatus.WARNING, NLS.bind("{0} for protocol {1} from {2} will be used in preference to existing handler.  Both have same priority={3}.", new Object[] {CONTRIBUTION_WARNING, protocol, contributorName, new Integer(priority)}), null)); //$NON-NLS-1$
+						} else if (result > 0) {
+							// Warn that we are using new one because it has higher priority.
+							Activator.getDefault().log(new Status(IStatus.WARNING, PLUGIN_ID, IStatus.WARNING, NLS.bind("{0} for protocol {1} from {2} will be used in preference to existing handler.  New handler has higher priority={3}<{4}.", new Object[] {CONTRIBUTION_WARNING, protocol, contributorName, new Integer(priority), new Integer(oldProtocolFactory.priority)}), null)); //$NON-NLS-1$
+						}
+					}
+					if (!isSchemeRegistered(protocol, existingSchemes))
+						registerScheme(protocol);
+					// Finally, put clazz in map with protocol as key
+					browseFileTransferProtocolMap.put(protocol, newProtocolFactory);
+				}
+			} catch (final CoreException e) {
+				Activator.getDefault().log(new Status(IStatus.ERROR, PLUGIN_ID, IStatus.ERROR, NLS.bind("Error loading from {0} extension point", BROWSE_FILETRANSFER_PROTOCOL_FACTORY_EPOINT), e)); //$NON-NLS-1$
+			}
+		}
+	}
+
+	void removeBrowseExtensions(IConfigurationElement[] configElements) {
+		for (int i = 0; i < configElements.length; i++) {
+			final String protocol = configElements[i].getAttribute(PROTOCOL_ATTR);
+			if (protocol == null || "".equals(protocol)) //$NON-NLS-1$
+				return;
+			synchronized (browseFileTransferProtocolMap) {
+				ProtocolFactory protocolFactory = (ProtocolFactory) browseFileTransferProtocolMap.get(protocol);
+				if (protocolFactory != null) {
+					// If the contributor that is leaving is the one responsible for the protocol factory then remove
+					if (configElements[i].getContributor().getName().equals(protocolFactory.getID())) {
+						browseFileTransferProtocolMap.remove(protocol);
+					}
+				}
+			}
+		}
+	}
+
+	private void loadProtocolHandlers() {
+		this.retrieveFileTransferProtocolMap = new HashMap(3);
+		this.sendFileTransferProtocolMap = new HashMap(3);
+		this.browseFileTransferProtocolMap = new HashMap(3);
+		final IExtensionRegistry reg = getExtensionRegistry();
+		if (reg != null) {
+			final IExtensionPoint retrieveExtensionPoint = reg.getExtensionPoint(RETRIEVE_FILETRANSFER_PROTOCOL_FACTORY_EPOINT);
+			if (retrieveExtensionPoint != null)
+				addRetrieveExtensions(retrieveExtensionPoint.getConfigurationElements());
+			// Now do it with send
+			final IExtensionPoint sendExtensionPoint = reg.getExtensionPoint(SEND_FILETRANSFER_PROTOCOL_FACTORY_EPOINT);
+			if (sendExtensionPoint != null)
+				addSendExtensions(sendExtensionPoint.getConfigurationElements());
+			// Now for browse
+			final IExtensionPoint browseExtensionPoint = reg.getExtensionPoint(BROWSE_FILETRANSFER_PROTOCOL_FACTORY_EPOINT);
+			if (browseExtensionPoint != null)
+				addBrowseExtensions(browseExtensionPoint.getConfigurationElements());
+		}
+	}
+
+	private boolean isSchemeRegistered(String protocol, String[] schemes) {
+		for (int i = 0; i < schemes.length; i++) {
+			if (protocol.equals(schemes[i]))
+				return true;
+		}
+		return false;
+	}
+
+	class DummyURLStreamHandlerService extends AbstractURLStreamHandlerService {
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see org.osgi.service.url.AbstractURLStreamHandlerService#openConnection(java.net.URL)
+		 */
+		public URLConnection openConnection(URL u) throws IOException {
+			throw new IOException(NLS.bind("URLConnection cannot be created for {0}", u.toExternalForm())); //$NON-NLS-1$
+		}
+
+	}
+
+	private final DummyURLStreamHandlerService dummyService = new DummyURLStreamHandlerService();
+
+	private void registerScheme(String protocol) {
+		final Hashtable properties = new Hashtable();
+		properties.put(URLConstants.URL_HANDLER_PROTOCOL, new String[] {protocol});
+		context.registerService(URLStreamHandlerService.class.getName(), dummyService, properties);
+	}
+
+	public IRetrieveFileTransfer getFileTransfer(String protocol) {
+		ProtocolFactory protocolFactory = null;
+		synchronized (retrieveFileTransferProtocolMap) {
+			protocolFactory = (ProtocolFactory) retrieveFileTransferProtocolMap.get(protocol);
+		}
+		if (protocolFactory == null)
+			return null;
+		final IRetrieveFileTransferFactory factory = (IRetrieveFileTransferFactory) protocolFactory.getFactory();
+		if (factory != null)
+			return factory.newInstance();
+		return null;
+	}
+
+	public ISendFileTransfer getSendFileTransfer(String protocol) {
+		ProtocolFactory protocolFactory = null;
+		synchronized (sendFileTransferProtocolMap) {
+			protocolFactory = (ProtocolFactory) sendFileTransferProtocolMap.get(protocol);
+		}
+		if (protocolFactory == null)
+			return null;
+		final ISendFileTransferFactory factory = (ISendFileTransferFactory) protocolFactory.getFactory();
+		if (factory != null)
+			return factory.newInstance();
+		return null;
+	}
+
+	public IRemoteFileSystemBrowser getBrowseFileTransfer(String protocol) {
+		ProtocolFactory protocolFactory = null;
+		synchronized (browseFileTransferProtocolMap) {
+			protocolFactory = (ProtocolFactory) browseFileTransferProtocolMap.get(protocol);
+		}
+		if (protocolFactory == null)
+			return null;
+		final IRemoteFileSystemBrowserFactory factory = (IRemoteFileSystemBrowserFactory) protocolFactory.getFactory();
+		if (factory != null)
+			return factory.newInstance();
+		return null;
+	}
+
+	public IAdapterManager getAdapterManager() {
+		// First, try to get the adapter manager via
+		if (adapterManagerTracker == null) {
+			adapterManagerTracker = new ServiceTracker(this.context, IAdapterManager.class.getName(), null);
+			adapterManagerTracker.open();
+		}
+		IAdapterManager adapterManager = (IAdapterManager) adapterManagerTracker.getService();
+		// Then, if the service isn't there, try to get from Platform class via
+		// PlatformHelper class
+		if (adapterManager == null)
+			adapterManager = PlatformHelper.getPlatformAdapterManager();
+		return adapterManager;
+	}
+
+	public IURLConnectionModifier getURLConnectionModifier() {
+		return urlConnectionModifier;
+	}
+
+}
diff --git a/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/browse/AbstractFileSystemBrowser.java b/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/browse/AbstractFileSystemBrowser.java
new file mode 100644
index 0000000..4b655ff
--- /dev/null
+++ b/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/browse/AbstractFileSystemBrowser.java
@@ -0,0 +1,136 @@
+/****************************************************************************
+ * Copyright (c) 2007 Composent, Inc. 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:
+ *    Composent, Inc. - initial API and implementation
+ *****************************************************************************/
+
+package org.eclipse.ecf.provider.filetransfer.browse;
+
+import java.util.Arrays;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.ecf.filetransfer.IRemoteFile;
+import org.eclipse.ecf.filetransfer.IRemoteFileSystemListener;
+import org.eclipse.ecf.filetransfer.IRemoteFileSystemRequest;
+import org.eclipse.ecf.filetransfer.UserCancelledException;
+import org.eclipse.ecf.filetransfer.events.IRemoteFileSystemBrowseEvent;
+import org.eclipse.ecf.filetransfer.events.IRemoteFileSystemEvent;
+import org.eclipse.ecf.filetransfer.identity.IFileID;
+import org.eclipse.ecf.internal.provider.filetransfer.Messages;
+
+/**
+ * Abstract class for browsing an efs file system.
+ */
+public abstract class AbstractFileSystemBrowser {
+
+	protected IFileID fileID = null;
+	protected IRemoteFileSystemListener listener = null;
+
+	Job job = null;
+	protected Exception exception = null;
+	protected IRemoteFile[] remoteFiles = null;
+
+	Object lock = new Object();
+
+	class DirectoryJob extends Job {
+
+		public DirectoryJob() {
+			super(fileID.getName());
+		}
+
+		protected IStatus run(IProgressMonitor monitor) {
+			try {
+				if (monitor.isCanceled())
+					throw new UserCancelledException(Messages.AbstractRetrieveFileTransfer_Exception_User_Cancelled);
+				runRequest();
+			} catch (Exception e) {
+				AbstractFileSystemBrowser.this.exception = e;
+			} finally {
+				listener.handleRemoteFileEvent(createRemoteFileEvent());
+				cleanUp();
+			}
+			return Status.OK_STATUS;
+		}
+
+	}
+
+	protected void cleanUp() {
+		synchronized (lock) {
+			job = null;
+		}
+	}
+
+	/**
+	 * Run the actual request.  This method is called within the job created to actually get the
+	 * directory or file information.
+	 * @throws Exception if some problem with making the request or receiving response to the request.
+	 */
+	protected abstract void runRequest() throws Exception;
+
+	public AbstractFileSystemBrowser(IFileID directoryOrFileID, IRemoteFileSystemListener listener) {
+		Assert.isNotNull(directoryOrFileID);
+		this.fileID = directoryOrFileID;
+		Assert.isNotNull(listener);
+		this.listener = listener;
+	}
+
+	public IRemoteFileSystemRequest sendBrowseRequest() {
+		job = new DirectoryJob();
+		job.schedule();
+		return new IRemoteFileSystemRequest() {
+
+			public void cancel() {
+				synchronized (lock) {
+					if (job != null)
+						job.cancel();
+				}
+			}
+
+			public IFileID getFileID() {
+				return fileID;
+			}
+
+			public IRemoteFileSystemListener getRemoteFileListener() {
+				return listener;
+			}
+
+		};
+
+	}
+
+	/**
+	 * @return file system directory event
+	 */
+	protected IRemoteFileSystemEvent createRemoteFileEvent() {
+		return new IRemoteFileSystemBrowseEvent() {
+
+			public IFileID getFileID() {
+				return fileID;
+			}
+
+			public Exception getException() {
+				return exception;
+			}
+
+			public String toString() {
+				StringBuffer buf = new StringBuffer("RemoteFileSystemBrowseEvent["); //$NON-NLS-1$
+				buf.append("fileID=").append(fileID).append(";"); //$NON-NLS-1$ //$NON-NLS-2$
+				buf.append("files=" + Arrays.asList(remoteFiles)).append("]"); //$NON-NLS-1$ //$NON-NLS-2$
+				return buf.toString();
+			}
+
+			public IRemoteFile[] getRemoteFiles() {
+				return remoteFiles;
+			}
+		};
+	}
+
+}
diff --git a/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/browse/LocalRemoteFile.java b/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/browse/LocalRemoteFile.java
new file mode 100644
index 0000000..c486f1a
--- /dev/null
+++ b/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/browse/LocalRemoteFile.java
@@ -0,0 +1,118 @@
+/****************************************************************************
+ * Copyright (c) 2007 Composent, Inc. 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:
+ *    Composent, Inc. - initial API and implementation
+ *****************************************************************************/
+
+package org.eclipse.ecf.provider.filetransfer.browse;
+
+import java.io.File;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IAdapterManager;
+import org.eclipse.ecf.core.identity.IDFactory;
+import org.eclipse.ecf.filetransfer.IRemoteFile;
+import org.eclipse.ecf.filetransfer.IRemoteFileAttributes;
+import org.eclipse.ecf.filetransfer.IRemoteFileInfo;
+import org.eclipse.ecf.filetransfer.identity.FileIDFactory;
+import org.eclipse.ecf.filetransfer.identity.IFileID;
+import org.eclipse.ecf.internal.provider.filetransfer.Activator;
+import org.eclipse.ecf.provider.filetransfer.identity.FileTransferNamespace;
+
+/**
+ * Local representation of an {@link IRemoteFile}.
+ */
+public class LocalRemoteFile implements IRemoteFile {
+
+	File file = null;
+
+	IRemoteFileInfo info;
+
+	/**
+	 * @param file
+	 */
+	public LocalRemoteFile(File file) {
+		this.file = file;
+		Assert.isNotNull(file);
+		this.info = new IRemoteFileInfo() {
+
+			IRemoteFileAttributes attributes = new LocalRemoteFileAttributes(LocalRemoteFile.this.file);
+
+			public IRemoteFileAttributes getAttributes() {
+				return attributes;
+			}
+
+			public long getLastModified() {
+				return LocalRemoteFile.this.file.lastModified();
+			}
+
+			public long getLength() {
+				return LocalRemoteFile.this.file.length();
+			}
+
+			public String getName() {
+				return LocalRemoteFile.this.file.getName();
+			}
+
+			public boolean isDirectory() {
+				return LocalRemoteFile.this.file.isDirectory();
+			}
+
+			public void setAttributes(IRemoteFileAttributes attributes) {
+				// can't set attributes
+			}
+
+			public void setLastModified(long time) {
+				// can't set post hoc
+			}
+
+			public void setName(String name) {
+				// Can't modify post hoc
+			}
+		};
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ecf.filetransfer.IRemoteFile#getID()
+	 */
+	public IFileID getID() {
+		try {
+			return FileIDFactory.getDefault().createFileID(IDFactory.getDefault().getNamespaceByName(FileTransferNamespace.PROTOCOL), file.toURL());
+		} catch (Exception e) {
+			// Should never happen
+			return null;
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ecf.filetransfer.IRemoteFile#getInfo()
+	 */
+	public IRemoteFileInfo getInfo() {
+		return info;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
+	 */
+	public Object getAdapter(Class adapter) {
+		IAdapterManager adapterManager = Activator.getDefault().getAdapterManager();
+		if (adapterManager == null)
+			return null;
+		return adapterManager.loadAdapter(this, adapter.getName());
+	}
+
+	public String toString() {
+		StringBuffer buf = new StringBuffer("LocalRemoteFile["); //$NON-NLS-1$
+		buf.append("id=").append(getID()).append(";"); //$NON-NLS-1$//$NON-NLS-2$
+		buf.append("name=").append(getInfo().getName()).append(";"); //$NON-NLS-1$ //$NON-NLS-2$
+		buf.append("isDir=").append(getInfo().isDirectory()).append(";"); //$NON-NLS-1$ //$NON-NLS-2$
+		buf.append("length=").append(getInfo().getLength()).append(";"); //$NON-NLS-1$ //$NON-NLS-2$
+		buf.append("lastMod=").append(getInfo().getLastModified()).append(";"); //$NON-NLS-1$ //$NON-NLS-2$
+		buf.append("attr=").append(getInfo().getAttributes()).append("]"); //$NON-NLS-1$ //$NON-NLS-2$
+		return buf.toString();
+	}
+}
diff --git a/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/browse/LocalRemoteFileAttributes.java b/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/browse/LocalRemoteFileAttributes.java
new file mode 100644
index 0000000..4334633
--- /dev/null
+++ b/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/browse/LocalRemoteFileAttributes.java
@@ -0,0 +1,84 @@
+/****************************************************************************
+ * Copyright (c) 2007 Composent, Inc. 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:
+ *    Composent, Inc. - initial API and implementation
+ *****************************************************************************/
+
+package org.eclipse.ecf.provider.filetransfer.browse;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import org.eclipse.ecf.filetransfer.IRemoteFileAttributes;
+
+/**
+ * File attributes for {@link LocalRemoteFile} instances.
+ */
+public class LocalRemoteFileAttributes implements IRemoteFileAttributes {
+
+	File file = null;
+
+	static String[] fileAttributes = {IRemoteFileAttributes.READ_ATTRIBUTE, IRemoteFileAttributes.WRITE_ATTRIBUTE, IRemoteFileAttributes.HIDDEN_ATTRIBUTE, IRemoteFileAttributes.EXEC_ATTRIBUTE, IRemoteFileAttributes.ARCHIVE_ATTRIBUTE};
+	static List attributeKeys = new ArrayList(Arrays.asList(fileAttributes));
+
+	public LocalRemoteFileAttributes(File file) {
+		this.file = file;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ecf.filetransfer.IRemoteFileAttributes#getAttribute(java.lang.String)
+	 */
+	public String getAttribute(String key) {
+		if (key == null)
+			return null;
+		if (key.equals(IRemoteFileAttributes.READ_ATTRIBUTE)) {
+			if (file.canRead())
+				return Boolean.TRUE.toString();
+		} else if (key.equals(IRemoteFileAttributes.WRITE_ATTRIBUTE)) {
+			if (file.canWrite())
+				return Boolean.TRUE.toString();
+		} else if (key.equals(IRemoteFileAttributes.HIDDEN_ATTRIBUTE)) {
+			if (file.isHidden())
+				return Boolean.TRUE.toString();
+		} else if (key.equals(IRemoteFileAttributes.EXEC_ATTRIBUTE)) {
+			return Boolean.TRUE.toString();
+		} else if (key.equals(IRemoteFileAttributes.ARCHIVE_ATTRIBUTE)) {
+			return Boolean.TRUE.toString();
+		}
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ecf.filetransfer.IRemoteFileAttributes#getAttributeKeys()
+	 */
+	public Iterator getAttributeKeys() {
+		return attributeKeys.iterator();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ecf.filetransfer.IRemoteFileAttributes#setAttribute(java.lang.String, java.lang.String)
+	 */
+	public void setAttribute(String key, String value) {
+		// not supported
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.Object#toString()
+	 */
+	public String toString() {
+		StringBuffer buf = new StringBuffer("LocalRemoteFileAttributes["); //$NON-NLS-1$
+		for (Iterator i = getAttributeKeys(); i.hasNext();) {
+			String key = (String) i.next();
+			buf.append(key).append("=").append(getAttribute(key)); //$NON-NLS-1$
+			buf.append(i.hasNext() ? ";" : "]"); //$NON-NLS-1$ //$NON-NLS-2$
+		}
+		return buf.toString();
+	}
+}
diff --git a/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/browse/MultiProtocolFileSystemBrowserAdapter.java b/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/browse/MultiProtocolFileSystemBrowserAdapter.java
new file mode 100644
index 0000000..49a5e7c
--- /dev/null
+++ b/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/browse/MultiProtocolFileSystemBrowserAdapter.java
@@ -0,0 +1,110 @@
+/****************************************************************************
+ * Copyright (c) 2004, 2007 Composent, Inc. 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:
+ *    Composent, Inc. - initial API and implementation
+ *****************************************************************************/
+
+package org.eclipse.ecf.provider.filetransfer.browse;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IAdapterManager;
+import org.eclipse.ecf.core.identity.IDFactory;
+import org.eclipse.ecf.core.identity.Namespace;
+import org.eclipse.ecf.core.security.IConnectContext;
+import org.eclipse.ecf.core.util.Proxy;
+import org.eclipse.ecf.filetransfer.IRemoteFileSystemBrowserContainerAdapter;
+import org.eclipse.ecf.filetransfer.IRemoteFileSystemListener;
+import org.eclipse.ecf.filetransfer.IRemoteFileSystemRequest;
+import org.eclipse.ecf.filetransfer.RemoteFileSystemException;
+import org.eclipse.ecf.filetransfer.identity.IFileID;
+import org.eclipse.ecf.filetransfer.service.IRemoteFileSystemBrowser;
+import org.eclipse.ecf.internal.provider.filetransfer.Activator;
+import org.eclipse.ecf.internal.provider.filetransfer.Messages;
+import org.eclipse.ecf.provider.filetransfer.identity.FileTransferNamespace;
+
+/**
+ * Multi protocol handler for remote file system browser. 
+ */
+public class MultiProtocolFileSystemBrowserAdapter implements IRemoteFileSystemBrowser {
+
+	IConnectContext connectContext = null;
+	Proxy proxy = null;
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ecf.filetransfer.IRetrieveFileTransferContainerAdapter#setConnectContextForAuthentication(org.eclipse.ecf.core.security.IConnectContext)
+	 */
+	public void setConnectContextForAuthentication(IConnectContext connectContext) {
+		this.connectContext = connectContext;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ecf.filetransfer.IRetrieveFileTransferContainerAdapter#setProxy(org.eclipse.ecf.core.util.Proxy)
+	 */
+	public void setProxy(Proxy proxy) {
+		this.proxy = proxy;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ecf.filetransfer.IRemoteFileSystemBrowserContainerAdapter#getDirectoryNamespace()
+	 */
+	public Namespace getBrowseNamespace() {
+		return IDFactory.getDefault().getNamespaceByName(FileTransferNamespace.PROTOCOL);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ecf.filetransfer.IRemoteFileSystemBrowserContainerAdapter#sendDirectoryRequest(org.eclipse.ecf.filetransfer.identity.IFileID, org.eclipse.ecf.filetransfer.IRemoteFileSystemListener)
+	 */
+	public IRemoteFileSystemRequest sendBrowseRequest(IFileID directoryOrFileID, IRemoteFileSystemListener listener) throws RemoteFileSystemException {
+		Assert.isNotNull(directoryOrFileID);
+		Assert.isNotNull(listener);
+		URL url;
+		try {
+			url = directoryOrFileID.getURL();
+		} catch (final MalformedURLException e) {
+			throw new RemoteFileSystemException(Messages.AbstractRetrieveFileTransfer_MalformedURLException);
+		}
+
+		IRemoteFileSystemBrowserContainerAdapter fileSystemBrowser = null;
+		fileSystemBrowser = Activator.getDefault().getBrowseFileTransfer(url.getProtocol());
+
+		if (fileSystemBrowser == null) {
+			if (url.getProtocol().equalsIgnoreCase("file")) { //$NON-NLS-1$
+				LocalFileSystemBrowser fsb = new LocalFileSystemBrowser(directoryOrFileID, listener);
+				return fsb.sendBrowseRequest();
+			}
+			URLFileSystemBrowser ufsb = new URLFileSystemBrowser(directoryOrFileID, listener, url, connectContext, proxy);
+			return ufsb.sendBrowseRequest();
+		}
+
+		// Set connect context
+		fileSystemBrowser.setConnectContextForAuthentication(connectContext);
+		// Set Proxy
+		fileSystemBrowser.setProxy(proxy);
+
+		return fileSystemBrowser.sendBrowseRequest(directoryOrFileID, listener);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
+	 */
+	public Object getAdapter(Class adapter) {
+		if (adapter == null)
+			return null;
+		final IAdapterManager adapterManager = Activator.getDefault().getAdapterManager();
+		if (adapterManager == null)
+			return null;
+		return adapterManager.loadAdapter(this, adapter.getName());
+	}
+
+}
diff --git a/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/browse/URLFileSystemBrowser.java b/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/browse/URLFileSystemBrowser.java
index 406344b..1d604c1 100644
--- a/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/browse/URLFileSystemBrowser.java
+++ b/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/browse/URLFileSystemBrowser.java
@@ -13,16 +13,26 @@
 
 import java.io.IOException;
 import java.io.InputStream;
-import java.net.*;
+import java.net.Authenticator;
+import java.net.PasswordAuthentication;
+import java.net.URL;
+import java.net.URLConnection;
 import org.eclipse.core.net.proxy.IProxyData;
 import org.eclipse.core.net.proxy.IProxyService;
-import org.eclipse.ecf.core.security.*;
+import org.eclipse.ecf.core.security.Callback;
+import org.eclipse.ecf.core.security.CallbackHandler;
+import org.eclipse.ecf.core.security.IConnectContext;
+import org.eclipse.ecf.core.security.NameCallback;
+import org.eclipse.ecf.core.security.ObjectCallback;
+import org.eclipse.ecf.core.security.UnsupportedCallbackException;
 import org.eclipse.ecf.core.util.Proxy;
 import org.eclipse.ecf.core.util.ProxyAddress;
 import org.eclipse.ecf.filetransfer.IRemoteFile;
 import org.eclipse.ecf.filetransfer.IRemoteFileSystemListener;
 import org.eclipse.ecf.filetransfer.identity.IFileID;
-import org.eclipse.ecf.internal.provider.filetransfer.*;
+import org.eclipse.ecf.internal.provider.filetransfer.Activator;
+import org.eclipse.ecf.internal.provider.filetransfer.IURLConnectionModifier;
+import org.eclipse.ecf.internal.provider.filetransfer.Messages;
 import org.eclipse.ecf.provider.filetransfer.util.JREProxyHelper;
 
 /**
diff --git a/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/browse/URLRemoteFile.java b/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/browse/URLRemoteFile.java
new file mode 100644
index 0000000..a64c87b
--- /dev/null
+++ b/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/browse/URLRemoteFile.java
@@ -0,0 +1,129 @@
+/****************************************************************************
+ * Copyright (c) 2008 Composent, Inc. 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:
+ *    Composent, Inc. - initial API and implementation
+ *****************************************************************************/
+
+package org.eclipse.ecf.provider.filetransfer.browse;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IAdapterManager;
+import org.eclipse.ecf.filetransfer.IRemoteFile;
+import org.eclipse.ecf.filetransfer.IRemoteFileAttributes;
+import org.eclipse.ecf.filetransfer.IRemoteFileInfo;
+import org.eclipse.ecf.filetransfer.identity.IFileID;
+import org.eclipse.ecf.internal.provider.filetransfer.Activator;
+
+/**
+ *
+ */
+public class URLRemoteFile implements IRemoteFile {
+
+	IFileID fileID;
+
+	URLConnection urlConnection;
+	IRemoteFileAttributes remoteFileAttributes;
+
+	public URLRemoteFile(URLConnection urlConnection, IFileID fileID) {
+		Assert.isNotNull(urlConnection);
+		this.urlConnection = urlConnection;
+		Assert.isNotNull(fileID);
+		this.fileID = fileID;
+		remoteFileAttributes = new URLRemoteFileAttributes();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ecf.filetransfer.IRemoteFile#getID()
+	 */
+	public IFileID getID() {
+		return fileID;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ecf.filetransfer.IRemoteFile#getInfo()
+	 */
+	public IRemoteFileInfo getInfo() {
+		return new IRemoteFileInfo() {
+
+			public IRemoteFileAttributes getAttributes() {
+				return remoteFileAttributes;
+			}
+
+			public long getLastModified() {
+				return urlConnection.getLastModified();
+			}
+
+			public long getLength() {
+				return urlConnection.getContentLength();
+			}
+
+			public String getName() {
+				URL url;
+				String result = null;
+				try {
+					url = fileID.getURL();
+					String path = url.getPath();
+					int index = path.lastIndexOf("/"); //$NON-NLS-1$
+					if (index == -1)
+						return path;
+					result = path.substring(index + 1);
+					return result;
+				} catch (MalformedURLException e) {
+					return fileID.getName();
+				}
+			}
+
+			public boolean isDirectory() {
+				try {
+					return fileID.getURL().toString().endsWith("/"); //$NON-NLS-1$
+				} catch (MalformedURLException e) {
+					return false;
+				}
+			}
+
+			public void setAttributes(IRemoteFileAttributes attributes) {
+				// Not supported
+			}
+
+			public void setLastModified(long time) {
+				// not supported
+			}
+
+			public void setName(String name) {
+				// not supported
+			}
+		};
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
+	 */
+	public Object getAdapter(Class adapter) {
+		IAdapterManager adapterManager = Activator.getDefault().getAdapterManager();
+		if (adapterManager == null)
+			return null;
+		return adapterManager.loadAdapter(this, adapter.getName());
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.Object#toString()
+	 */
+	public String toString() {
+		StringBuffer buf = new StringBuffer("URLRemoteFile["); //$NON-NLS-1$
+		buf.append("id=").append(getID()).append(";"); //$NON-NLS-1$//$NON-NLS-2$
+		buf.append("name=").append(getInfo().getName()).append(";"); //$NON-NLS-1$ //$NON-NLS-2$
+		buf.append("isDir=").append(getInfo().isDirectory()).append(";"); //$NON-NLS-1$ //$NON-NLS-2$
+		buf.append("length=").append(getInfo().getLength()).append(";"); //$NON-NLS-1$ //$NON-NLS-2$
+		buf.append("lastMod=").append(getInfo().getLastModified()).append(";"); //$NON-NLS-1$ //$NON-NLS-2$
+		buf.append("attr=").append(getInfo().getAttributes()).append("]"); //$NON-NLS-1$ //$NON-NLS-2$
+		return buf.toString();
+	}
+}
diff --git a/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/browse/URLRemoteFileAttributes.java b/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/browse/URLRemoteFileAttributes.java
new file mode 100644
index 0000000..95741eb
--- /dev/null
+++ b/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/browse/URLRemoteFileAttributes.java
@@ -0,0 +1,75 @@
+/****************************************************************************
+ * Copyright (c) 2008 Composent, Inc. 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:
+ *    Composent, Inc. - initial API and implementation
+ *****************************************************************************/
+
+package org.eclipse.ecf.provider.filetransfer.browse;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import org.eclipse.ecf.filetransfer.IRemoteFileAttributes;
+
+/**
+ *
+ */
+public class URLRemoteFileAttributes implements IRemoteFileAttributes {
+
+	static String[] fileAttributes = {IRemoteFileAttributes.READ_ATTRIBUTE, IRemoteFileAttributes.WRITE_ATTRIBUTE, IRemoteFileAttributes.HIDDEN_ATTRIBUTE, IRemoteFileAttributes.EXEC_ATTRIBUTE, IRemoteFileAttributes.ARCHIVE_ATTRIBUTE};
+	static List attributeKeys = new ArrayList(Arrays.asList(fileAttributes));
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ecf.filetransfer.IRemoteFileAttributes#getAttribute(java.lang.String)
+	 */
+	public String getAttribute(String key) {
+		if (key == null)
+			return null;
+		if (key.equals(IRemoteFileAttributes.READ_ATTRIBUTE)) {
+			return Boolean.TRUE.toString();
+		} else if (key.equals(IRemoteFileAttributes.WRITE_ATTRIBUTE)) {
+			return Boolean.FALSE.toString();
+		} else if (key.equals(IRemoteFileAttributes.HIDDEN_ATTRIBUTE)) {
+			return Boolean.FALSE.toString();
+		} else if (key.equals(IRemoteFileAttributes.EXEC_ATTRIBUTE)) {
+			return Boolean.FALSE.toString();
+		} else if (key.equals(IRemoteFileAttributes.ARCHIVE_ATTRIBUTE)) {
+			return Boolean.TRUE.toString();
+		}
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ecf.filetransfer.IRemoteFileAttributes#getAttributeKeys()
+	 */
+	public Iterator getAttributeKeys() {
+		return attributeKeys.iterator();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ecf.filetransfer.IRemoteFileAttributes#setAttribute(java.lang.String, java.lang.String)
+	 */
+	public void setAttribute(String key, String value) {
+		//
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.Object#toString()
+	 */
+	public String toString() {
+		StringBuffer buf = new StringBuffer("URLRemoteFileAttributes["); //$NON-NLS-1$
+		for (Iterator i = getAttributeKeys(); i.hasNext();) {
+			String key = (String) i.next();
+			buf.append(key).append("=").append(getAttribute(key)); //$NON-NLS-1$
+			buf.append(i.hasNext() ? ";" : "]"); //$NON-NLS-1$ //$NON-NLS-2$
+		}
+		return buf.toString();
+	}
+
+}
diff --git a/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/identity/FileTransferNamespace.java b/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/identity/FileTransferNamespace.java
new file mode 100644
index 0000000..cc1cede
--- /dev/null
+++ b/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/identity/FileTransferNamespace.java
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Composent, Inc. 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: Composent, Inc. - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.ecf.provider.filetransfer.identity;
+
+import java.net.URL;
+import java.util.HashSet;
+import java.util.Set;
+import org.eclipse.ecf.core.identity.ID;
+import org.eclipse.ecf.core.identity.IDCreateException;
+import org.eclipse.ecf.core.identity.Namespace;
+import org.eclipse.ecf.internal.provider.filetransfer.Activator;
+import org.eclipse.ecf.internal.provider.filetransfer.Messages;
+
+/**
+ * URL file namespace class. This defines a namespace that understands how to
+ * create IFileID instances from arbitary URLs
+ */
+public class FileTransferNamespace extends Namespace {
+
+	private static final long serialVersionUID = 8204058147686930765L;
+
+	public static final String PROTOCOL = Messages.FileTransferNamespace_Namespace_Protocol;
+
+	private String getInitFromExternalForm(Object[] args) {
+		if (args == null || args.length < 1 || args[0] == null)
+			return null;
+		if (args[0] instanceof String) {
+			String arg = (String) args[0];
+			if (arg.startsWith(getScheme() + Namespace.SCHEME_SEPARATOR)) {
+				int index = arg.indexOf(Namespace.SCHEME_SEPARATOR);
+				if (index >= arg.length())
+					return null;
+				return arg.substring(index + 1);
+			}
+		}
+		return null;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ecf.core.identity.Namespace#createInstance(java.lang.Object[])
+	 */
+	public ID createInstance(Object[] args) throws IDCreateException {
+		try {
+			String init = getInitFromExternalForm(args);
+			if (init != null)
+				return new FileTransferID(this, new URL(init));
+			if (args[0] instanceof URL)
+				return new FileTransferID(this, (URL) args[0]);
+			if (args[0] instanceof String)
+				return new FileTransferID(this, new URL((String) args[0]));
+		} catch (Exception e) {
+			throw new IDCreateException(Messages.FileTransferNamespace_Exception_Create_Instance, e);
+		}
+		throw new IDCreateException(Messages.FileTransferNamespace_Exception_Create_Instance_Failed);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ecf.core.identity.Namespace#getSupportedSchemes()
+	 */
+	public String[] getSupportedSchemes() {
+		Set result = new HashSet();
+		String[] platformSchemes = Activator.getDefault().getPlatformSupportedSchemes();
+		for (int i = 0; i < platformSchemes.length; i++)
+			result.add(platformSchemes[i]);
+		return (String[]) result.toArray(new String[] {});
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ecf.core.identity.Namespace#getScheme()
+	 */
+	public String getScheme() {
+		return PROTOCOL;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ecf.core.identity.Namespace#getSupportedParameterTypesForCreateInstance()
+	 */
+	public Class[][] getSupportedParameterTypes() {
+		return new Class[][] { {URL.class}, {String.class}};
+	}
+
+}
diff --git a/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/outgoing/AbstractOutgoingFileTransfer.java b/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/outgoing/AbstractOutgoingFileTransfer.java
new file mode 100644
index 0000000..254f557
--- /dev/null
+++ b/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/outgoing/AbstractOutgoingFileTransfer.java
@@ -0,0 +1,456 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Composent, Inc. 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: Composent, Inc. - initial API and implementation
+ *               Cloudsmith, Inc. - additional API and implementation
+ ******************************************************************************/
+package org.eclipse.ecf.provider.filetransfer.outgoing;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Map;
+import org.eclipse.core.net.proxy.IProxyData;
+import org.eclipse.core.net.proxy.IProxyService;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IAdapterManager;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.ecf.core.identity.ID;
+import org.eclipse.ecf.core.identity.IDFactory;
+import org.eclipse.ecf.core.identity.Namespace;
+import org.eclipse.ecf.core.security.IConnectContext;
+import org.eclipse.ecf.core.util.Proxy;
+import org.eclipse.ecf.core.util.ProxyAddress;
+import org.eclipse.ecf.filetransfer.FileTransferInfo;
+import org.eclipse.ecf.filetransfer.FileTransferJob;
+import org.eclipse.ecf.filetransfer.IFileTransferInfo;
+import org.eclipse.ecf.filetransfer.IFileTransferListener;
+import org.eclipse.ecf.filetransfer.IFileTransferRunnable;
+import org.eclipse.ecf.filetransfer.IIncomingFileTransferRequestListener;
+import org.eclipse.ecf.filetransfer.IOutgoingFileTransfer;
+import org.eclipse.ecf.filetransfer.SendFileTransferException;
+import org.eclipse.ecf.filetransfer.UserCancelledException;
+import org.eclipse.ecf.filetransfer.events.IOutgoingFileTransferResponseEvent;
+import org.eclipse.ecf.filetransfer.events.IOutgoingFileTransferSendDataEvent;
+import org.eclipse.ecf.filetransfer.events.IOutgoingFileTransferSendDoneEvent;
+import org.eclipse.ecf.filetransfer.identity.IFileID;
+import org.eclipse.ecf.filetransfer.service.ISendFileTransfer;
+import org.eclipse.ecf.internal.provider.filetransfer.Activator;
+import org.eclipse.ecf.internal.provider.filetransfer.Messages;
+import org.eclipse.ecf.provider.filetransfer.identity.FileTransferNamespace;
+import org.eclipse.osgi.util.NLS;
+
+/**
+ *
+ */
+public abstract class AbstractOutgoingFileTransfer implements IOutgoingFileTransfer, ISendFileTransfer {
+
+	public static final int DEFAULT_BUF_LENGTH = 4096;
+
+	private static final int FILETRANSFER_ERRORCODE = 1001;
+
+	protected Job job;
+
+	protected URL remoteFileURL;
+
+	protected IFileID remoteFileID;
+
+	protected IFileTransferListener listener;
+
+	protected int buff_length = DEFAULT_BUF_LENGTH;
+
+	protected boolean done = false;
+
+	protected long bytesSent = 0;
+
+	protected InputStream localFileContents;
+
+	protected OutputStream remoteFileContents;
+
+	protected Exception exception;
+
+	protected IFileTransferInfo fileTransferInfo;
+
+	protected Map options = null;
+
+	protected IConnectContext connectContext;
+
+	protected Proxy proxy;
+
+	private final IFileTransferRunnable fileTransferRunnable = new IFileTransferRunnable() {
+		public IStatus performFileTransfer(IProgressMonitor monitor) {
+			final byte[] buf = new byte[buff_length];
+			final long totalWork = ((fileTransferInfo.getFileSize() == -1) ? 100 : fileTransferInfo.getFileSize());
+			double factor = (totalWork > Integer.MAX_VALUE) ? (((double) Integer.MAX_VALUE) / ((double) totalWork)) : 1.0;
+			int work = (totalWork > Integer.MAX_VALUE) ? Integer.MAX_VALUE : (int) totalWork;
+			monitor.beginTask(getRemoteFileURL().toString() + Messages.AbstractOutgoingFileTransfer_Progress_Data, work);
+			try {
+				while (!isDone()) {
+					if (monitor.isCanceled())
+						throw new UserCancelledException(Messages.AbstractOutgoingFileTransfer_Exception_User_Cancelled);
+					final int bytes = localFileContents.read(buf);
+					if (bytes != -1) {
+						bytesSent += bytes;
+						remoteFileContents.write(buf, 0, bytes);
+						fireTransferSendDataEvent();
+						monitor.worked((int) Math.round(factor * bytes));
+					} else {
+						done = true;
+					}
+				}
+			} catch (final Exception e) {
+				exception = e;
+				done = true;
+			} finally {
+				hardClose();
+				monitor.done();
+				try {
+					fireTransferSendDoneEvent();
+				} catch (Exception e) {
+					Activator.getDefault().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, Messages.AbstractOutgoingFileTransfer_EXCEPTION_IN_FINALLY, e));
+				}
+			}
+			return getFinalStatus(exception);
+		}
+	};
+
+	FileTransferJob fileTransferJob;
+
+	protected URL getRemoteFileURL() {
+		return remoteFileURL;
+	}
+
+	protected void setInputStream(InputStream ins) {
+		localFileContents = ins;
+	}
+
+	protected void setOutputStream(OutputStream outs) {
+		remoteFileContents = outs;
+	}
+
+	protected IFileTransferInfo getFileTransferInfo() {
+		return fileTransferInfo;
+	}
+
+	protected Map getOptions() {
+		return options;
+	}
+
+	public AbstractOutgoingFileTransfer() {
+		//
+	}
+
+	protected IStatus getFinalStatus(Throwable exception1) {
+		if (exception1 == null)
+			return new Status(IStatus.OK, Activator.getDefault().getBundle().getSymbolicName(), 0, Messages.AbstractOutgoingFileTransfer_Status_Transfer_Completed_OK, null);
+		else if (exception1 instanceof UserCancelledException)
+			return new Status(IStatus.CANCEL, Activator.PLUGIN_ID, FILETRANSFER_ERRORCODE, Messages.AbstractOutgoingFileTransfer_Exception_User_Cancelled, exception1);
+		else
+			return new Status(IStatus.ERROR, Activator.PLUGIN_ID, FILETRANSFER_ERRORCODE, Messages.AbstractOutgoingFileTransfer_Status_Transfer_Exception, exception1);
+	}
+
+	protected void hardClose() {
+		try {
+			if (remoteFileContents != null)
+				remoteFileContents.close();
+		} catch (final IOException e) {
+			Activator.getDefault().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, "hardClose", e)); //$NON-NLS-1$
+		}
+		try {
+			if (localFileContents != null)
+				localFileContents.close();
+		} catch (final IOException e) {
+			Activator.getDefault().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, "hardClose", e)); //$NON-NLS-1$
+		}
+		job = null;
+		remoteFileContents = null;
+		localFileContents = null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ecf.core.identity.IIdentifiable#getID()
+	 */
+	public ID getID() {
+		return remoteFileID;
+	}
+
+	protected void fireTransferSendDoneEvent() {
+		listener.handleTransferEvent(new IOutgoingFileTransferSendDoneEvent() {
+
+			private static final long serialVersionUID = -2686266564645210722L;
+
+			public IOutgoingFileTransfer getSource() {
+				return AbstractOutgoingFileTransfer.this;
+			}
+
+			public Exception getException() {
+				return AbstractOutgoingFileTransfer.this.getException();
+			}
+
+			public String toString() {
+				final StringBuffer sb = new StringBuffer("IOutgoingFileTransferSendDoneEvent["); //$NON-NLS-1$
+				sb.append("bytesSent=").append(bytesSent) //$NON-NLS-1$
+						.append(";fileLength=").append(fileTransferInfo.getFileSize()).append(";exception=").append(getException()) //$NON-NLS-1$ //$NON-NLS-2$
+						.append("]"); //$NON-NLS-1$
+				return sb.toString();
+			}
+		});
+	}
+
+	protected void fireTransferSendDataEvent() {
+		listener.handleTransferEvent(new IOutgoingFileTransferSendDataEvent() {
+
+			private static final long serialVersionUID = -2916500675859842392L;
+
+			public IOutgoingFileTransfer getSource() {
+				return AbstractOutgoingFileTransfer.this;
+			}
+
+			public String toString() {
+				final StringBuffer sb = new StringBuffer("IOutgoingFileTransferSendDataEvent["); //$NON-NLS-1$
+				sb.append("bytesSent=").append(bytesSent) //$NON-NLS-1$
+						.append(";fileLength=").append(fileTransferInfo.getFileSize()) //$NON-NLS-1$ 
+						.append("]"); //$NON-NLS-1$
+				return sb.toString();
+			}
+		});
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ecf.filetransfer.IOutgoingFileTransfer#getBytesSent()
+	 */
+	public long getBytesSent() {
+		return bytesSent;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ecf.filetransfer.IFileTransfer#cancel()
+	 */
+	public void cancel() {
+		if (job != null)
+			job.cancel();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ecf.filetransfer.IFileTransfer#getException()
+	 */
+	public Exception getException() {
+		return exception;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ecf.filetransfer.IFileTransfer#getPercentComplete()
+	 */
+	public double getPercentComplete() {
+		long fileLength = getFileLength();
+		if (fileLength == -1 || fileLength == 0)
+			return fileLength;
+		return ((double) bytesSent / (double) fileLength);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ecf.filetransfer.IFileTransfer#getFileLength()
+	 */
+	public long getFileLength() {
+		return fileTransferInfo.getFileSize();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ecf.filetransfer.IFileTransfer#isDone()
+	 */
+	public boolean isDone() {
+		return done;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
+	 */
+	public Object getAdapter(Class adapter) {
+		if (adapter == null)
+			return null;
+		if (adapter.isInstance(this)) {
+			return this;
+		}
+		final IAdapterManager adapterManager = Activator.getDefault().getAdapterManager();
+		return (adapterManager == null) ? null : adapterManager.loadAdapter(this, adapter.getName());
+	}
+
+	/**
+	 * Open incoming and outgoing streams associated with this file transfer.
+	 * Subclasses must implement this method to open input and output streams.
+	 * The <code>remoteFileContents</code> and <code>localFileContent</code>
+	 * must be non-<code>null</code> after successful completion of the
+	 * implementation of this method.
+	 * 
+	 * @throws SendFileTransferException
+	 */
+	protected abstract void openStreams() throws SendFileTransferException;
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ecf.filetransfer.ISendFileTransferContainerAdapter#getOutgoingNamespace()
+	 */
+	public Namespace getOutgoingNamespace() {
+		return IDFactory.getDefault().getNamespaceByName(FileTransferNamespace.PROTOCOL);
+	}
+
+	public IFileTransferListener getListener() {
+		return listener;
+	}
+
+	protected String createJobName() {
+		return getRemoteFileURL().toString();
+	}
+
+	protected void setupAndScheduleJob() {
+		if (fileTransferJob == null)
+			fileTransferJob = new FileTransferJob(createJobName());
+		fileTransferJob.setFileTransferRunnable(fileTransferRunnable);
+		job = fileTransferJob;
+		job.schedule();
+	}
+
+	protected void fireSendStartEvent() {
+		listener.handleTransferEvent(new IOutgoingFileTransferResponseEvent() {
+
+			private static final long serialVersionUID = 2171381825030082432L;
+
+			public String toString() {
+				final StringBuffer sb = new StringBuffer("IOutgoingFileTransferResponseEvent["); //$NON-NLS-1$
+				sb.append("isdone=").append(done).append(";"); //$NON-NLS-1$ //$NON-NLS-2$
+				sb.append("bytesSent=").append(bytesSent) //$NON-NLS-1$
+						.append("]"); //$NON-NLS-1$
+				return sb.toString();
+			}
+
+			/* (non-Javadoc)
+			 * @see org.eclipse.ecf.filetransfer.events.IOutgoingFileTransferResponseEvent#requestAccepted()
+			 */
+			public boolean requestAccepted() {
+				return true;
+			}
+
+			/* (non-Javadoc)
+			 * @see org.eclipse.ecf.filetransfer.events.IOutgoingFileTransferEvent#getSource()
+			 */
+			public IOutgoingFileTransfer getSource() {
+				return AbstractOutgoingFileTransfer.this;
+			}
+
+			/* (non-Javadoc)
+			 * @see org.eclipse.ecf.filetransfer.events.IOutgoingFileTransferResponseEvent#setFileTransferJob(org.eclipse.ecf.filetransfer.FileTransferJob)
+			 */
+			public void setFileTransferJob(org.eclipse.ecf.filetransfer.FileTransferJob ftj) {
+				AbstractOutgoingFileTransfer.this.fileTransferJob = ftj;
+			}
+
+		});
+	}
+
+	protected abstract void setupProxy(Proxy proxy);
+
+	protected void setupProxies() {
+		// If it's been set directly (via ECF API) then this overrides platform settings
+		if (proxy == null) {
+			try {
+				IProxyService proxyService = Activator.getDefault().getProxyService();
+				// Only do this if platform service exists
+				if (proxyService != null && proxyService.isProxiesEnabled()) {
+					// Setup via proxyService entry
+					URL target = getRemoteFileURL();
+					String type = IProxyData.SOCKS_PROXY_TYPE;
+					if (target.getProtocol().equalsIgnoreCase(IProxyData.HTTP_PROXY_TYPE)) {
+						type = IProxyData.HTTP_PROXY_TYPE;
+					} else if (target.getProtocol().equalsIgnoreCase(IProxyData.HTTPS_PROXY_TYPE)) {
+						type = IProxyData.HTTPS_PROXY_TYPE;
+					}
+					final IProxyData proxyData = proxyService.getProxyDataForHost(target.getHost(), type);
+					if (proxyData != null) {
+						proxy = new Proxy(((type.equalsIgnoreCase(IProxyData.SOCKS_PROXY_TYPE)) ? Proxy.Type.SOCKS : Proxy.Type.HTTP), new ProxyAddress(proxyData.getHost(), proxyData.getPort()), proxyData.getUserId(), proxyData.getPassword());
+					}
+				}
+			} catch (Exception e) {
+				// If we don't even have the classes for this (i.e. the org.eclipse.core.net plugin not available)
+				// then we simply log and ignore
+				Activator.logNoProxyWarning(e);
+			} catch (NoClassDefFoundError e) {
+				Activator.logNoProxyWarning(e);
+			}
+		}
+		if (proxy != null)
+			setupProxy(proxy);
+
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ecf.filetransfer.ISendFileTransferContainerAdapter#sendOutgoingRequest(org.eclipse.ecf.filetransfer.identity.IFileID, org.eclipse.ecf.filetransfer.IFileTransferInfo, org.eclipse.ecf.filetransfer.IFileTransferListener, java.util.Map)
+	 */
+	public void sendOutgoingRequest(IFileID targetReceiver, IFileTransferInfo localFileToSend, IFileTransferListener transferListener, Map ops) throws SendFileTransferException {
+		Assert.isNotNull(targetReceiver, Messages.AbstractOutgoingFileTransfer_RemoteFileID_Not_Null);
+		Assert.isNotNull(transferListener, Messages.AbstractOutgoingFileTransfer_TransferListener_Not_Null);
+		Assert.isNotNull(localFileToSend, Messages.AbstractOutgoingFileTransfer_EXCEPTION_FILE_TRANSFER_INFO_NOT_NULL);
+		this.done = false;
+		this.bytesSent = 0;
+		this.exception = null;
+		this.fileTransferInfo = localFileToSend;
+		this.remoteFileID = targetReceiver;
+		this.options = ops;
+
+		try {
+			this.remoteFileURL = targetReceiver.getURL();
+		} catch (final MalformedURLException e) {
+			throw new SendFileTransferException(NLS.bind(Messages.AbstractOutgoingFileTransfer_MalformedURLException, targetReceiver), e);
+		}
+		this.listener = transferListener;
+		setupProxies();
+		openStreams();
+		fireSendStartEvent();
+		setupAndScheduleJob();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ecf.filetransfer.ISendFileTransferContainerAdapter#sendOutgoingRequest(org.eclipse.ecf.filetransfer.identity.IFileID, java.io.File, org.eclipse.ecf.filetransfer.IFileTransferListener, java.util.Map)
+	 */
+	public void sendOutgoingRequest(IFileID targetReceiver, final File localFileToSend, IFileTransferListener transferListener, Map ops) throws SendFileTransferException {
+		sendOutgoingRequest(targetReceiver, new FileTransferInfo(localFileToSend, null, null), transferListener, ops);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ecf.filetransfer.ISendFileTransferContainerAdapter#addListener(org.eclipse.ecf.filetransfer.IIncomingFileTransferRequestListener)
+	 */
+	public void addListener(IIncomingFileTransferRequestListener l) {
+		// Not needed
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ecf.filetransfer.ISendFileTransferContainerAdapter#removeListener(org.eclipse.ecf.filetransfer.IIncomingFileTransferRequestListener)
+	 */
+	public boolean removeListener(IIncomingFileTransferRequestListener l) {
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ecf.filetransfer.ISendFileTransferContainerAdapter#setConnectContextForAuthentication(org.eclipse.ecf.core.security.IConnectContext)
+	 */
+	public void setConnectContextForAuthentication(IConnectContext connectContext) {
+		this.connectContext = connectContext;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ecf.filetransfer.ISendFileTransferContainerAdapter#setProxy(org.eclipse.ecf.core.util.Proxy)
+	 */
+	public void setProxy(Proxy proxy) {
+		this.proxy = proxy;
+	}
+
+}
diff --git a/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/outgoing/AbstractUrlConnectionOutgoingFileTransfer.java b/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/outgoing/AbstractUrlConnectionOutgoingFileTransfer.java
new file mode 100644
index 0000000..1d5b085
--- /dev/null
+++ b/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/outgoing/AbstractUrlConnectionOutgoingFileTransfer.java
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * Copyright (c) 2004 Composent, Inc. 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: Composent, Inc. - initial API and implementation
+ *               Cloudsmith, Inc. - additional API and implementation
+ ******************************************************************************/
+package org.eclipse.ecf.provider.filetransfer.outgoing;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.net.ProtocolException;
+import java.net.URLConnection;
+import org.eclipse.ecf.core.util.Proxy;
+import org.eclipse.ecf.filetransfer.SendFileTransferException;
+import org.eclipse.ecf.filetransfer.service.ISendFileTransfer;
+import org.eclipse.ecf.internal.provider.filetransfer.Messages;
+import org.eclipse.ecf.provider.filetransfer.util.JREProxyHelper;
+import org.eclipse.osgi.util.NLS;
+
+public abstract class AbstractUrlConnectionOutgoingFileTransfer extends AbstractOutgoingFileTransfer implements ISendFileTransfer {
+
+	private static final int OK_RESPONSE_CODE = 200;
+
+	protected URLConnection urlConnection;
+
+	protected long lastModifiedTime = 0L;
+
+	protected int httpVersion = 1;
+
+	protected int responseCode = -1;
+
+	protected String responseMessage = null;
+
+	private JREProxyHelper proxyHelper = null;
+
+	public AbstractUrlConnectionOutgoingFileTransfer() {
+		super();
+		proxyHelper = new JREProxyHelper();
+	}
+
+	/**
+	 * Setup and connect.  Subclasses should override as appropriate.  After calling is complete,
+	 * the <code>urlConnection</code> member variable should be non-null, and ready to have it's
+	 * getInputStream() method called.
+	 * 
+	 * @throws IOException if the connection cannot be opened.
+	 */
+	protected abstract void connect() throws IOException;
+
+	protected boolean isConnected() {
+		return (urlConnection != null);
+	}
+
+	public int getResponseCode() {
+		if (responseCode != -1)
+			return responseCode;
+		if (isHTTP()) {
+			final String response = urlConnection.getHeaderField(0);
+			if (response == null) {
+				responseCode = -1;
+				httpVersion = 1;
+				return responseCode;
+			}
+			if (response == null || !response.startsWith("HTTP/")) //$NON-NLS-1$
+				return -1;
+			response.trim();
+			final int mark = response.indexOf(" ") + 1; //$NON-NLS-1$
+			if (mark == 0)
+				return -1;
+			if (response.charAt(mark - 2) != '1')
+				httpVersion = 0;
+			int last = mark + 3;
+			if (last > response.length())
+				last = response.length();
+			responseCode = Integer.parseInt(response.substring(mark, last));
+			if (last + 1 <= response.length())
+				responseMessage = response.substring(last + 1);
+		} else {
+			responseCode = OK_RESPONSE_CODE;
+			responseMessage = "OK"; //$NON-NLS-1$
+		}
+
+		return responseCode;
+
+	}
+
+	private boolean isHTTP() {
+		final String protocol = getRemoteFileURL().getProtocol();
+		if (protocol.equalsIgnoreCase("http") || protocol.equalsIgnoreCase("https")) //$NON-NLS-1$ //$NON-NLS-2$
+			return true;
+		return false;
+	}
+
+	/**
+	 * @param proxy2 the ECF proxy to setup
+	 */
+	protected void setupProxy(final Proxy proxy2) {
+		proxyHelper.setupProxy(proxy2);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ecf.provider.filetransfer.retrieve.AbstractRetrieveFileTransfer#openStreams()
+	 */
+	protected void openStreams() throws SendFileTransferException {
+		try {
+			File localFile = getFileTransferInfo().getFile();
+			// Set input stream from local file
+			setInputStream(new BufferedInputStream(new FileInputStream(localFile)));
+			// Then connect
+			connect();
+			// Make PUT request
+			setOutputStream(urlConnection.getOutputStream());
+		} catch (final Exception e) {
+			throw new SendFileTransferException(NLS.bind(Messages.UrlConnectionOutgoingFileTransfer_EXCEPTION_COULD_NOT_CONNECT, getRemoteFileURL().toString()), e);
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ecf.provider.filetransfer.retrieve.AbstractRetrieveFileTransfer#hardClose()
+	 */
+	protected void hardClose() {
+		super.hardClose();
+		int rCode = getResponseCode();
+		if (rCode != OK_RESPONSE_CODE) {
+			exception = new ProtocolException(NLS.bind("{0} {1}", new Integer(rCode), responseMessage)); //$NON-NLS-1$
+		}
+		urlConnection = null;
+		if (proxyHelper != null) {
+			proxyHelper.dispose();
+			proxyHelper = null;
+		}
+	}
+
+}
diff --git a/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/outgoing/LocalFileOutgoingFileTransfer.java b/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/outgoing/LocalFileOutgoingFileTransfer.java
new file mode 100644
index 0000000..f94e613
--- /dev/null
+++ b/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/outgoing/LocalFileOutgoingFileTransfer.java
@@ -0,0 +1,69 @@
+/****************************************************************************
+ * Copyright (c) 2007 Composent, Inc. 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:
+ *    Composent, Inc. - initial API and implementation
+ *               Cloudsmith, Inc. - additional API and implementation
+ *****************************************************************************/
+
+package org.eclipse.ecf.provider.filetransfer.outgoing;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.net.URL;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.ecf.core.util.Proxy;
+import org.eclipse.ecf.filetransfer.IFileTransferInfo;
+import org.eclipse.ecf.filetransfer.SendFileTransferException;
+import org.eclipse.ecf.internal.provider.filetransfer.Messages;
+import org.eclipse.osgi.util.NLS;
+
+/**
+ *
+ */
+public class LocalFileOutgoingFileTransfer extends AbstractOutgoingFileTransfer {
+
+	public LocalFileOutgoingFileTransfer() {
+		// not needed
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ecf.provider.filetransfer.outgoing.AbstractOutgoingFileTransfer#openStreams()
+	 */
+	protected void openStreams() throws SendFileTransferException {
+		IFileTransferInfo localFileTransferInfo = getFileTransferInfo();
+		Assert.isNotNull(localFileTransferInfo);
+		// Setup input file
+		File inputFile = localFileTransferInfo.getFile();
+		try {
+			setInputStream(new BufferedInputStream(new FileInputStream(inputFile)));
+		} catch (Exception e) {
+			hardClose();
+			throw new SendFileTransferException(NLS.bind(Messages.LocalFileOutgoingFileTransfer_EXCEPTION_OPENING_FOR_INPUT, inputFile));
+		}
+		URL url = getRemoteFileURL();
+		Assert.isNotNull(url);
+		try {
+			File outputFile = new File(url.getPath());
+			setOutputStream(new BufferedOutputStream(new FileOutputStream(outputFile)));
+		} catch (Exception e) {
+			hardClose();
+			throw new SendFileTransferException(NLS.bind(Messages.LocalFileOutgoingFileTransfer_EXCEPTION_OPENING_FOR_OUTPUT, url));
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ecf.provider.filetransfer.outgoing.AbstractOutgoingFileTransfer#setupProxy(org.eclipse.ecf.core.util.Proxy)
+	 */
+	protected void setupProxy(Proxy proxy) {
+		// No proxy for local file system
+	}
+
+}
diff --git a/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/outgoing/MultiProtocolOutgoingAdapter.java b/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/outgoing/MultiProtocolOutgoingAdapter.java
new file mode 100644
index 0000000..466038c
--- /dev/null
+++ b/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/outgoing/MultiProtocolOutgoingAdapter.java
@@ -0,0 +1,146 @@
+/****************************************************************************
+ * Copyright (c) 2004, 2007 Composent, Inc. 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:
+ *    Composent, Inc. - initial API and implementation
+ *****************************************************************************/
+
+package org.eclipse.ecf.provider.filetransfer.outgoing;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.util.Map;
+import org.eclipse.core.runtime.IAdapterManager;
+import org.eclipse.ecf.core.identity.IDFactory;
+import org.eclipse.ecf.core.identity.Namespace;
+import org.eclipse.ecf.core.security.IConnectContext;
+import org.eclipse.ecf.core.util.Proxy;
+import org.eclipse.ecf.filetransfer.IFileTransferInfo;
+import org.eclipse.ecf.filetransfer.IFileTransferListener;
+import org.eclipse.ecf.filetransfer.IIncomingFileTransferRequestListener;
+import org.eclipse.ecf.filetransfer.ISendFileTransferContainerAdapter;
+import org.eclipse.ecf.filetransfer.SendFileTransferException;
+import org.eclipse.ecf.filetransfer.identity.IFileID;
+import org.eclipse.ecf.filetransfer.service.ISendFileTransfer;
+import org.eclipse.ecf.internal.provider.filetransfer.Activator;
+import org.eclipse.ecf.internal.provider.filetransfer.Messages;
+import org.eclipse.ecf.provider.filetransfer.identity.FileTransferNamespace;
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Multi protocol handler for outgoing file transfer. Multiplexes between Apache
+ * httpclient 3.0.1-based file retriever and the URLConnection-based file
+ * retriever.
+ */
+public class MultiProtocolOutgoingAdapter implements ISendFileTransfer {
+
+	IConnectContext connectContext = null;
+	Proxy proxy = null;
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ecf.filetransfer.ISendFileTransferContainerAdapter#getOutgoingNamespace()
+	 */
+	public Namespace getOutgoingNamespace() {
+		return IDFactory.getDefault().getNamespaceByName(FileTransferNamespace.PROTOCOL);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ecf.filetransfer.IRetrieveFileTransferContainerAdapter#setConnectContextForAuthentication(org.eclipse.ecf.core.security.IConnectContext)
+	 */
+	public void setConnectContextForAuthentication(IConnectContext connectContext) {
+		this.connectContext = connectContext;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ecf.filetransfer.IRetrieveFileTransferContainerAdapter#setProxy(org.eclipse.ecf.core.util.Proxy)
+	 */
+	public void setProxy(Proxy proxy) {
+		this.proxy = proxy;
+	}
+
+	public void sendOutgoingRequest(IFileID targetID, File outgoingFile, IFileTransferListener transferListener, Map options) throws SendFileTransferException {
+		String protocol = null;
+		try {
+			protocol = targetID.getURL().getProtocol();
+		} catch (final MalformedURLException e) {
+			throw new SendFileTransferException(Messages.AbstractRetrieveFileTransfer_MalformedURLException);
+		}
+
+		ISendFileTransferContainerAdapter fileTransfer = null;
+		fileTransfer = Activator.getDefault().getSendFileTransfer(protocol);
+
+		// If no handler setup for this protocol then throw
+		if (fileTransfer == null) {
+			if (protocol.equalsIgnoreCase("file")) { //$NON-NLS-1$
+				fileTransfer = new LocalFileOutgoingFileTransfer();
+			}
+		}
+
+		if (fileTransfer == null) {
+			throw new SendFileTransferException(NLS.bind(Messages.MultiProtocolOutgoingAdapter_EXCEPTION_NO_PROTOCOL_HANDER, targetID));
+		}
+
+		fileTransfer.setConnectContextForAuthentication(connectContext);
+		fileTransfer.setProxy(proxy);
+		fileTransfer.sendOutgoingRequest(targetID, outgoingFile, transferListener, options);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ecf.filetransfer.ISendFileTransferContainerAdapter#addListener(org.eclipse.ecf.filetransfer.IIncomingFileTransferRequestListener)
+	 */
+	public void addListener(IIncomingFileTransferRequestListener listener) {
+		// We don't have any listeners
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ecf.filetransfer.ISendFileTransferContainerAdapter#removeListener(org.eclipse.ecf.filetransfer.IIncomingFileTransferRequestListener)
+	 */
+	public boolean removeListener(IIncomingFileTransferRequestListener listener) {
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ecf.filetransfer.ISendFileTransferContainerAdapter#sendOutgoingRequest(org.eclipse.ecf.filetransfer.identity.IFileID, org.eclipse.ecf.filetransfer.IFileTransferInfo, org.eclipse.ecf.filetransfer.IFileTransferListener, java.util.Map)
+	 */
+	public void sendOutgoingRequest(IFileID targetID, IFileTransferInfo localFileToSend, IFileTransferListener transferListener, Map options) throws SendFileTransferException {
+		String protocol = null;
+		try {
+			protocol = targetID.getURL().getProtocol();
+		} catch (final MalformedURLException e) {
+			throw new SendFileTransferException(Messages.AbstractRetrieveFileTransfer_MalformedURLException);
+		}
+
+		ISendFileTransferContainerAdapter fileTransfer = null;
+		fileTransfer = Activator.getDefault().getSendFileTransfer(protocol);
+
+		// If no handler setup for this protocol then throw
+		if (fileTransfer == null) {
+			throw new SendFileTransferException(NLS.bind(Messages.MultiProtocolOutgoingAdapter_EXCEPTION_NO_PROTOCOL_HANDER, targetID));
+		}
+
+		fileTransfer.setConnectContextForAuthentication(connectContext);
+		fileTransfer.setProxy(proxy);
+		fileTransfer.sendOutgoingRequest(targetID, localFileToSend, transferListener, options);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
+	 */
+	public Object getAdapter(Class adapter) {
+		if (adapter == null)
+			return null;
+		final IAdapterManager adapterManager = Activator.getDefault().getAdapterManager();
+		if (adapterManager == null)
+			return null;
+		return adapterManager.loadAdapter(this, adapter.getName());
+	}
+
+}
diff --git a/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/retrieve/AbstractRetrieveFileTransfer.java b/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/retrieve/AbstractRetrieveFileTransfer.java
new file mode 100644
index 0000000..6fbd703
--- /dev/null
+++ b/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/retrieve/AbstractRetrieveFileTransfer.java
@@ -0,0 +1,750 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 Composent, Inc. 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:
+ *    Composent, Inc. - initial API and implementation
+ *    Benjamin Cabe <benjamin.cabe@anyware-tech.com> - bug 220258
+ ******************************************************************************/
+package org.eclipse.ecf.provider.filetransfer.retrieve;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.text.DecimalFormat;
+import java.util.Date;
+import java.util.Map;
+import org.eclipse.core.net.proxy.IProxyData;
+import org.eclipse.core.net.proxy.IProxyService;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IAdapterManager;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.ecf.core.identity.ID;
+import org.eclipse.ecf.core.identity.IDFactory;
+import org.eclipse.ecf.core.identity.Namespace;
+import org.eclipse.ecf.core.security.IConnectContext;
+import org.eclipse.ecf.core.util.Proxy;
+import org.eclipse.ecf.core.util.ProxyAddress;
+import org.eclipse.ecf.filetransfer.FileTransferJob;
+import org.eclipse.ecf.filetransfer.IFileRangeSpecification;
+import org.eclipse.ecf.filetransfer.IFileTransferListener;
+import org.eclipse.ecf.filetransfer.IFileTransferPausable;
+import org.eclipse.ecf.filetransfer.IFileTransferRunnable;
+import org.eclipse.ecf.filetransfer.IIncomingFileTransfer;
+import org.eclipse.ecf.filetransfer.IncomingFileTransferException;
+import org.eclipse.ecf.filetransfer.UserCancelledException;
+import org.eclipse.ecf.filetransfer.events.IIncomingFileTransferReceiveDataEvent;
+import org.eclipse.ecf.filetransfer.events.IIncomingFileTransferReceiveDoneEvent;
+import org.eclipse.ecf.filetransfer.events.IIncomingFileTransferReceivePausedEvent;
+import org.eclipse.ecf.filetransfer.events.IIncomingFileTransferReceiveResumedEvent;
+import org.eclipse.ecf.filetransfer.events.IIncomingFileTransferReceiveStartEvent;
+import org.eclipse.ecf.filetransfer.identity.IFileID;
+import org.eclipse.ecf.filetransfer.service.IRetrieveFileTransfer;
+import org.eclipse.ecf.internal.provider.filetransfer.Activator;
+import org.eclipse.ecf.internal.provider.filetransfer.Messages;
+import org.eclipse.ecf.provider.filetransfer.identity.FileTransferNamespace;
+import org.eclipse.osgi.util.NLS;
+
+public abstract class AbstractRetrieveFileTransfer implements IIncomingFileTransfer, IRetrieveFileTransfer, IFileTransferPausable {
+
+	public static final int DEFAULT_BUF_LENGTH = 4096;
+
+	private static final int FILETRANSFER_ERRORCODE = 1001;
+
+	protected Job job;
+
+	protected URL remoteFileURL;
+
+	protected IFileID remoteFileID;
+
+	protected IFileTransferListener listener;
+
+	protected int buff_length = DEFAULT_BUF_LENGTH;
+
+	protected boolean done = false;
+
+	protected long bytesReceived = 0;
+
+	protected InputStream remoteFileContents;
+
+	protected OutputStream localFileContents;
+
+	protected boolean closeOutputStream = true;
+
+	protected Exception exception;
+
+	protected long fileLength = -1;
+
+	protected long lastModifiedTime = 0L;
+
+	protected Map options = null;
+
+	protected boolean paused = false;
+
+	protected IFileRangeSpecification rangeSpecification = null;
+
+	protected Proxy proxy;
+
+	protected IConnectContext connectContext;
+
+	protected long transferStartTime;
+
+	protected double downloadRateBytesPerSecond = 0L;
+
+	public AbstractRetrieveFileTransfer() {
+		//
+	}
+
+	private IFileTransferRunnable fileTransferRunnable = new IFileTransferRunnable() {
+		public IStatus performFileTransfer(IProgressMonitor monitor) {
+			transferStartTime = System.currentTimeMillis();
+			final byte[] buf = new byte[buff_length];
+			final long totalWork = ((fileLength == -1) ? 100 : fileLength);
+			double factor = (totalWork > Integer.MAX_VALUE) ? (((double) Integer.MAX_VALUE) / ((double) totalWork)) : 1.0;
+			int work = (totalWork > Integer.MAX_VALUE) ? Integer.MAX_VALUE : (int) totalWork;
+			monitor.beginTask(getRemoteFileURL().toString() + Messages.AbstractRetrieveFileTransfer_Progress_Data, work);
+			try {
+				while (!isDone() && !isPaused()) {
+					if (monitor.isCanceled())
+						throw new UserCancelledException(Messages.AbstractRetrieveFileTransfer_Exception_User_Cancelled);
+					final int bytes = remoteFileContents.read(buf);
+					handleReceivedData(buf, bytes, factor, monitor);
+				}
+			} catch (final Exception e) {
+				exception = e;
+				done = true;
+			} finally {
+				hardClose();
+				monitor.done();
+				try {
+					if (isPaused())
+						fireTransferReceivePausedEvent();
+					else
+						fireTransferReceiveDoneEvent();
+				} catch (Exception e) {
+					// simply log
+					Activator.getDefault().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, Messages.AbstractRetrieveFileTransfer_EXCEPTION_IN_FINALLY, e));
+				}
+			}
+			return getFinalStatus(exception);
+		}
+
+	};
+
+	protected URL getRemoteFileURL() {
+		return remoteFileURL;
+	}
+
+	protected void setInputStream(InputStream ins) {
+		remoteFileContents = ins;
+	}
+
+	protected void setOutputStream(OutputStream outs) {
+		localFileContents = outs;
+	}
+
+	protected void setCloseOutputStream(boolean close) {
+		closeOutputStream = close;
+	}
+
+	protected void setFileLength(long length) {
+		fileLength = length;
+	}
+
+	protected void setLastModifiedTime(long timestamp) {
+		lastModifiedTime = timestamp;
+	}
+
+	protected Map getOptions() {
+		return options;
+	}
+
+	protected void handleReceivedData(byte[] buf, int bytes, double factor, IProgressMonitor monitor) throws IOException {
+		if (bytes != -1) {
+			bytesReceived += bytes;
+			localFileContents.write(buf, 0, bytes);
+			downloadRateBytesPerSecond = (bytesReceived / ((System.currentTimeMillis() + 1 - transferStartTime) / 1000.0));
+			monitor.setTaskName(createJobName() + Messages.AbstractRetrieveFileTransfer_Progress_Data + NLS.bind(Messages.AbstractRetrieveFileTransfer_InfoTransferRate, toHumanReadableBytes(downloadRateBytesPerSecond)));
+			monitor.worked((int) Math.round(factor * bytes));
+			fireTransferReceiveDataEvent();
+		} else
+			done = true;
+	}
+
+	public static String toHumanReadableBytes(double size) {
+		double convertedSize;
+		String unit;
+
+		if (size / (1024 * 1024 * 1024) >= 1) {
+			convertedSize = size / (1024 * 1024 * 1024);
+			unit = Messages.AbstractRetrieveFileTransfer_SizeUnitGB;
+		} else if (size / (1024 * 1024) >= 1) {
+			convertedSize = size / (1024 * 1024);
+			unit = Messages.AbstractRetrieveFileTransfer_SizeUnitMB;
+		} else if (size / 1024 >= 1) {
+			convertedSize = size / 1024;
+			unit = Messages.AbstractRetrieveFileTransfer_SizeUnitKB;
+		} else {
+			convertedSize = size;
+			unit = Messages.AbstractRetrieveFileTransfer_SizeUnitBytes;
+		}
+
+		DecimalFormat df = new DecimalFormat(NLS.bind(Messages.AbstractRetrieveFileTransfer_TransferRateFormat, unit));
+		return df.format(convertedSize);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ecf.core.identity.IIdentifiable#getID()
+	 */
+	public ID getID() {
+		return remoteFileID;
+	}
+
+	protected IStatus getFinalStatus(Throwable exception1) {
+		if (exception1 == null)
+			return new Status(IStatus.OK, Activator.getDefault().getBundle().getSymbolicName(), 0, Messages.AbstractRetrieveFileTransfer_Status_Transfer_Completed_OK, null);
+		else if (exception1 instanceof UserCancelledException)
+			return new Status(IStatus.CANCEL, Activator.PLUGIN_ID, FILETRANSFER_ERRORCODE, Messages.AbstractRetrieveFileTransfer_Exception_User_Cancelled, exception1);
+		else
+			return new Status(IStatus.ERROR, Activator.PLUGIN_ID, FILETRANSFER_ERRORCODE, Messages.AbstractRetrieveFileTransfer_Status_Transfer_Exception, exception1);
+	}
+
+	protected void hardClose() {
+		try {
+			if (remoteFileContents != null)
+				remoteFileContents.close();
+		} catch (final IOException e) {
+			Activator.getDefault().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, "hardClose", e)); //$NON-NLS-1$
+		}
+		try {
+			if (localFileContents != null && closeOutputStream)
+				localFileContents.close();
+		} catch (final IOException e) {
+			Activator.getDefault().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, "hardClose", e)); //$NON-NLS-1$
+		}
+		job = null;
+		remoteFileContents = null;
+		localFileContents = null;
+	}
+
+	protected void fireTransferReceivePausedEvent() {
+		listener.handleTransferEvent(new IIncomingFileTransferReceivePausedEvent() {
+
+			private static final long serialVersionUID = -1317411290525985140L;
+
+			public IIncomingFileTransfer getSource() {
+				return AbstractRetrieveFileTransfer.this;
+			}
+
+			public String toString() {
+				final StringBuffer sb = new StringBuffer("IIncomingFileTransferReceivePausedEvent["); //$NON-NLS-1$
+				sb.append("bytesReceived=").append(bytesReceived) //$NON-NLS-1$
+						.append(";fileLength=").append(fileLength).append("]"); //$NON-NLS-1$ //$NON-NLS-2$
+				return sb.toString();
+			}
+		});
+	}
+
+	protected void fireTransferReceiveDoneEvent() {
+		listener.handleTransferEvent(new IIncomingFileTransferReceiveDoneEvent() {
+
+			private static final long serialVersionUID = 6925524078226825710L;
+
+			public IIncomingFileTransfer getSource() {
+				return AbstractRetrieveFileTransfer.this;
+			}
+
+			public Exception getException() {
+				return AbstractRetrieveFileTransfer.this.getException();
+			}
+
+			public String toString() {
+				final StringBuffer sb = new StringBuffer("IIncomingFileTransferReceiveDoneEvent["); //$NON-NLS-1$
+				sb.append("bytesReceived=").append(bytesReceived) //$NON-NLS-1$
+						.append(";fileLength=").append(fileLength).append(";exception=").append(getException()) //$NON-NLS-1$ //$NON-NLS-2$
+						.append("]"); //$NON-NLS-1$
+				return sb.toString();
+			}
+		});
+	}
+
+	protected void fireTransferReceiveDataEvent() {
+		listener.handleTransferEvent(new IIncomingFileTransferReceiveDataEvent() {
+			private static final long serialVersionUID = -5656328374614130161L;
+
+			public IIncomingFileTransfer getSource() {
+				return AbstractRetrieveFileTransfer.this;
+			}
+
+			public String toString() {
+				final StringBuffer sb = new StringBuffer("IIncomingFileTransferReceiveDataEvent["); //$NON-NLS-1$
+				sb.append("bytesReceived=").append(bytesReceived) //$NON-NLS-1$
+						.append(";fileLength=").append(fileLength) //$NON-NLS-1$ 
+						.append("]"); //$NON-NLS-1$
+				return sb.toString();
+			}
+		});
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ecf.filetransfer.IRetrieveFileTransferContainerAdapter#setConnectContextForAuthentication(org.eclipse.ecf.core.security.IConnectContext)
+	 */
+	public void setConnectContextForAuthentication(IConnectContext connectContext) {
+		this.connectContext = connectContext;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ecf.filetransfer.IRetrieveFileTransferContainerAdapter#setProxy(org.eclipse.ecf.core.util.Proxy)
+	 */
+	public void setProxy(Proxy proxy) {
+		this.proxy = proxy;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ecf.filetransfer.IIncomingFileTransfer#getBytesReceived()
+	 */
+	public long getBytesReceived() {
+		return bytesReceived;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ecf.filetransfer.IFileTransfer#cancel()
+	 */
+	public void cancel() {
+		if (isPaused()) {
+			done = true;
+			this.exception = new UserCancelledException(Messages.AbstractRetrieveFileTransfer_Exception_User_Cancelled);
+			fireTransferReceiveDoneEvent();
+		} else if (job != null)
+			job.cancel();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ecf.filetransfer.IFileTransfer#getException()
+	 */
+	public Exception getException() {
+		return exception;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ecf.filetransfer.IFileTransfer#getPercentComplete()
+	 */
+	public double getPercentComplete() {
+		if (fileLength == -1 || fileLength == 0)
+			return fileLength;
+		return ((double) bytesReceived / (double) fileLength);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ecf.filetransfer.IFileTransfer#getFileLength()
+	 */
+	public long getFileLength() {
+		return fileLength;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ecf.provider.filetransfer.retrieve.AbstractRetrieveFileTransfer#getRemoteLastModified()
+	 */
+	public Date getRemoteLastModified() {
+		return lastModifiedTime == 0L ? null : new Date(lastModifiedTime);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ecf.filetransfer.IFileTransfer#isDone()
+	 */
+	public boolean isDone() {
+		return done;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
+	 */
+	public Object getAdapter(Class adapter) {
+		if (adapter == null)
+			return null;
+		if (adapter.isInstance(this)) {
+			return this;
+		}
+		final IAdapterManager adapterManager = Activator.getDefault().getAdapterManager();
+		return (adapterManager == null) ? null : adapterManager.loadAdapter(this, adapter.getName());
+	}
+
+	/**
+	 * Open incoming and outgoing streams associated with this file transfer.
+	 * Subclasses must implement this method to open input and output streams.
+	 * The <code>remoteFileContents</code> and <code>localFileContent</code>
+	 * must be non-<code>null</code> after successful completion of the
+	 * implementation of this method.
+	 * 
+	 * @throws IncomingFileTransferException
+	 */
+	protected abstract void openStreams() throws IncomingFileTransferException;
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ecf.filetransfer.IRetrieveFileTransferContainerAdapter#sendRetrieveRequest(org.eclipse.ecf.filetransfer.identity.IFileID,
+	 *      org.eclipse.ecf.filetransfer.IFileTransferListener, java.util.Map)
+	 */
+	public void sendRetrieveRequest(final IFileID remoteFileID1, IFileTransferListener transferListener, Map options1) throws IncomingFileTransferException {
+		sendRetrieveRequest(remoteFileID1, null, transferListener, options1);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ecf.filetransfer.IRetrieveFileTransferContainerAdapter#getRetrieveNamespace()
+	 */
+	public Namespace getRetrieveNamespace() {
+		return IDFactory.getDefault().getNamespaceByName(FileTransferNamespace.PROTOCOL);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ecf.filetransfer.IFileTransferPausable#isPaused()
+	 */
+	public boolean isPaused() {
+		return paused;
+	}
+
+	/**
+	 * Subclass overridable version of {@link #pause()}. Subclasses must
+	 * provide an implementation of this method to support
+	 * {@link IFileTransferPausable}.
+	 * 
+	 * @return true if the pause is successful. <code>false</code> otherwise.
+	 */
+	protected abstract boolean doPause();
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ecf.filetransfer.IFileTransferPausable#pause()
+	 */
+	public boolean pause() {
+		return doPause();
+	}
+
+	/**
+	 * Subclass overridable version of {@link #resume()}. Subclasses must
+	 * provide an implementation of this method to support
+	 * {@link IFileTransferPausable}.
+	 * 
+	 * @return true if the resume is successful. <code>false</code> otherwise.
+	 */
+	protected abstract boolean doResume();
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ecf.filetransfer.IFileTransferPausable#resume()
+	 */
+	public boolean resume() {
+		return doResume();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ecf.filetransfer.IIncomingFileTransfer#getListener()
+	 */
+	public IFileTransferListener getListener() {
+		return listener;
+	}
+
+	protected String createRangeName() {
+		if (rangeSpecification == null)
+			return ""; //$NON-NLS-1$
+		return "[" + rangeSpecification.getStartPosition() + "," + rangeSpecification.getEndPosition() + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+	}
+
+	protected String createJobName() {
+		return getRemoteFileURL().toString() + createRangeName();
+	}
+
+	protected void setupAndScheduleJob(FileTransferJob fileTransferJob) {
+		if (fileTransferJob == null) {
+			// Create our own
+			fileTransferJob = new FileTransferJob(createJobName());
+		}
+		// Now set to our runnable
+		fileTransferJob.setFileTransferRunnable(fileTransferRunnable);
+		job = fileTransferJob;
+		job.schedule();
+	}
+
+	protected void fireReceiveStartEvent() {
+		listener.handleTransferEvent(new IIncomingFileTransferReceiveStartEvent() {
+			private static final long serialVersionUID = -513800598918052184L;
+
+			/* (non-Javadoc)
+			 * @see org.eclipse.ecf.filetransfer.events.IIncomingFileTransferEvent#getFileID()
+			 */
+			public IIncomingFileTransfer getSource() {
+				return AbstractRetrieveFileTransfer.this;
+			}
+
+			/* (non-Javadoc)
+			 * @see org.eclipse.ecf.filetransfer.events.IIncomingFileTransferReceiveStartEvent#getFileID()
+			 */
+			public IFileID getFileID() {
+				return remoteFileID;
+			}
+
+			/* (non-Javadoc)
+			 * @see org.eclipse.ecf.filetransfer.events.IIncomingFileTransferReceiveStartEvent#receive(java.io.File)
+			 */
+			public IIncomingFileTransfer receive(File localFileToSave) throws IOException {
+				return receive(localFileToSave, null);
+			}
+
+			/* (non-Javadoc)
+			 * @see org.eclipse.ecf.filetransfer.events.IIncomingFileTransferReceiveStartEvent#receive(java.io.File, org.eclipse.ecf.filetransfer.FileTransferJob)
+			 */
+			public IIncomingFileTransfer receive(File localFileToSave, FileTransferJob fileTransferJob) throws IOException {
+				setOutputStream(new BufferedOutputStream(new FileOutputStream(localFileToSave)));
+				setupAndScheduleJob(fileTransferJob);
+				return AbstractRetrieveFileTransfer.this;
+			}
+
+			/**
+			 * @param streamToStore
+			 * @return incoming file transfer instance.
+			 * @throws IOException not thrown in this implementation.
+			 */
+			public IIncomingFileTransfer receive(OutputStream streamToStore) throws IOException {
+				return receive(streamToStore, null);
+			}
+
+			/**
+			 * @throws IOException not actually thrown by this implementation.
+			 */
+			public IIncomingFileTransfer receive(OutputStream streamToStore, FileTransferJob fileTransferJob) throws IOException {
+				setOutputStream(streamToStore);
+				setCloseOutputStream(false);
+				setupAndScheduleJob(fileTransferJob);
+				return AbstractRetrieveFileTransfer.this;
+			}
+
+			/* (non-Javadoc)
+			 * @see org.eclipse.ecf.filetransfer.events.IIncomingFileTransferReceiveStartEvent#cancel()
+			 */
+			public void cancel() {
+				hardClose();
+			}
+
+			/* (non-Javadoc)
+			 * @see java.lang.Object#toString()
+			 */
+			public String toString() {
+				final StringBuffer sb = new StringBuffer("IIncomingFileTransferReceiveStartEvent["); //$NON-NLS-1$
+				sb.append("isdone=").append(done).append(";"); //$NON-NLS-1$ //$NON-NLS-2$
+				sb.append("bytesReceived=").append(bytesReceived) //$NON-NLS-1$
+						.append("]"); //$NON-NLS-1$
+				return sb.toString();
+			}
+
+		});
+	}
+
+	protected void fireReceiveResumedEvent() {
+		listener.handleTransferEvent(new IIncomingFileTransferReceiveResumedEvent() {
+
+			private static final long serialVersionUID = 7111739642849612839L;
+
+			/* (non-Javadoc)
+			 * @see org.eclipse.ecf.filetransfer.events.IIncomingFileTransferReceiveStartEvent#getFileID()
+			 */
+			public IFileID getFileID() {
+				return remoteFileID;
+			}
+
+			/* (non-Javadoc)
+			 * @see org.eclipse.ecf.filetransfer.events.IIncomingFileTransferReceiveStartEvent#receive(java.io.File)
+			 */
+			public IIncomingFileTransfer receive(File localFileToSave, boolean append) throws IOException {
+				return receive(localFileToSave, null, append);
+			}
+
+			/* (non-Javadoc)
+			 * @see org.eclipse.ecf.filetransfer.events.IIncomingFileTransferReceiveStartEvent#receive(java.io.File, org.eclipse.ecf.filetransfer.FileTransferJob)
+			 */
+			public IIncomingFileTransfer receive(File localFileToSave, FileTransferJob fileTransferJob, boolean append) throws IOException {
+				setOutputStream(new BufferedOutputStream(new FileOutputStream(localFileToSave.getName(), append)));
+				setupAndScheduleJob(fileTransferJob);
+				return AbstractRetrieveFileTransfer.this;
+			}
+
+			/**
+			 * @param streamToStore
+			 * @return incoming file transfer instance.
+			 * @throws IOException not thrown in this implementation.
+			 */
+			public IIncomingFileTransfer receive(OutputStream streamToStore) throws IOException {
+				return receive(streamToStore, null);
+			}
+
+			/**
+			 * @throws IOException not actually thrown by this implementation.
+			 */
+			public IIncomingFileTransfer receive(OutputStream streamToStore, FileTransferJob fileTransferJob) throws IOException {
+				setOutputStream(streamToStore);
+				setCloseOutputStream(false);
+				setupAndScheduleJob(fileTransferJob);
+				return AbstractRetrieveFileTransfer.this;
+			}
+
+			/* (non-Javadoc)
+			 * @see org.eclipse.ecf.filetransfer.events.IIncomingFileTransferReceiveStartEvent#cancel()
+			 */
+			public void cancel() {
+				hardClose();
+			}
+
+			public String toString() {
+				final StringBuffer sb = new StringBuffer("IIncomingFileTransferReceiveResumedEvent["); //$NON-NLS-1$
+				sb.append("isdone=").append(done).append(";"); //$NON-NLS-1$ //$NON-NLS-2$
+				sb.append("bytesReceived=").append(bytesReceived) //$NON-NLS-1$
+						.append("]"); //$NON-NLS-1$
+				return sb.toString();
+			}
+
+		});
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ecf.filetransfer.IIncomingFileTransfer#getFileRangeSpecification()
+	 */
+	public IFileRangeSpecification getFileRangeSpecification() {
+		return rangeSpecification;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ecf.filetransfer.IRetrieveFileTransferContainerAdapter#sendRetrieveRequest(org.eclipse.ecf.filetransfer.identity.IFileID, org.eclipse.ecf.filetransfer.IFileRangeSpecification, org.eclipse.ecf.filetransfer.IFileTransferListener, java.util.Map)
+	 */
+	public void sendRetrieveRequest(IFileID rFileID, IFileRangeSpecification rangeSpec, IFileTransferListener transferListener, Map ops) throws IncomingFileTransferException {
+		Assert.isNotNull(rFileID, Messages.AbstractRetrieveFileTransfer_RemoteFileID_Not_Null);
+		Assert.isNotNull(transferListener, Messages.AbstractRetrieveFileTransfer_TransferListener_Not_Null);
+		this.job = null;
+		this.remoteFileURL = null;
+		this.remoteFileID = rFileID;
+		this.listener = transferListener;
+		this.remoteFileContents = null;
+		this.localFileContents = null;
+		this.closeOutputStream = true;
+		this.done = false;
+		this.exception = null;
+		this.bytesReceived = 0;
+		this.fileLength = -1;
+		this.options = ops;
+		this.paused = false;
+		this.rangeSpecification = rangeSpec;
+
+		try {
+			this.remoteFileURL = rFileID.getURL();
+		} catch (final MalformedURLException e) {
+			throw new IncomingFileTransferException(NLS.bind(Messages.AbstractRetrieveFileTransfer_MalformedURLException, rFileID), e);
+		}
+		setupProxies();
+		openStreams();
+	}
+
+	/**
+	 * Setup ECF proxy.  Subclasses must override this method to do appropriate proxy setup.  This method will be called
+	 * from within {@link #sendRetrieveRequest(IFileID, IFileTransferListener, Map)} and {@link #sendRetrieveRequest(IFileID, IFileRangeSpecification, IFileTransferListener, Map)},
+	 * prior to the actual call to {@link #openStreams()}.
+	 * @param proxy the proxy to be setup.  Will not be <code>null</code>.
+	 */
+	protected abstract void setupProxy(Proxy proxy);
+
+	/**
+	 * Select a single proxy from a set of proxies available for the given host.  This implementation
+	 * selects in the following manner:  1) If proxies provided is null or array of 0 length, null 
+	 * is returned.  If only one proxy is available (array of length 1) then the entry is returned.
+	 * If proxies provided is length > 1, then if the type of a proxy in the array matches the given
+	 * protocol (e.g. http, https), then the first matching proxy is returned.  If the protocol does
+	 * not match any of the proxies, then the *first* proxy (i.e. proxies[0]) is returned.  Subclasses may
+	 * override if desired.
+	 * 
+	 * @param protocol the target protocol (e.g. http, https, scp, etc).  Will not be <code>null</code>.
+	 * @param proxies the proxies to select from.  May be <code>null</code> or array of length 0.
+	 * @return proxy data selected from the proxies provided.  
+	 */
+	protected IProxyData selectProxyFromProxies(String protocol, IProxyData[] proxies) {
+		if (proxies == null || proxies.length == 0)
+			return null;
+		// If only one proxy is available, then use that
+		if (proxies.length == 1)
+			return proxies[0];
+		// If more than one proxy is available, then if http/https protocol then look for that
+		// one...if not found then use first
+		if (protocol.equalsIgnoreCase("http")) { //$NON-NLS-1$
+			for (int i = 0; i < proxies.length; i++) {
+				if (proxies[i].getType().equals(IProxyData.HTTP_PROXY_TYPE))
+					return proxies[i];
+			}
+		} else if (protocol.equalsIgnoreCase("https")) { //$NON-NLS-1$
+			for (int i = 0; i < proxies.length; i++) {
+				if (proxies[i].getType().equals(IProxyData.HTTPS_PROXY_TYPE))
+					return proxies[i];
+			}
+		}
+		// If we haven't found it yet, then return the first one.
+		return proxies[0];
+	}
+
+	protected void setupProxies() {
+		// If it's been set directly (via ECF API) then this overrides platform settings
+		if (proxy == null) {
+			try {
+				IProxyService proxyService = Activator.getDefault().getProxyService();
+				// Only do this if platform service exists
+				if (proxyService != null && proxyService.isProxiesEnabled()) {
+					// Setup via proxyService entry
+					URL target = getRemoteFileURL();
+					final IProxyData[] proxies = proxyService.getProxyDataForHost(target.getHost());
+					IProxyData selectedProxy = selectProxyFromProxies(target.getProtocol(), proxies);
+					if (selectedProxy != null) {
+						proxy = new Proxy(((selectedProxy.getType().equalsIgnoreCase(IProxyData.SOCKS_PROXY_TYPE)) ? Proxy.Type.SOCKS : Proxy.Type.HTTP), new ProxyAddress(selectedProxy.getHost(), selectedProxy.getPort()), selectedProxy.getUserId(), selectedProxy.getPassword());
+					}
+				}
+			} catch (Exception e) {
+				// If we don't even have the classes for this (i.e. the org.eclipse.core.net plugin not available)
+				// then we simply log and ignore
+				Activator.logNoProxyWarning(e);
+			} catch (NoClassDefFoundError e) {
+				Activator.logNoProxyWarning(e);
+			}
+		}
+		if (proxy != null)
+			setupProxy(proxy);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ecf.filetransfer.IIncomingFileTransfer#getRemoteFileName()
+	 */
+	public String getRemoteFileName() {
+		String pathStr = getRemoteFileURL().getPath();
+		if (pathStr.length() > 0) {
+			IPath path = Path.fromPortableString(pathStr);
+			if (path.segmentCount() > 0)
+				return path.lastSegment();
+		}
+		return null;
+	}
+
+}
diff --git a/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/retrieve/MultiProtocolRetrieveAdapter.java b/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/retrieve/MultiProtocolRetrieveAdapter.java
new file mode 100644
index 0000000..b3f1cd3
--- /dev/null
+++ b/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/retrieve/MultiProtocolRetrieveAdapter.java
@@ -0,0 +1,148 @@
+/****************************************************************************
+ * Copyright (c) 2004, 2007 Composent, Inc. 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:
+ *    Composent, Inc. - initial API and implementation
+ *****************************************************************************/
+
+package org.eclipse.ecf.provider.filetransfer.retrieve;
+
+import java.net.MalformedURLException;
+import java.util.Map;
+import org.eclipse.core.runtime.IAdapterManager;
+import org.eclipse.ecf.core.identity.IDFactory;
+import org.eclipse.ecf.core.identity.Namespace;
+import org.eclipse.ecf.core.security.IConnectContext;
+import org.eclipse.ecf.core.util.Proxy;
+import org.eclipse.ecf.filetransfer.IFileRangeSpecification;
+import org.eclipse.ecf.filetransfer.IFileTransferListener;
+import org.eclipse.ecf.filetransfer.IRetrieveFileTransferContainerAdapter;
+import org.eclipse.ecf.filetransfer.IncomingFileTransferException;
+import org.eclipse.ecf.filetransfer.identity.IFileID;
+import org.eclipse.ecf.filetransfer.service.IRetrieveFileTransfer;
+import org.eclipse.ecf.internal.provider.filetransfer.Activator;
+import org.eclipse.ecf.internal.provider.filetransfer.Messages;
+import org.eclipse.ecf.provider.filetransfer.identity.FileTransferNamespace;
+
+/**
+ * Multi protocol handler for retrieve file transfer. Multiplexes between Apache
+ * httpclient 3.0.1-based file retriever and the URLConnection-based file
+ * retriever.
+ */
+public class MultiProtocolRetrieveAdapter implements IRetrieveFileTransfer {
+
+	IConnectContext connectContext = null;
+	Proxy proxy = null;
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ecf.filetransfer.IRetrieveFileTransferContainerAdapter#getRetrieveNamespace()
+	 */
+	public Namespace getRetrieveNamespace() {
+		return IDFactory.getDefault().getNamespaceByName(FileTransferNamespace.PROTOCOL);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ecf.filetransfer.IRetrieveFileTransferContainerAdapter#setConnectContextForAuthentication(org.eclipse.ecf.core.security.IConnectContext)
+	 */
+	public void setConnectContextForAuthentication(IConnectContext connectContext) {
+		this.connectContext = connectContext;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ecf.filetransfer.IRetrieveFileTransferContainerAdapter#setProxy(org.eclipse.ecf.core.util.Proxy)
+	 */
+	public void setProxy(Proxy proxy) {
+		this.proxy = proxy;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ecf.filetransfer.IRetrieveFileTransferContainerAdapter#sendRetrieveRequest(org.eclipse.ecf.filetransfer.identity.IFileID,
+	 *      org.eclipse.ecf.filetransfer.IFileTransferListener, java.util.Map)
+	 */
+	public void sendRetrieveRequest(IFileID remoteFileID, IFileTransferListener transferListener, Map options) throws IncomingFileTransferException {
+
+		String protocol = null;
+		try {
+			protocol = remoteFileID.getURL().getProtocol();
+		} catch (final MalformedURLException e) {
+			throw new IncomingFileTransferException(Messages.AbstractRetrieveFileTransfer_MalformedURLException);
+		}
+
+		IRetrieveFileTransferContainerAdapter fileTransfer = null;
+		fileTransfer = Activator.getDefault().getFileTransfer(protocol);
+
+		// We will default to JRE-provided file transfer if nothing else
+		// available
+		// for given protocol
+		if (fileTransfer == null)
+			fileTransfer = new UrlConnectionRetrieveFileTransfer();
+
+		// Set connect context
+		fileTransfer.setConnectContextForAuthentication(connectContext);
+		// Set Proxy
+		fileTransfer.setProxy(proxy);
+
+		// send request using given file transfer protocol
+		fileTransfer.sendRetrieveRequest(remoteFileID, transferListener, options);
+
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ecf.filetransfer.IRetrieveFileTransferContainerAdapter#sendRetrieveRequest(org.eclipse.ecf.filetransfer.identity.IFileID,
+	 *      org.eclipse.ecf.filetransfer.IFileRangeSpecification,
+	 *      org.eclipse.ecf.filetransfer.IFileTransferListener, java.util.Map)
+	 */
+	public void sendRetrieveRequest(IFileID remoteFileID, IFileRangeSpecification rangeSpecification, IFileTransferListener transferListener, Map options) throws IncomingFileTransferException {
+		String protocol = null;
+		try {
+			protocol = remoteFileID.getURL().getProtocol();
+		} catch (final MalformedURLException e) {
+			throw new IncomingFileTransferException(Messages.AbstractRetrieveFileTransfer_MalformedURLException);
+		}
+
+		IRetrieveFileTransferContainerAdapter fileTransfer = null;
+		fileTransfer = Activator.getDefault().getFileTransfer(protocol);
+
+		// We will default to JRE-provided file transfer if nothing else
+		// available
+		// for given protocol
+		if (fileTransfer == null)
+			fileTransfer = new UrlConnectionRetrieveFileTransfer();
+
+		// Set connect context
+		fileTransfer.setConnectContextForAuthentication(connectContext);
+		// Set Proxy
+		fileTransfer.setProxy(proxy);
+
+		// send request using given file transfer protocol
+		fileTransfer.sendRetrieveRequest(remoteFileID, rangeSpecification, transferListener, options);
+
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
+	 */
+	public Object getAdapter(Class adapter) {
+		if (adapter == null)
+			return null;
+		final IAdapterManager adapterManager = Activator.getDefault().getAdapterManager();
+		if (adapterManager == null)
+			return null;
+		return adapterManager.loadAdapter(this, adapter.getName());
+	}
+
+}
diff --git a/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/retrieve/UrlConnectionRetrieveFileTransfer.java b/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/retrieve/UrlConnectionRetrieveFileTransfer.java
index c937614..77fa497 100644
--- a/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/retrieve/UrlConnectionRetrieveFileTransfer.java
+++ b/providers/bundles/org.eclipse.ecf.provider.filetransfer/src/org/eclipse/ecf/provider/filetransfer/retrieve/UrlConnectionRetrieveFileTransfer.java
@@ -11,13 +11,27 @@
 
 import java.io.IOException;
 import java.io.InputStream;
-import java.net.*;
+import java.net.Authenticator;
+import java.net.ConnectException;
+import java.net.PasswordAuthentication;
+import java.net.URL;
+import java.net.URLConnection;
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.Path;
-import org.eclipse.ecf.core.security.*;
+import org.eclipse.ecf.core.security.Callback;
+import org.eclipse.ecf.core.security.CallbackHandler;
+import org.eclipse.ecf.core.security.IConnectContext;
+import org.eclipse.ecf.core.security.NameCallback;
+import org.eclipse.ecf.core.security.ObjectCallback;
+import org.eclipse.ecf.core.security.UnsupportedCallbackException;
 import org.eclipse.ecf.core.util.Proxy;
-import org.eclipse.ecf.filetransfer.*;
-import org.eclipse.ecf.internal.provider.filetransfer.*;
+import org.eclipse.ecf.filetransfer.IFileRangeSpecification;
+import org.eclipse.ecf.filetransfer.IFileTransferPausable;
+import org.eclipse.ecf.filetransfer.IncomingFileTransferException;
+import org.eclipse.ecf.filetransfer.InvalidFileRangeSpecificationException;
+import org.eclipse.ecf.internal.provider.filetransfer.Activator;
+import org.eclipse.ecf.internal.provider.filetransfer.IURLConnectionModifier;
+import org.eclipse.ecf.internal.provider.filetransfer.Messages;
 import org.eclipse.ecf.provider.filetransfer.util.JREProxyHelper;
 import org.eclipse.osgi.util.NLS;