Initial release
diff --git a/examples/org.eclipse.team.examples.filesystem/.classpath b/examples/org.eclipse.team.examples.filesystem/.classpath
new file mode 100644
index 0000000..51c4de0
--- /dev/null
+++ b/examples/org.eclipse.team.examples.filesystem/.classpath
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+    <classpathentry kind="src" path="/org.eclipse.core.resources"/>
+    <classpathentry kind="src" path="/org.eclipse.team.core"/>
+    <classpathentry kind="src" path="/org.apache.xerces"/>
+    <classpathentry kind="src" path="/org.eclipse.webdav"/>
+    <classpathentry kind="src" path="/org.eclipse.team.ui"/>
+    <classpathentry kind="src" path="/org.eclipse.ui"/>
+    <classpathentry kind="src" path="src"/>
+    <classpathentry kind="src" path="/org.eclipse.core.runtime"/>
+    <classpathentry kind="src" path="/org.eclipse.core.boot"/>
+    <classpathentry kind="var" path="JRE_LIB" rootpath="JRE_SRCROOT" sourcepath="JRE_SRC"/>
+    <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.team.examples.filesystem/.cvsignore b/examples/org.eclipse.team.examples.filesystem/.cvsignore
new file mode 100644
index 0000000..ba077a4
--- /dev/null
+++ b/examples/org.eclipse.team.examples.filesystem/.cvsignore
@@ -0,0 +1 @@
+bin
diff --git a/examples/org.eclipse.team.examples.filesystem/.project b/examples/org.eclipse.team.examples.filesystem/.project
new file mode 100644
index 0000000..a465668
--- /dev/null
+++ b/examples/org.eclipse.team.examples.filesystem/.project
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.team.examples.filesystem</name>
+	<comment></comment>
+	<projects>
+		<project>org.apache.xerces</project>
+		<project>org.eclipse.core.boot</project>
+		<project>org.eclipse.core.resources</project>
+		<project>org.eclipse.core.runtime</project>
+		<project>org.eclipse.team.core</project>
+		<project>org.eclipse.team.ui</project>
+		<project>org.eclipse.ui</project>
+		<project>org.eclipse.webdav</project>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/examples/org.eclipse.team.examples.filesystem/icons/full/wizards/fsicon_wiz.gif b/examples/org.eclipse.team.examples.filesystem/icons/full/wizards/fsicon_wiz.gif
new file mode 100644
index 0000000..af038fa
--- /dev/null
+++ b/examples/org.eclipse.team.examples.filesystem/icons/full/wizards/fsicon_wiz.gif
Binary files differ
diff --git a/examples/org.eclipse.team.examples.filesystem/icons/full/wizban/newconnect_wizban.gif b/examples/org.eclipse.team.examples.filesystem/icons/full/wizban/newconnect_wizban.gif
new file mode 100644
index 0000000..3038a23
--- /dev/null
+++ b/examples/org.eclipse.team.examples.filesystem/icons/full/wizban/newconnect_wizban.gif
Binary files differ
diff --git a/examples/org.eclipse.team.examples.filesystem/plugin.properties b/examples/org.eclipse.team.examples.filesystem/plugin.properties
new file mode 100644
index 0000000..c162efa
--- /dev/null
+++ b/examples/org.eclipse.team.examples.filesystem/plugin.properties
@@ -0,0 +1,12 @@
+pluginName = Eclipse Team File System Examples
+
+Put.name=Put
+Put.tooltip=Copy resources to the shared file system location
+Get.name=Get
+Get.tooltip=Copy resources from the shared file system location to the workbench
+Unmanage.name=Unmanage
+Unmanage.tooltip=Mark resources as not-shared
+fspropertypage.name=FileSystem Provider
+fspropertypage.tooltip=An example repository provider that uses the filesystem to provide storage.
+fswizard.name=File System Example (Non-Versioning)
+fswizard.description=Associate a project with a file system location. This location can be used to shared resources with others.
diff --git a/examples/org.eclipse.team.examples.filesystem/plugin.xml b/examples/org.eclipse.team.examples.filesystem/plugin.xml
new file mode 100644
index 0000000..c6624ad
--- /dev/null
+++ b/examples/org.eclipse.team.examples.filesystem/plugin.xml
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<plugin
+   id="org.eclipse.team.examples.filesystem"
+   name="%pluginName"
+   version="2.0.0"
+   provider-name="Object Technology International, Inc."
+   class="org.eclipse.team.examples.filesystem.FileSystemPlugin">
+
+   <runtime>
+   </runtime>
+   <requires>
+      <import plugin="org.eclipse.core.resources"/>
+      <import plugin="org.eclipse.team.core"/>
+      <import plugin="org.apache.xerces"/>
+      <import plugin="org.eclipse.webdav"/>
+      <import plugin="org.eclipse.team.ui"/>
+      <import plugin="org.eclipse.ui"/>
+   </requires>
+
+<!-- *************** Repository Provider **************** -->
+   <extension
+         point="org.eclipse.team.core.repository">
+      <repository
+            class="org.eclipse.team.examples.filesystem.FileSystemProvider"
+            id="org.eclipse.team.examples.filesystem.FileSystemProvider">
+      </repository>
+   </extension>
+
+<!-- *************** POPUP MENUS **************** -->
+   <extension
+         point="org.eclipse.ui.popupMenus">
+      <objectContribution
+            objectClass="org.eclipse.core.resources.IResource"
+            adaptable="true"
+            id="org.eclipse.team.examples.filesystem.ResourceContributions">
+         <filter
+               name="projectPersistentProperty"
+               value="org.eclipse.team.core.repository=org.eclipse.team.examples.filesystem.FileSystemProvider">
+         </filter>
+         <action
+               label="%Get.name"
+               tooltip="%Get.tooltip"
+               class="org.eclipse.team.examples.filesystem.ui.GetAction"
+               menubarPath="team.main/group1"
+               id="org.eclipse.team.examples.filesystem.get">
+         </action>
+         <action
+               label="%Put.name"
+               tooltip="%Put.tooltip"
+               class="org.eclipse.team.examples.filesystem.ui.PutAction"
+               menubarPath="team.main/group1"
+               id="org.eclipse.team.examples.filesystem.put">
+         </action>
+      </objectContribution>
+      
+      <objectContribution
+            objectClass="org.eclipse.core.resources.IProject"
+            adaptable="true"
+            id="org.eclipse.team.examples.filesystem.ProjectContributions">
+         <filter
+               name="projectPersistentProperty"
+               value="org.eclipse.team.core.repository=org.eclipse.team.examples.filesystem.FileSystemProvider">
+         </filter>
+         <action
+               label="%Unmanage.name"
+               tooltip="%Unmanage.tooltip"
+               class="org.eclipse.team.examples.filesystem.ui.DisconnectAction"
+               menubarPath="team.main/group2"
+               id="org.eclipse.team.examples.filesystem.unmanage">
+         </action>
+      </objectContribution>
+   </extension>
+   
+<!-- *************** CONFIGURATION WIZARD **************** -->
+   <extension
+         point="org.eclipse.team.ui.configurationWizards">
+      <wizard
+            name="%fswizard.name"
+            icon="icons/full/wizards/fsicon_wiz.gif"
+            category="org.eclipse.team.ui"
+            class="org.eclipse.team.examples.filesystem.ui.ConfigurationWizard"
+            id="org.eclipse.team.examples.filesystem.ui.ConfigurationWizard">
+         <description>
+            %fswizard.description
+         </description>
+      </wizard>
+   </extension>
+
+   
+<!-- *************** PROPERTY PAGES **************** -->
+   <extension
+         point="org.eclipse.ui.propertyPages">
+      <page
+            objectClass="org.eclipse.core.resources.IResource"
+            adaptable="true"
+            name="%fspropertypage.name"
+            class="org.eclipse.team.examples.filesystem.ui.FileSystemPropertiesPage"
+            id="org.eclipse.team.examples.filesystem.ui.FileSystemPropertiesPage">
+         <filter
+               name="projectPersistentProperty"
+               value="org.eclipse.team.core.repository=org.eclipse.team.examples.filesystem.FileSystemProvider">
+         </filter>
+      </page>
+   </extension>
+   
+</plugin>
diff --git a/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/FileSystemPlugin.java b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/FileSystemPlugin.java
new file mode 100644
index 0000000..f59deea
--- /dev/null
+++ b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/FileSystemPlugin.java
@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * Copyright (c) 2002 IBM Corporation and others.
+ * All rights reserved.   This program and the accompanying materials
+ * are made available under the terms of the Common Public License v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ * 
+ * Contributors:
+ * IBM - Initial API and implementation
+ ******************************************************************************/
+package org.eclipse.team.examples.filesystem;
+
+import java.io.IOException;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPluginDescriptor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.team.core.TeamException;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+/**
+ * This is the plugin class for the file system examples. It provides the following:
+ * 
+ * <ol>
+ * <li>public fields for the plugin and provider IDs as defined in the plugin.xml
+ * <li>initialization on startup of Policy class that provides internationalization of strings
+ * <li>helper methods for outputing IStatus objects to the log
+ * <li>helper methods for converting CoreExceptions and IOExceptions to TeamExceptions
+ * </ol>
+ */
+public class FileSystemPlugin extends AbstractUIPlugin {
+	
+	/**
+	 * This is the ID of the plugin as defined in the plugin.xml
+	 */
+	public static final String ID = "org.eclipse.team.examples.filesystem";
+	
+	/**
+	 * This is the provider ID of the plugin as defined in the plugin.xml
+	 */
+	public static final String PROVIDER_ID = ID + ".FileSystemProvider";
+	
+	// This static field will hold the singleton instance of the plugin class
+	private static FileSystemPlugin plugin;
+	
+	/**
+	 * Override the standard plugin constructor.
+	 * 
+	 * @param descriptor the plugin descriptor
+	 */
+	public FileSystemPlugin(IPluginDescriptor descriptor) {
+		super(descriptor);
+		// record this instance as the singleton
+		plugin = this;
+	}
+	
+	/**
+	 * This method will get invoked when the plugin is started.
+	 * Note that this is not necessarily at workbench startup.
+	 * 
+	 * @see org.eclipse.core.runtime.Plugin#startup()
+	 */
+	public void startup() throws CoreException {
+		// localize the string bindings used by the plugins (in order to provide NLS support)
+		Policy.localize("org.eclipse.team.examples.filesystem.messages");
+	}
+	
+	/**
+	 * Return the singlton instance of the plugin class to allow other
+	 * classes in the plugin access to plugin instance methods such as 
+	 * those for logging errors, etc.
+	 */
+	public static FileSystemPlugin getPlugin() {
+		return plugin;
+	}
+	
+	/**
+	 * Helper method to convert a CoreException into a TeamException.
+	 * We do this to maintain the core status and code. This type of
+	 * mapping may not be appropriate in more complicated exception 
+	 * handling situations.
+	 * 
+	 * @param e the CoreException
+	 */
+	public static TeamException wrapException(CoreException e) {
+		return new TeamException(e.getStatus());
+	}
+
+	/**
+	 * Helper method to convert an IOException into a TeamException.
+	 * This type of mapping may not be appropriate in more complicated 
+	 * exception handling situations.
+	 * 
+	 * @param e the CoreException
+	 */
+	public static TeamException wrapException(IOException e) {
+		return new TeamException(new Status(IStatus.ERROR, FileSystemPlugin.ID, 
+			TeamException.IO_FAILED, e.getMessage(), e));
+	}
+	
+	/**
+	 * Helper method to log an exception status.
+	 * 
+	 * @param status the status to be logged
+	 */
+	public static void log(IStatus status) {
+		plugin.getLog().log(status);
+	}
+}
+
diff --git a/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/FileSystemProvider.java b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/FileSystemProvider.java
new file mode 100644
index 0000000..053ad5d
--- /dev/null
+++ b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/FileSystemProvider.java
@@ -0,0 +1,170 @@
+/*******************************************************************************
+ * Copyright (c) 2002 IBM Corporation and others.
+ * All rights reserved.   This program and the accompanying materials
+ * are made available under the terms of the Common Public License v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ * 
+ * Contributors:
+ * IBM - Initial API and implementation
+ ******************************************************************************/
+package org.eclipse.team.examples.filesystem;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ISynchronizer;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.QualifiedName;
+
+import org.eclipse.team.core.RepositoryProvider;
+import org.eclipse.team.core.TeamException;
+import org.eclipse.team.core.sync.IRemoteResource;
+import org.eclipse.team.internal.core.simpleAccess.SimpleAccessOperations;
+
+/**
+ * This example illustrates how to create a concrete implementation of a <code>RepositoryProvider</code>
+ * that uses the file system to act as the repository. See the plugin.xml file for the xml required
+ * to register this provider with the Team extension point <code>org.eclipse.team.core.repository</code>.
+ * The plugin.xml file also contains examples of how to filter menu items using a repsitory provider's
+ * ID.
+ * 
+ * <p>
+ * This example provider illustrates the following:
+ * <ol>
+ * <li>simple working implementation of <code>RepositoyProvider</code>
+ * <li>storage of a persistant property with the project (which provides the target location for the provider)
+ * <li>access to an instance of <code>SimpleAccessOperations</code> for performing simple file operations
+ * </ol>
+ * 
+ * <p>
+ * Additional functionality that will be illustrated in the future include:
+ * <ol>
+ * <li>Validate Save/Validat Edit
+ * <li>Move/Delete Hook
+ * <li>Project Sets
+ * <li>Use of the workspace synchronizer (ISynchronizer)
+ * <li>Use of decorators
+ * <li>combining streams and progress monitors to get responsive UI
+ * </ol>
+ * 
+ */
+public class FileSystemProvider extends RepositoryProvider {
+	
+	// The location of the folder on file system where the repository is stored.
+	private IPath root;
+	
+	// The QualifiedName that is used to persist the location accross workspace as a persistant property on a resource
+	private static QualifiedName FILESYSTEM_REPO_LOC = new QualifiedName(FileSystemPlugin.ID, "disk_location");
+
+	/**
+	 * Create a new FileSystemProvider.
+	 */
+	public FileSystemProvider() {
+		super();
+	}
+	
+	/**
+	 * This method is invoked when the provider is mapped to a project.
+	 * Although we have access to the project at this point (using 
+	 * <code>getProject()</code>, we don't know the root location so
+	 * there is nothing we can do yet.
+	 * 
+	 * @see org.eclipse.team.core.RepositoryProvider#configureProject()
+	 */
+	public void configureProject() throws CoreException {
+	}
+
+	/**
+	 * This method is invoked when the provider is unmapped from its
+	 * project.
+	 * 
+	 * @see org.eclipse.core.resources.IProjectNature#deconfigure()
+	 */
+	public void deconfigure() throws CoreException {
+		// Clear the persistant property containing the location
+		getProject().setPersistentProperty(FILESYSTEM_REPO_LOC, null);
+	}
+
+	/**
+	 * Return the provider ID as specified in the plugin.xml
+	 * 
+	 * @see RepositoryProvider#getID()
+	 */
+	public String getID() {
+		return FileSystemPlugin.PROVIDER_ID;
+	}
+		
+	/**
+	 * Set the file system location for the provider. This mist be invoked after 
+	 * the provider is mapped and configured but before the provider is used to 
+	 * perform any operations.
+	 * 
+	 * @param location the path representing the location where the project contents will be stored.
+	 * @throws TeamException
+	 */
+	public void setTargetLocation(String location) throws TeamException {
+		
+		// set the instance variable to the provided path
+		root = new Path(location);
+		
+		// ensure that the location is a folder (if it exists)
+		File file = new File(location);
+		if (file.exists() && !file.isDirectory()) {
+			throw new TeamException(Policy.bind("FileSystemProvider.mustBeFolder", location));
+		}
+		
+		// record the location as a persistant property so it will be remembered across platform invokations
+		try {
+			getProject().setPersistentProperty(FILESYSTEM_REPO_LOC, location);
+		} catch (CoreException e) {
+			throw FileSystemPlugin.wrapException(e);
+		}
+	}
+	
+	/**
+	 * Returns the folder in the file system to which the provider is connected.
+	 * Return <code>null</code> if there is no location or there was a problem
+	 * determining it.
+	 * 
+	 * @return IPath The path to the root of the repository.
+	 */
+	public IPath getRoot() {
+		if (root == null) {
+			try {
+				String location = getProject().getPersistentProperty(FILESYSTEM_REPO_LOC);
+				if (location == null) {
+					return null;
+				}
+				root = new Path(location);
+			} catch (CoreException e) {
+				// log the problem and carry on
+				FileSystemPlugin.log(e.getStatus());
+				return null;
+			}
+		}
+		return root;
+	}
+
+	/**
+	 * Return an instance of <code>SimpleAccessOperations</code> that provides the
+	 * operations for transfering data to and from the provider's location.
+	 * Note: The interface <code>SimpleAccessOperations</code> is not part of the official
+	 * Team API. We use it here for convenience.
+	 * 
+	 * @see org.eclipse.team.core.RepositoryProvider#getSimpleAccess()
+	 */
+	public SimpleAccessOperations getSimpleAccess() {
+		return new FileSystemSimpleAccessOperations(this);
+	}
+}
diff --git a/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/FileSystemRemoteResource.java b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/FileSystemRemoteResource.java
new file mode 100644
index 0000000..f183184
--- /dev/null
+++ b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/FileSystemRemoteResource.java
@@ -0,0 +1,118 @@
+/*******************************************************************************
+ * Copyright (c) 2002 IBM Corporation and others.
+ * All rights reserved.   This program and the accompanying materials
+ * are made available under the terms of the Common Public License v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ * 
+ * Contributors:
+ * IBM - Initial API and implementation
+ ******************************************************************************/
+package org.eclipse.team.examples.filesystem;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.team.core.TeamException;
+import org.eclipse.team.core.sync.IRemoteResource;
+
+/**
+ * Class represents a handle to a <code>java.io.File</code> that conforms to
+ * the <code>org.eclipse.team.core.IRemoteResource</code> interface.
+ */
+public class FileSystemRemoteResource implements IRemoteResource {
+	
+	// the file object in which the data is stored on the disk
+	private File ioFile;
+
+	/**
+	 * The constructor.
+	 * @param path the full path of the resource on disk
+	 */
+	public FileSystemRemoteResource(IPath path) {
+		this(new File(path.toOSString()));
+	}
+	
+	/**
+	 * Create a remote resource handle from the given java.io.file
+	 * 
+	 * @param ioFile the file
+	 */
+	private FileSystemRemoteResource(File ioFile) {
+		this.ioFile = ioFile;
+	}
+	
+	/**
+	 * Adapters are used to ensure that the right menus will appear in differnet views.
+	 * 
+	 * @see org.eclipse.core.runtime.IAdaptable#getAdapter(Class)
+	 */
+	public Object getAdapter(Class adapter) {
+		return Platform.getAdapterManager().getAdapter(this, adapter);
+	}
+
+	/**
+	 * Returns an input stream containing the contents of the remote resource.
+	 * The remote resource must be a file.
+	 * 
+	 * @see org.eclipse.team.core.sync.IRemoteResource#getContents(IProgressMonitor)
+	 */
+	public InputStream getContents(IProgressMonitor progress) throws TeamException {
+		if (isContainer())
+			throw new TeamException("This resource is a container so it cannot have data.");
+		try {
+			return new FileInputStream(ioFile);
+		} catch (FileNotFoundException e) {
+			throw FileSystemPlugin.wrapException(e);
+		}
+	}
+		
+	/**
+	 * Return the modification timestamp of the remote resource.
+	 * 
+	 * @return long The date and time (in milliseconds) when the file was last changed on disk.
+	 */
+	public long getLastModified() {
+		return ioFile.lastModified();
+	}
+
+	/**
+	 * @see org.eclipse.team.core.sync.IRemoteResource#getName()
+	 */
+	public String getName() {
+		return ioFile.getName();
+	}
+		
+	/**
+	 * @see org.eclipse.team.core.sync.IRemoteResource#isContainer()
+	 */
+	public boolean isContainer() {
+		return ioFile.isDirectory();
+	}
+
+	/**
+	 * Fetch the members of the remote resource. The remote resource must be a 
+	 * container.
+	 * 
+	 * @see org.eclipse.team.core.sync.IRemoteResource#members(IProgressMonitor)
+	 */
+	public IRemoteResource[] members(IProgressMonitor progress) throws TeamException {
+		// Make sure we have a container
+		if (!isContainer())
+			throw new TeamException("This resource is a file so it cannot have entries.");
+		
+		// convert the File children to remote resource children
+		File[] members = ioFile.listFiles();
+		IRemoteResource[] result = new IRemoteResource[members.length];
+		for (int i = 0; i < members.length; i++) {
+			result[i] = new FileSystemRemoteResource(members[i]);
+		}
+		return result;
+	}
+	
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/FileSystemSimpleAccessOperations.java b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/FileSystemSimpleAccessOperations.java
new file mode 100644
index 0000000..6bc3b22
--- /dev/null
+++ b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/FileSystemSimpleAccessOperations.java
@@ -0,0 +1,222 @@
+/*******************************************************************************
+ * Copyright (c) 2002 IBM Corporation and others.
+ * All rights reserved.   This program and the accompanying materials
+ * are made available under the terms of the Common Public License v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ * 
+ * Contributors:
+ * IBM - Initial API and implementation
+ ******************************************************************************/
+package org.eclipse.team.examples.filesystem;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.team.core.TeamException;
+import org.eclipse.team.core.sync.IRemoteResource;
+import org.eclipse.team.internal.core.simpleAccess.SimpleAccessOperations;
+
+/**
+ * SimpleAccessOperations is not part of the Team API. We use it here because it provides
+ * a reasonable set of operation commonly implemented by repository providers.
+ * Note: This class is not to be interpreted as an example of how a repository
+ * provider is to do its work. It is only here because we needed to have some operations
+ * to perform. In the future, we may update this class to illustrate the use of the workspace 
+ * synchronizer (<code>ISynchronizer</code>).
+ */
+public class FileSystemSimpleAccessOperations implements SimpleAccessOperations {
+	
+	// A reference to the provider
+	private FileSystemProvider provider;
+
+	/**
+	 * Constructor
+	 * @param provider
+	 */
+	FileSystemSimpleAccessOperations(FileSystemProvider provider) {
+		this.provider = provider;
+	}
+	
+	/**
+	 * Given a local resource, finds the remote counterpart.
+	 * @param resource The local resource to lookup
+	 * @return FileSystemRemoteResource The remote counterpart to the given local resource
+	 */
+	public FileSystemRemoteResource getRemoteResourceFor(IResource resource) {
+		return new FileSystemRemoteResource(provider.getRoot().append(resource.getProjectRelativePath()));
+	}
+
+	/**
+	 * @see SimpleAccessOperations#get(IResource[], int, IProgressMonitor)
+	 */
+	public void get(IResource[] resources, int depth, IProgressMonitor progress) throws TeamException {
+		// ensure the progress monitor is not null
+		progress = Policy.monitorFor(progress);
+		progress.beginTask("Checking resources in...", resources.length);
+		for (int i = 0; i < resources.length; i++) {
+			Policy.checkCanceled(progress);
+			IPath rootdir = provider.getRoot();
+
+			FileSystemRemoteResource remote = getRemoteResourceFor(resources[i]);
+			if (resources[i].getType() == IResource.FILE) {
+				//Copy the resource over to the other side:
+				IFile localFile = (IFile) resources[i]; //since we know the local resource is a file.
+				if (localFile.getModificationStamp() != remote.getLastModified()) {
+					//Only do this if the timestamps are different
+					try {
+						//Copy from the local file to the remote file:
+						InputStream source = null;
+						try {
+							// Get the remote file content.
+							source = remote.getContents(progress); //new FileInputStream(diskFile);
+							// Set the local file content to be the same as the remote file.
+							if (localFile.exists())
+								localFile.setContents(source, false, false, progress);
+							else
+								localFile.create(source, false, progress);
+						} finally {
+							if (source != null)
+								source.close();
+						}
+					} catch (IOException e) {
+						throw FileSystemPlugin.wrapException(e);
+					} catch (CoreException e) {
+						throw FileSystemPlugin.wrapException(e);
+					}
+				}
+			} else if (depth > 0) { //Assume that resources are either files or containers.
+				//Recursively copy children, if any, over as well:
+				try {
+					IResource[] children;
+					if (resources[i].getType() == IResource.PROJECT) {
+						children = provider.getProject().members();
+					} else {
+						IRemoteResource[] estranged = remote.members(progress);
+						children = new IResource[estranged.length];
+						for (int j = 0; j < estranged.length; j++) {
+							children[j] = provider.getProject().getFile(estranged[j].getName());
+						}
+					}
+					if (children.length > 0)
+						get(children, depth - 1, null);
+				} catch (CoreException e) {
+					throw FileSystemPlugin.wrapException(e);
+				}
+			}
+			progress.worked(1);
+		}
+		//TODO: release lock (i.e. diskFile should no longer be locked).
+		progress.done();
+	}
+
+	/**
+	 * @see SimpleAccessOperations#checkout(IResource[], int, IProgressMonitor)
+	 */
+	public void checkout(IResource[] resources, int depth, IProgressMonitor progress) throws TeamException {}
+
+	/**
+	 * Checkin the resources to the given depth.
+	 * @see org.eclipse.team.internal.core.simpleAccess.SimpleAccessOperations#checkin(IResource[], int, IProgressMonitor)
+	 */
+	public void checkin(IResource[] resources, int depth, IProgressMonitor progress) throws TeamException {
+		// ensure the progress monitor is not null
+		progress = Policy.monitorFor(progress);
+		progress.beginTask("Checking resources in...", resources.length);
+		for (int i = 0; i < resources.length; i++) {
+			Policy.checkCanceled(progress);
+			//TODO: verify that the resources are checked out.
+			IPath rootdir = provider.getRoot();
+			File diskFile = new File(rootdir.append(resources[i].getProjectRelativePath()).toOSString());
+			if (resources[i].getType() == IResource.FILE) {
+				//Copy the resource over to the other side:
+				IFile localFile = (IFile) resources[i]; //since we know the local resource is a file.
+				if (localFile.getModificationStamp() != diskFile.lastModified()) {
+					//Only do this if the timestamps are different
+					try {
+						diskFile.getParentFile().mkdirs();
+						//Copy from the local file to the remote file:
+						InputStream in = null;
+						FileOutputStream out = null;
+						try {
+							in = localFile.getContents();
+							out = new FileOutputStream(diskFile);
+							//Copy the contents of the local file to the remote file:
+							StreamUtil.pipe(in, out, diskFile.length(), progress, diskFile.getName());
+						} finally {
+							if (in != null)
+								in.close();
+							if (out != null)
+								out.close();
+						}
+					} catch (IOException e) {
+						throw FileSystemPlugin.wrapException(e);
+					} catch (CoreException e) {
+						throw FileSystemPlugin.wrapException(e);
+					}
+				}
+			} else if (depth > 0) { //Assume that resources are either files or containers.
+				diskFile.mkdirs();
+				//Recursively copy children, if any, over as well:
+				try {
+					IResource[] children;
+					if (resources[i].getType() == IResource.PROJECT)
+						children = provider.getProject().members();
+					else
+						children = provider.getProject().getFolder(resources[i].getName()).members();
+					if (children.length > 0)
+						checkin(children, depth - 1, null);
+				} catch (CoreException e) {
+					throw FileSystemPlugin.wrapException(e);
+				}
+			}
+			progress.worked(1);
+		}
+		//TODO: release lock (i.e. diskFile should no longer be locked).
+		progress.done();
+	}
+
+	/**
+	 * @see org.eclipse.team.internal.core.simpleAccess.SimpleAccessOperations#uncheckout(IResource[], int, IProgressMonitor)
+	 */
+	public void uncheckout(IResource[] resources, int depth, IProgressMonitor progress) throws TeamException {}
+
+	/**
+	 * @see org.eclipse.team.internal.core.simpleAccess.SimpleAccessOperations#delete(IResource[], IProgressMonitor)
+	 */
+	public void delete(IResource[] resources, IProgressMonitor progress) throws TeamException {}
+
+	/**
+	 * @see org.eclipse.team.internal.core.simpleAccess.SimpleAccessOperations#moved(IPath, IResource, IProgressMonitor)
+	 */
+	public void moved(IPath source, IResource target, IProgressMonitor progress) throws TeamException {}
+
+	/**
+	 * @see org.eclipse.team.internal.core.simpleAccess.SimpleAccessOperations#isCheckedOut(IResource)
+	 */
+	public boolean isCheckedOut(IResource resource) {
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.team.internal.core.simpleAccess.SimpleAccessOperations#hasRemote(IResource)
+	 */
+	public boolean hasRemote(IResource resource) {
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.team.internal.core.simpleAccess.SimpleAccessOperations#isDirty(IResource)
+	 */
+	public boolean isDirty(IResource resource) {
+		return false;
+	}
+
+}
diff --git a/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/Policy.java b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/Policy.java
new file mode 100644
index 0000000..e58e46a
--- /dev/null
+++ b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/Policy.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * Copyright (c) 2002 IBM Corporation and others.
+ * All rights reserved.   This program and the accompanying materials
+ * are made available under the terms of the Common Public License v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ * 
+ * Contributors:
+ * IBM - Initial API and implementation
+ ******************************************************************************/
+package org.eclipse.team.examples.filesystem;
+
+import java.text.MessageFormat;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+
+/**
+ * This class is a clone of the Polciy classes many Eclipse plugin suse to 
+ * provide NLSing of strings and aid in proper progress monitoring.
+ */
+public class Policy {
+	
+	protected static ResourceBundle bundle = null;
+
+	/**
+	 * Creates a NLS catalog for the given locale.
+	 */
+	public static void localize(String bundleName) {
+		bundle = ResourceBundle.getBundle(bundleName);
+	}
+	
+	/**
+	 * Lookup the message with the given ID in this catalog and bind its
+	 * substitution locations with the given string.
+	 */
+	public static String bind(String id, String binding) {
+		return bind(id, new String[] { binding });
+	}
+	
+	/**
+	 * Lookup the message with the given ID in this catalog and bind its
+	 * substitution locations with the given strings.
+	 */
+	public static String bind(String id, String binding1, String binding2) {
+		return bind(id, new String[] { binding1, binding2 });
+	}
+	
+	/**
+	 * Gets a string from the resource bundle. We don't want to crash because of a missing String.
+	 * Returns the key if not found.
+	 */
+	public static String bind(String key) {
+		try {
+			return bundle.getString(key);
+		} catch (MissingResourceException e) {
+			return key;
+		} catch (NullPointerException e) {
+			return "!" + key + "!";
+		}
+	}
+	
+	/**
+	 * Gets a string from the resource bundle and binds it with the given arguments. If the key is 
+	 * not found, return the key.
+	 */
+	public static String bind(String key, Object[] args) {
+		try {
+			return MessageFormat.format(bind(key), args);
+		} catch (MissingResourceException e) {
+			return key;
+		} catch (NullPointerException e) {
+			return "!" + key + "!";
+		}
+	}
+	
+	/**
+	 * Progress monitor helpers
+	 */
+	public static void checkCanceled(IProgressMonitor monitor) {
+		if (monitor.isCanceled())
+			throw new OperationCanceledException();
+	}
+	
+	public static IProgressMonitor monitorFor(IProgressMonitor monitor) {
+		if (monitor == null)
+			return new NullProgressMonitor();
+		return monitor;
+	}	
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/StreamUtil.java b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/StreamUtil.java
new file mode 100644
index 0000000..cdca08c
--- /dev/null
+++ b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/StreamUtil.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2002 IBM Corporation and others.
+ * All rights reserved.   This program and the accompanying materials
+ * are made available under the terms of the Common Public License v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ * 
+ * Contributors:
+ * IBM - Initial API and implementation
+ ******************************************************************************/
+package org.eclipse.team.examples.filesystem;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+
+public class StreamUtil {
+
+	protected final static byte[] COPY_BUFFER = new byte[4096];
+
+	public static void pipe(
+		InputStream in,
+		OutputStream out,
+		long sizeEstimate,
+		IProgressMonitor progress,
+		String title)
+		throws IOException {
+
+		// Only show progress for files larger than 25Kb.
+		Long kilobytesEstimate = new Long(sizeEstimate / 1024);
+		boolean showProgress = (progress != null) && (sizeEstimate > 25000);
+		long bytesCopied = 0;
+
+		synchronized (COPY_BUFFER) {
+			// Read the initial chunk.
+			int read = in.read(COPY_BUFFER, 0, COPY_BUFFER.length);
+
+			while (read != -1) {
+				out.write(COPY_BUFFER, 0, read);
+
+				// Report progress
+				if (showProgress) {
+					bytesCopied = bytesCopied + read;
+					progress.subTask(
+						Policy.bind(
+							"filetransfer.monitor",
+							new Object[] { title, new Long(bytesCopied / 1024), kilobytesEstimate }));
+				}
+
+				// Read the next chunk.
+				read = in.read(COPY_BUFFER, 0, COPY_BUFFER.length);
+			} // end while
+		} // end synchronized
+	}
+
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/messages.properties b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/messages.properties
new file mode 100644
index 0000000..de45f75
--- /dev/null
+++ b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/messages.properties
@@ -0,0 +1,24 @@
+fileSystem.propertyLocation=Location:
+
+FileSystemMainPage.location=Location:
+FileSystemMainPage.browseDir=&Browse...
+FileSystemMainPage.notValidLocation=Location must be an existing directory
+
+fsMainPage.name=Select a file system location
+fsMainPage.description=This location will be used to share resources with a team 
+
+ConfigurationWizard.errorTitle=Error configuring the provider.
+ConfigurationWizard.error=File System provider could not be created
+
+ConfigurationWizard.name=File System Repository
+ConfigurationWizard.description=File System Repository Properties
+
+DisconnectAction.errorTitle=Error Disconnecting
+
+PutAction.working=Putting resources...
+PutAction.problemMessage=A problem occured putting the resources.
+
+GetAction.working=Getting resources...
+GetAction.problemMessage=A problem occured getting the resources.
+
+FileSystemProvider.mustBeFolder=Target location ''{0}'' is a file and must be a folder.
\ No newline at end of file
diff --git a/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/ui/ConfigurationWizard.java b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/ui/ConfigurationWizard.java
new file mode 100644
index 0000000..0e0bbf3
--- /dev/null
+++ b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/ui/ConfigurationWizard.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (c) 2002 IBM Corporation and others.
+ * All rights reserved.   This program and the accompanying materials
+ * are made available under the terms of the Common Public License v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ * 
+ * Contributors:
+ * IBM - Initial API and implementation
+ ******************************************************************************/
+package org.eclipse.team.examples.filesystem.ui;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.Properties;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.dialogs.ProgressMonitorDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.team.core.RepositoryProvider;
+import org.eclipse.team.core.Team;
+import org.eclipse.team.core.TeamException;
+import org.eclipse.team.examples.filesystem.FileSystemPlugin;
+import org.eclipse.team.examples.filesystem.FileSystemProvider;
+import org.eclipse.team.examples.filesystem.Policy;
+import org.eclipse.team.ui.IConfigurationWizard;
+import org.eclipse.ui.IWorkbench;
+
+/**
+ * The file system configuration wizard used when associating a project
+ * the the file system provider. It is registered as a Team configuration wizard
+ * in the plugin.xml and is invoked when a user chooses to create a File System
+ * Repository Provider. One invoked, this wizard makes use of the <code>FileSystemMainPage</code>
+ * in order to obtain a target locaton on disk.
+ */
+public class ConfigurationWizard extends Wizard implements IConfigurationWizard {
+	
+	IProject project;
+	
+	FileSystemMainPage mainPage;
+	
+	public ConfigurationWizard() {
+		// retrieve the remembered dialog settings
+		IDialogSettings workbenchSettings = FileSystemPlugin.getPlugin().getDialogSettings();
+		IDialogSettings section = workbenchSettings.getSection("ProviderExamplesWizard"); //$NON-NLS-1$
+		if (section == null) {
+			section = workbenchSettings.addNewSection("ProviderExamplesWizard"); //$NON-NLS-1$
+		}
+		setDialogSettings(section);
+	}
+
+	/**
+	 * Remember the project so we can map it on finish
+	 * 
+	 * @see org.eclipse.team.ui.IConfigurationWizard#init(IWorkbench, IProject)
+	 */
+	public void init(IWorkbench workbench, IProject project) {
+		this.project = project;
+	}
+	
+	public void addPages() {
+		mainPage = new FileSystemMainPage(
+			"FileSystemMainPage", //$NON-NLS-1$
+			Policy.bind("ConfigurationWizard.name"), 
+			Policy.bind("ConfigurationWizard.description"), 
+			null);
+		addPage(mainPage);
+	}
+	
+	/*
+	 * Using the information entered in the main page set the provider for
+	 * the given project.
+	 */
+	public boolean performFinish() {
+		mainPage.finish(null);
+		try {
+			// Map the provider and set the location
+			RepositoryProvider.map(project, FileSystemPlugin.PROVIDER_ID);
+			FileSystemProvider provider = (FileSystemProvider) RepositoryProvider.getProvider(project);
+			provider.setTargetLocation(mainPage.getLocation());
+		} catch (TeamException e) {
+			ErrorDialog.openError(
+				getShell(),
+				Policy.bind("ConfigurationWizard.errorMapping"),
+				Policy.bind("ConfigurationWizard.error"),
+				e.getStatus());
+			return false;
+		}
+		return true;
+	}
+
+}
diff --git a/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/ui/DisconnectAction.java b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/ui/DisconnectAction.java
new file mode 100644
index 0000000..d8a61f6
--- /dev/null
+++ b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/ui/DisconnectAction.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2002 IBM Corporation and others.
+ * All rights reserved.   This program and the accompanying materials
+ * are made available under the terms of the Common Public License v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ * 
+ * Contributors:
+ * IBM - Initial API and implementation
+ ******************************************************************************/
+package org.eclipse.team.examples.filesystem.ui;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.team.core.RepositoryProvider;
+import org.eclipse.team.core.TeamException;
+import org.eclipse.team.examples.filesystem.Policy;
+import org.eclipse.team.internal.ui.actions.TeamAction;
+
+/**
+ * Action for getting the contents of the selected resources
+ */
+public class DisconnectAction extends TeamAction {
+	
+	/**
+	 * @see org.eclipse.ui.IActionDelegate#run(IAction)
+	 */
+	public void run(IAction action) {
+		IProject projects[] = getSelectedProjects();
+		try {
+			for (int i = 0; i < projects.length; i++) {
+				RepositoryProvider.unmap(projects[i]);
+			}
+		} catch (TeamException e) {
+			ErrorDialog.openError(getShell(), Policy.bind("DisconnectAction.errorTitle"), null, e.getStatus());
+		} 
+	}
+	
+	/**
+	 * @see TeamAction#isEnabled()
+	 */
+	protected boolean isEnabled() {
+		return true;
+	}
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/ui/FileSystemAction.java b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/ui/FileSystemAction.java
new file mode 100644
index 0000000..6bf4098
--- /dev/null
+++ b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/ui/FileSystemAction.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2002 IBM Corporation and others.
+ * All rights reserved.   This program and the accompanying materials
+ * are made available under the terms of the Common Public License v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ * 
+ * Contributors:
+ * IBM - Initial API and implementation
+ ******************************************************************************/
+package org.eclipse.team.examples.filesystem.ui;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.team.core.RepositoryProvider;
+import org.eclipse.team.core.TeamException;
+import org.eclipse.team.examples.filesystem.FileSystemPlugin;
+import org.eclipse.team.internal.ui.actions.TeamAction;
+
+/**
+ * An abstract class that acts as a super class for FileSystemProvider actions.
+ * It provides some general methods applicable to multipe actions.
+ */
+public abstract class FileSystemAction extends TeamAction {
+
+	/**
+	 * @see org.eclipse.team.internal.ui.actions.TeamAction#isEnabled()
+	 */
+	protected boolean isEnabled() {
+		IResource[] resources = getSelectedResources();
+		if (resources.length == 0)
+			return false;
+		for (int i = 0; i < resources.length; i++) {
+			IResource resource = resources[i];
+			// we only want to work on resources mapped to a file system provider
+			RepositoryProvider provider = RepositoryProvider.getProvider(resource.getProject(), FileSystemPlugin.PROVIDER_ID);
+			if (provider == null)
+				return false;
+		}
+		return true;
+	}
+
+	/**
+	 * Split the resources into sets associated with their project/provider
+	 */
+	protected Map getRepositoryProviderMapping() throws TeamException {
+		HashMap result = new HashMap();
+		IResource[] resources = getSelectedResources();
+		for (int i = 0; i < resources.length; i++) {
+			RepositoryProvider provider = RepositoryProvider.getProvider(resources[i].getProject());
+			List list = (List) result.get(provider);
+			if (list == null) {
+				list = new ArrayList();
+				result.put(provider, list);
+			}
+			list.add(resources[i]);
+		}
+		return result;
+	}
+	
+}
diff --git a/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/ui/FileSystemMainPage.java b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/ui/FileSystemMainPage.java
new file mode 100644
index 0000000..063053d
--- /dev/null
+++ b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/ui/FileSystemMainPage.java
@@ -0,0 +1,301 @@
+/*******************************************************************************
+ * Copyright (c) 2002 IBM Corporation and others.
+ * All rights reserved.   This program and the accompanying materials
+ * are made available under the terms of the Common Public License v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ * 
+ * Contributors:
+ * IBM - Initial API and implementation
+ ******************************************************************************/
+package org.eclipse.team.examples.filesystem.ui;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.DirectoryDialog;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.team.examples.filesystem.Policy;
+
+/**
+ * This class provides the main page of the file system repository configuration wizard.
+ * It allows the user to select a location on disk. Once the page is finished, the
+ * location can be accessed using the <code>getLocation()</code> method.
+ */
+public class FileSystemMainPage extends WizardPage {
+	
+	private static final int COMBO_HISTORY_LENGTH = 5;
+	
+	String location;
+	Combo locationCombo;
+	
+	/*
+	 * WizardPage constructor comment.
+	 * @param pageName  the name of the page
+	 * @param title  the title of the page
+	 * @param description  the description of the page
+	 * @param titleImage  the image for the page
+	 */
+
+	public FileSystemMainPage(String pageName, String title, String description, ImageDescriptor titleImage) {
+		super(pageName, title, titleImage);
+		setDescription(description);
+		setTitle(title);
+	}
+		
+	/*
+	 * Creates a new checkbox instance and sets the default layout data.
+	 *
+	 * @param group  the composite in which to create the checkbox
+	 * @param label  the string to set into the checkbox
+	 * @return the new checkbox
+	 */ 
+	protected Button createCheckBox(Composite group, String label) {
+		Button button = new Button(group, SWT.CHECK | SWT.LEFT);
+		button.setText(label);
+		GridData data = new GridData();
+		data.horizontalSpan = 2;
+		button.setLayoutData(data);
+		return button;
+	}
+	
+	/*
+	 * Utility method that creates a combo box
+	 *
+	 * @param parent  the parent for the new label
+	 * @return the new widget
+	 */
+	protected Combo createCombo(Composite parent) {
+		Combo combo = new Combo(parent, SWT.READ_ONLY);
+		GridData data = new GridData(GridData.FILL_HORIZONTAL);
+		data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH;
+		combo.setLayoutData(data);
+		return combo;
+	}
+	
+	/*
+	 * Creates composite control and sets the default layout data.
+	 *
+	 * @param parent  the parent of the new composite
+	 * @param numColumns  the number of columns for the new composite
+	 * @return the newly-created coposite
+	 */
+	protected Composite createComposite(Composite parent, int numColumns) {
+		Composite composite = new Composite(parent, SWT.NULL);
+	
+		// GridLayout
+		GridLayout layout = new GridLayout();
+		layout.numColumns = numColumns;
+		composite.setLayout(layout);
+	
+		// GridData
+		GridData data = new GridData();
+		data.verticalAlignment = GridData.FILL;
+		data.horizontalAlignment = GridData.FILL;
+		composite.setLayoutData(data);
+		return composite;
+	}
+	
+	/*
+	 * Utility method that creates a label instance
+	 * and sets the default layout data.
+	 *
+	 * @param parent  the parent for the new label
+	 * @param text  the text for the new label
+	 * @return the new label
+	 */
+	protected Label createLabel(Composite parent, String text) {
+		Label label = new Label(parent, SWT.LEFT);
+		label.setText(text);
+		GridData data = new GridData();
+		data.horizontalSpan = 1;
+		data.horizontalAlignment = GridData.FILL;
+		label.setLayoutData(data);
+		return label;
+	}
+	
+	/*
+	 * Create a text field specific for this application
+	 *
+	 * @param parent  the parent of the new text field
+	 * @return the new text field
+	 */
+	protected Text createTextField(Composite parent) {
+		Text text = new Text(parent, SWT.SINGLE | SWT.BORDER);
+		GridData data = new GridData(GridData.FILL_HORIZONTAL);
+		data.verticalAlignment = GridData.CENTER;
+		data.grabExcessVerticalSpace = false;
+		data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH;
+		text.setLayoutData(data);
+		return text;
+	}
+	
+	/*
+	 * Adds an entry to a history, while taking care of duplicate history items
+	 * and excessively long histories.  The assumption is made that all histories
+	 * should be of length <code>ConfigurationWizardMainPage.COMBO_HISTORY_LENGTH</code>.
+	 *
+	 * @param history the current history
+	 * @param newEntry the entry to add to the history
+	 * @return the history with the new entry appended
+	 */
+	protected String[] addToHistory(String[] history, String newEntry) {
+		ArrayList l = new ArrayList(Arrays.asList(history));
+		addToHistory(l, newEntry);
+		String[] r = new String[l.size()];
+		l.toArray(r);
+		return r;
+	}
+	
+	/*
+	 * Adds an entry to a history, while taking care of duplicate history items
+	 * and excessively long histories.  The assumption is made that all histories
+	 * should be of length <code>ConfigurationWizardMainPage.COMBO_HISTORY_LENGTH</code>.
+	 *
+	 * @param history the current history
+	 * @param newEntry the entry to add to the history
+	 */
+	protected void addToHistory(List history, String newEntry) {
+		history.remove(newEntry);
+		history.add(0,newEntry);
+	
+		// since only one new item was added, we can be over the limit
+		// by at most one item
+		if (history.size() > COMBO_HISTORY_LENGTH)
+			history.remove(COMBO_HISTORY_LENGTH);
+	}
+	
+	/*
+	 * Utility method to create an editable combo box
+	 * 
+	 * @param parent  the parent of the combo box
+	 * @return the created combo
+	 */
+	protected Combo createEditableCombo(Composite parent) {
+		Combo combo = new Combo(parent, SWT.NULL);
+		GridData data = new GridData(GridData.FILL_HORIZONTAL);
+		data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH;
+		combo.setLayoutData(data);
+		return combo;
+	}
+	
+	// Dialog store id constants
+	private static final String STORE_LOCATION =
+		"ExamplesFSWizardMainPage.STORE_LOCATION";//$NON-NLS-1$
+	
+	public void createControl(Composite parent) {
+		Composite composite = new Composite(parent, SWT.NULL);
+		composite.setLayoutData(new GridData(GridData.FILL_BOTH));
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 2;
+		composite.setLayout(layout);
+		setControl(composite);
+		
+		Label label = new Label(composite, SWT.NULL);
+		label.setText(Policy.bind("FileSystemMainPage.location"));
+		label.setLayoutData(new GridData());
+		
+		locationCombo = createEditableCombo(composite);
+		locationCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		locationCombo.addListener(SWT.Modify, new Listener() {
+			public void handleEvent(Event e) {
+				location = ((Combo)e.widget).getText();
+				FileSystemMainPage.this.validateFields();		
+			}
+		});
+		
+		locationCombo.setFocus();
+		
+		new Label(composite, SWT.NULL);
+		Button browse = new Button(composite, SWT.NULL);
+		browse.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
+		browse.setText(Policy.bind("FileSystemMainPage.browseDir"));
+		browse.addListener(SWT.Selection, new Listener() {
+			public void handleEvent(Event event) {
+				DirectoryDialog d = new DirectoryDialog(getShell());
+				String directory = d.open();
+				if(directory!=null) {
+					locationCombo.setText(directory);
+				}			
+			}
+		});
+	
+		initializeValues();
+		validateFields();
+	}
+	
+	public String getLocation() {
+		return location;
+	}
+
+	public boolean finish(IProgressMonitor monitor) {
+		saveWidgetValues();
+		return true;
+	}
+	/**
+	 * Initializes states of the controls.
+	 */
+	private void initializeValues() {
+		IDialogSettings settings = getDialogSettings();
+		if (settings != null) {
+			String[] locations = settings.getArray(STORE_LOCATION);
+			if (locations != null) {
+				for (int i = 0; i < locations.length; i++) {
+					locationCombo.add(locations[i]);
+				}
+				locationCombo.select(0);
+			}
+		}
+	}
+	/**
+	 * Saves the widget values
+	 */
+	private void saveWidgetValues() {
+		// Update history
+		IDialogSettings settings = getDialogSettings();
+		if (settings != null) {
+			String[] locations = settings.getArray(STORE_LOCATION);
+			if (locations == null) locations = new String[0];
+			locations = addToHistory(locations, locationCombo.getText());
+			settings.put(STORE_LOCATION, locations);	
+		}
+	}
+	
+	/*
+	 * Validates the contents of the editable fields and set page completion 
+	 * and error messages appropriately.
+	 */
+	private void validateFields() {
+		String location = locationCombo.getText();
+		if (location.length() == 0) {
+			setErrorMessage(null);
+			setPageComplete(false);
+			return;
+		} else {
+			File file = new File(location);
+			if(!file.exists() || !file.isDirectory()) {
+				setErrorMessage(Policy.bind("FileSystemMainPage.notValidLocation"));
+				setPageComplete(false);
+				return;				
+			}			
+		}
+		setErrorMessage(null);
+		setPageComplete(true);
+	}
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/ui/FileSystemPropertiesPage.java b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/ui/FileSystemPropertiesPage.java
new file mode 100644
index 0000000..bd8a472
--- /dev/null
+++ b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/ui/FileSystemPropertiesPage.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright (c) 2002 IBM Corporation and others.
+ * All rights reserved.   This program and the accompanying materials
+ * are made available under the terms of the Common Public License v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ * 
+ * Contributors:
+ * IBM - Initial API and implementation
+ ******************************************************************************/
+package org.eclipse.team.examples.filesystem.ui;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.team.core.RepositoryProvider;
+import org.eclipse.team.examples.filesystem.FileSystemProvider;
+import org.eclipse.team.examples.filesystem.Policy;
+import org.eclipse.ui.dialogs.PropertyPage;
+/*
+ * A property page which displays the  file system specific properties 
+ * for the selected resource.
+ */
+public class FileSystemPropertiesPage extends PropertyPage {
+	// The resource to show properties for
+	protected IResource resource;
+
+	/*	 
+	 * Creates a key-value property pair in the given parent.
+	 * 
+	 * @param parent  the parent for the labels
+	 * @param left  the string for the left label
+	 * @param right  the string for the right label
+	 */
+	protected void createPair(Composite parent, String left, String right) {
+		Label label = new Label(parent, SWT.NONE);
+		label.setText(left);
+	
+		label = new Label(parent, SWT.NONE);
+		label.setText(right);
+		label.setToolTipText(right);
+		label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+	}
+
+	/*
+	 * Returns the element selected when the properties was run
+	 * @return the selected element
+	 */	
+	protected IResource getSelectedElement() {
+		// get the resource that is the source of this property page
+		IResource resource = null;
+		IAdaptable element = getElement();
+		if (element instanceof IResource) {
+			resource = (IResource)element;
+		} else {
+			Object adapter = element.getAdapter(IResource.class);
+			if (adapter instanceof IResource) {
+				resource = (IResource)adapter;
+			}
+		}
+		return resource;
+	}
+	
+	/*
+	 * @see PreferencePage#createContents(Composite)
+	 */
+	protected Control createContents(Composite parent) {
+		Composite composite = new Composite(parent, SWT.NONE);
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 2;
+		layout.marginHeight = layout.marginWidth = 0;
+		composite.setLayout(layout);
+		composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+				
+		IResource resource = getSelectedElement();
+		RepositoryProvider provider = RepositoryProvider.getProvider(resource.getProject());
+		return composite;
+	}
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/ui/GetAction.java b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/ui/GetAction.java
new file mode 100644
index 0000000..6b7519d
--- /dev/null
+++ b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/ui/GetAction.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2002 IBM Corporation and others.
+ * All rights reserved.   This program and the accompanying materials
+ * are made available under the terms of the Common Public License v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ * 
+ * Contributors:
+ * IBM - Initial API and implementation
+ ******************************************************************************/
+package org.eclipse.team.examples.filesystem.ui;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.team.core.TeamException;
+import org.eclipse.team.examples.filesystem.FileSystemProvider;
+import org.eclipse.team.examples.filesystem.Policy;
+import org.eclipse.ui.actions.WorkspaceModifyOperation;
+
+/**
+ * Action for getting the contents of the selected resources
+ */
+public class GetAction extends FileSystemAction {
+	
+	public void run(IAction action) {
+		run(new WorkspaceModifyOperation() {
+			public void execute(IProgressMonitor monitor) throws InterruptedException, InvocationTargetException {
+				try {
+					Map table = getRepositoryProviderMapping();
+					monitor.beginTask(null, table.size() * 1000);
+					monitor.setTaskName(Policy.bind("GetAction.working")); //$NON-NLS-1$
+					for (Iterator iter = table.keySet().iterator(); iter.hasNext();) {
+						IProgressMonitor subMonitor = new SubProgressMonitor(monitor, 1000);
+						FileSystemProvider provider = (FileSystemProvider) iter.next();
+						List list = (List) table.get(provider);
+						IResource[] providerResources = (IResource[]) list.toArray(new IResource[list.size()]);
+						provider.getSimpleAccess().get(providerResources, IResource.DEPTH_INFINITE, subMonitor);
+					}
+				} catch (TeamException e) {
+					throw new InvocationTargetException(e);
+				} finally {
+					monitor.done();
+				}
+			}
+		}, Policy.bind("GetAction.problemMessage"), this.PROGRESS_DIALOG); //$NON-NLS-1$
+	}
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/ui/PutAction.java b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/ui/PutAction.java
new file mode 100644
index 0000000..5671258
--- /dev/null
+++ b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/ui/PutAction.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2002 IBM Corporation and others.
+ * All rights reserved.   This program and the accompanying materials
+ * are made available under the terms of the Common Public License v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ * 
+ * Contributors:
+ * IBM - Initial API and implementation
+ ******************************************************************************/
+package org.eclipse.team.examples.filesystem.ui;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.team.core.TeamException;
+import org.eclipse.team.examples.filesystem.FileSystemProvider;
+import org.eclipse.team.examples.filesystem.Policy;
+import org.eclipse.ui.actions.WorkspaceModifyOperation;
+
+/**
+ * Action for checking in the selected resources
+ */
+public class PutAction extends FileSystemAction {
+
+	/*
+	 * Method declared on IActionDelegate.
+	 */
+	public void run(IAction action) {
+		run(new WorkspaceModifyOperation() {
+			public void execute(IProgressMonitor monitor) throws InterruptedException, InvocationTargetException {
+				try {
+					Map table = getRepositoryProviderMapping();
+					monitor.beginTask(null, table.size() * 1000);
+					monitor.setTaskName(Policy.bind("PutAction.working")); //$NON-NLS-1$
+					for (Iterator iter = table.keySet().iterator(); iter.hasNext();) {
+						IProgressMonitor subMonitor = new SubProgressMonitor(monitor, 1000);
+						FileSystemProvider provider = (FileSystemProvider) iter.next();
+						List list = (List) table.get(provider);
+						IResource[] providerResources = (IResource[]) list.toArray(new IResource[list.size()]);
+						provider.getSimpleAccess().checkin(providerResources, IResource.DEPTH_INFINITE, subMonitor);
+					}
+				} catch (TeamException e) {
+					throw new InvocationTargetException(e);
+				} finally {
+					monitor.done();
+				}
+			}
+		}, Policy.bind("PutAction.problemMessage"), this.PROGRESS_DIALOG); //$NON-NLS-1$
+	}
+}