Fixed file revision fetching
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/messages.properties b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/messages.properties
index 6d7ecf7..95daa26 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/messages.properties
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/messages.properties
@@ -49,6 +49,7 @@
 ManagedFile.sending=Sending file {0}
 ManagedFile.transfer={0} ({1}K of {2}K bytes)
 
+RemoteFolder.errorFetchingRevisions=Error fetching file revision numbers
 RemoteManagedResource.invalidOperation=Invalid operation performed on remote resource
 RemoteManagedFolder.invalidChild=Invalid folder {0} received during remote operation
 
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteFile.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteFile.java
index 2fc18dc..03790b3 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteFile.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteFile.java
@@ -40,7 +40,7 @@
 	public InputStream getContents(final IProgressMonitor monitor) throws TeamException {
 			
 		// Perform a "cvs update..."
-		RemoteManagedFolder folder = new RemoteManagedFolder(".", getConnection(), parent.getFullPath(), getName());
+		RemoteManagedFolder folder = new RemoteManagedFolder(".", getConnection(), getParentPath(), new String[] {getName()});
 		List localOptions = getLocalOptionsForTag();
 		Client.execute(
 			Client.UPDATE,
@@ -60,16 +60,13 @@
 	 */
 	public ILogEntry[] getLogEntries(IProgressMonitor monitor) throws CVSException {
 		
-		// NOTE: Should we be using the localOptions here?
-		
-		// Perform a "cvs status..." with a custom message hanlder
-		RemoteManagedFolder folder = new RemoteManagedFolder(".", getConnection(), parent.getFullPath(), getName());
-		List localOptions = getLocalOptionsForTag();
+		// Perform a "cvs log..." with a custom message handler
+		RemoteManagedFolder folder = new RemoteManagedFolder(".", getConnection(), getParentPath(), new String[] {getName()});
 		final List entries = new ArrayList();
 		Client.execute(
 			Client.LOG,
 			Client.EMPTY_ARGS_LIST, 
-			(String[])localOptions.toArray(new String[localOptions.size()]),
+			Client.EMPTY_ARGS_LIST,
 			new String[]{getName()}, 
 			folder,
 			monitor,
@@ -83,29 +80,10 @@
 	 * @see IRemoteFile#getRevision()
 	 */
 	public String getRevision(IProgressMonitor monitor) throws CVSException {
-		
-		// Create a listener for receiving the revision info
-		final String[] revision = new String[] { null };
-		IStatusListener listener = new IStatusListener() {
-			public void fileStatus(IPath path, String remoteRevision) {
-				revision[0] = remoteRevision;
-			}
-		};
-			
-		// Perform a "cvs status..." with a custom message hanlder
-		RemoteManagedFolder folder = new RemoteManagedFolder(".", getConnection(), parent.getFullPath(), getName());
-		List localOptions = getLocalOptionsForTag();
-		Client.execute(
-			Client.STATUS,
-			Client.EMPTY_ARGS_LIST, 
-			(String[])localOptions.toArray(new String[localOptions.size()]),
-			new String[]{getName()}, 
-			folder,
-			monitor,
-			CVSTeamProvider.getPrintStream(),
-			getConnection(),
-			new IResponseHandler[] {new StatusMessageHandler(listener)});
-		return revision[0];
+		return tag;
+	}
+	public String getRevision() {
+		return tag;
 	}
 	
 	/**
@@ -115,8 +93,8 @@
 		return FILE;
 	}
 	
-	public RemoteFileRevision toRemoteFileRevision(String revision) {
-		return new RemoteFileRevision(parent, getName(), revision);
+	public RemoteFile toRemoteFileRevision(String revision) {
+		return new RemoteFile(parent, getName(), revision);
 	}
 }
 
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteFileRevision.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteFileRevision.java
deleted file mode 100644
index 21ea6f6..0000000
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteFileRevision.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package org.eclipse.team.internal.ccvs.core.resources;

-

-/*

- * (c) Copyright IBM Corp. 2000, 2001.

- * All Rights Reserved.

- */

-

-import org.eclipse.core.runtime.IProgressMonitor;

-import org.eclipse.team.internal.ccvs.core.CVSException;

- 

- /**

-  * Same as a RemoteFile except that the tag is fixed to a particular revision

-  */

-public class RemoteFileRevision extends RemoteFile {

-

-	/**

-	 * Constructor for RemoteFileRevision.

-	 * @param parent

-	 * @param name

-	 * @param tag

-	 */

-	protected RemoteFileRevision(RemoteFolder parent, String name, String tag) {

-		super(parent, name, tag);

-	}

-	

-	/**

-	 * @see IRemoteFile#getRevision()

-	 */

-	public String getRevision(IProgressMonitor monitor) throws CVSException {

-		return tag;

-	}

-	

-	public String getRevision() {

-		return tag;

-	}

-

-}

-

diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteFolder.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteFolder.java
index 4245fac..835eb67 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteFolder.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteFolder.java
@@ -6,21 +6,30 @@
  */
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.Path;
-import org.eclipse.team.core.TeamException;
-import org.eclipse.team.internal.ccvs.core.CVSException;
-import org.eclipse.team.internal.ccvs.core.Client;
-import org.eclipse.team.internal.ccvs.core.response.IResponseHandler;
-import org.eclipse.team.internal.ccvs.core.response.custom.IUpdateMessageListener;
-import org.eclipse.team.internal.ccvs.core.response.custom.UpdateErrorHandler;
-import org.eclipse.team.internal.ccvs.core.response.custom.UpdateMessageHandler;
 import org.eclipse.team.ccvs.core.CVSTeamProvider;
 import org.eclipse.team.ccvs.core.IRemoteFolder;
 import org.eclipse.team.ccvs.core.IRemoteResource;
+import org.eclipse.team.core.TeamException;
+import org.eclipse.team.internal.ccvs.core.CVSException;
+import org.eclipse.team.internal.ccvs.core.Client;
+import org.eclipse.team.internal.ccvs.core.Policy;
+import org.eclipse.team.internal.ccvs.core.commands.CommandDispatcher;
+import org.eclipse.team.internal.ccvs.core.connection.Connection;
+import org.eclipse.team.internal.ccvs.core.requests.RequestSender;
+import org.eclipse.team.internal.ccvs.core.response.IResponseHandler;
+import org.eclipse.team.internal.ccvs.core.response.ResponseDispatcher;
+import org.eclipse.team.internal.ccvs.core.response.custom.IStatusListener;
+import org.eclipse.team.internal.ccvs.core.response.custom.IUpdateMessageListener;
+import org.eclipse.team.internal.ccvs.core.response.custom.StatusMessageHandler;
+import org.eclipse.team.internal.ccvs.core.response.custom.UpdateErrorHandler;
+import org.eclipse.team.internal.ccvs.core.response.custom.UpdateMessageHandler;
 
 /**
  * This class provides the implementation of IRemoteFolder
@@ -34,6 +43,57 @@
 		super(parent, name, tag);
 	}
 
+	// Get the file revisions for the given filenames
+	protected String[] getFileRevisions(Connection connection, String[] fileNames, IProgressMonitor monitor) throws CVSException {
+		
+		// Create a listener for receiving the revision info
+		final Map revisions = new HashMap();
+		IStatusListener listener = new IStatusListener() {
+			public void fileStatus(IPath path, String remoteRevision) {
+				revisions.put(path.lastSegment(), remoteRevision);
+			}
+		};
+			
+		// Perform a "cvs status..." with a custom message hanlder
+		RemoteManagedFolder folder = new RemoteManagedFolder(".", getConnection(), getFullPath(), fileNames, tag);
+		List localOptions = getLocalOptionsForTag();
+		
+		// NOTE: This should be in a single methodin Client
+		ResponseDispatcher responseDispatcher = new ResponseDispatcher(connection, new IResponseHandler[] {new StatusMessageHandler(listener)});
+		RequestSender requestSender = new RequestSender(connection);
+		CommandDispatcher commandDispatcher = new CommandDispatcher(responseDispatcher, requestSender);		
+		commandDispatcher.execute(
+			Client.STATUS,
+			Client.EMPTY_ARGS_LIST, 
+			(String[])localOptions.toArray(new String[localOptions.size()]),
+			fileNames,
+			folder,
+			monitor,
+			CVSTeamProvider.getPrintStream());
+
+//		client.execute(
+//			Client.STATUS,
+//			Client.EMPTY_ARGS_LIST, 
+//			(String[])localOptions.toArray(new String[localOptions.size()]),
+//			fileNames,
+//			folder,
+//			monitor,
+//			CVSTeamProvider.getPrintStream(),
+//			connection,
+//			new IResponseHandler[] {new StatusMessageHandler(listener)});
+		
+		if (revisions.size() != fileNames.length)
+			throw new CVSException(Policy.bind("RemoteFolder.errorFetchingRevisions"));
+		String[] result = new String[fileNames.length];
+		for (int i=0;i<fileNames.length;i++) {
+			String revision = (String)revisions.get(fileNames[i]);
+			if (revision == null)
+				throw new CVSException(Policy.bind("RemoteFolder.errorFetchingRevisions"));
+			result[i] = revision;
+		}
+		return result;
+	}
+	
 	/**
 	 * @see IRemoteFolder#getMembers()
 	 */
@@ -78,9 +138,12 @@
 			localOptions.add(Client.TAG_OPTION);
 			localOptions.add(tagName);
 		}
-			
-		// Perform a "cvs -n update -d -r tagName folderName" with custom message and error handlers
+		
+		// Retrieve the children and any file revision numbers in a single connection
+		Connection c = getConnection().openConnection();
+		List result = new ArrayList();
 		try {
+			// Perform a "cvs -n update -d -r tagName folderName" with custom message and error handlers
 			Client.execute(
 				Client.UPDATE,
 				new String[]{Client.NOCHANGE_OPTION}, 
@@ -89,16 +152,26 @@
 				new RemoteManagedFolder(".", getConnection(), getFullPath()),
 				monitor,
 				CVSTeamProvider.getPrintStream(),
-				getConnection(),
+				c,
 				new IResponseHandler[]{new UpdateMessageHandler(listener), new UpdateErrorHandler(listener, errors)});
+			// Get the revision numbers for the files
+			
+			if (newRemoteFiles.size() > 0) {
+				String[] revisions = getFileRevisions(c, (String[])newRemoteFiles.toArray(new String[newRemoteFiles.size()]), monitor);
+				for (int i=0;i<newRemoteFiles.size();i++) {
+					result.add(new RemoteFile(this, (String)newRemoteFiles.get(i), revisions[i]));
+				}
+			}
+			for (int i=0;i<newRemoteDirectories.size();i++)
+				result.add(new RemoteFolder(this, (String)newRemoteDirectories.get(i), tagName));
+
+
+			
 		} catch (CVSException e) {
 			throw CVSTeamProvider.wrapException(e, errors);
+		} finally {
+			c.close();
 		}
-		List result = new ArrayList();
-		for (int i=0;i<newRemoteDirectories.size();i++)
-			result.add(new RemoteFolder(this, (String)newRemoteDirectories.get(i), tagName));
-		for (int i=0;i<newRemoteFiles.size();i++)
-			result.add(new RemoteFile(this, (String)newRemoteFiles.get(i), tagName));
 		return (IRemoteResource[])result.toArray(new IRemoteResource[0]);
 	}
 
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteManagedFolder.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteManagedFolder.java
index e7b1fca..5b3d628 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteManagedFolder.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteManagedFolder.java
@@ -5,6 +5,10 @@
  * All Rights Reserved.
  */
 
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.team.ccvs.core.ICVSRepositoryLocation;
 import org.eclipse.team.internal.ccvs.core.CVSException;
 import org.eclipse.team.internal.ccvs.core.Client;
 import org.eclipse.team.internal.ccvs.core.Policy;
@@ -13,7 +17,6 @@
 import org.eclipse.team.internal.ccvs.core.resources.api.IManagedFolder;
 import org.eclipse.team.internal.ccvs.core.resources.api.IManagedResource;
 import org.eclipse.team.internal.ccvs.core.resources.api.IManagedVisitor;
-import org.eclipse.team.ccvs.core.ICVSRepositoryLocation;
 
 /**
  * This class can be used to pass an empty folder to CVS in order to see
@@ -26,19 +29,27 @@
  */
 public class RemoteManagedFolder extends RemoteManagedResource implements IManagedFolder {
 	
-	// NIK: Comment for the "one child" solution ?
-	private RemoteManagedFile child;
+	private Map children;
 	protected String remote;
+	protected String tag;
 	
 	public RemoteManagedFolder(String name, ICVSRepositoryLocation repository, String remote) {
 		this(name, repository, remote, null);
 	}
 	
-	public RemoteManagedFolder(String name, ICVSRepositoryLocation repository, String remote, String child) {
+	public RemoteManagedFolder(String name, ICVSRepositoryLocation repository, String remote, String[] children) {
+		this(name, repository, remote, children, null);
+	}
+
+	public RemoteManagedFolder(String name, ICVSRepositoryLocation repository, String remote, String[] children, String tag) {
 		super(name, null, repository);
 		this.remote = remote;
-		if (child != null)
-			this.child = new RemoteManagedFile(child, this, repository);
+		this.tag = tag;
+		if (children != null) {
+			this.children = new HashMap();
+			for (int i=0;i<children.length;i++)
+				this.children.put(children[i], new RemoteManagedFile(children[i], this, repository));
+		}
 	}
 	
 	/**
@@ -52,10 +63,10 @@
 	 * @see IManagedFolder#getFiles()
 	 */
 	public IManagedFile[] getFiles() throws CVSException {
-		if (child == null)
+		if (children == null)
 			return new IManagedFile[0];
 		else
-			return new IManagedFile[] {child};
+			return (IManagedFile[])children.entrySet().toArray(new IManagedFile[children.size()]);
 	}
 
 	/**
@@ -98,8 +109,11 @@
 	public IManagedResource getChild(String path) throws CVSException {
 		if (path.equals(Client.CURRENT_LOCAL_FOLDER))
 			return this;
-		if ((child != null) && (path.equals(child.getName())))
-			return child;
+		if (children != null) {
+			IManagedResource resource = (IManagedResource) children.get(path);
+			if (resource != null)
+				return resource;
+		}
 		throw new CVSException(Policy.bind("RemoteManagedFolder.invalidChild", new Object[] {name}));
 	}
 
@@ -120,7 +134,10 @@
 	 * @see IManagedFolder#getFolderInfo()
 	 */
 	public FolderProperties getFolderInfo() throws CVSException {
-		return new FolderProperties(repository.getLocation(), remote, false);
+		FolderProperties fp = new FolderProperties(repository.getLocation(), remote, false);
+		if (tag != null)
+			fp.setTag(tag);
+		return fp;
 	}
 
 	/**
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteResource.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteResource.java
index 0df7439..6ea2248 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteResource.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteResource.java
@@ -53,6 +53,13 @@
 	}
 	
 	/**
+	 * Get the path of the parent, starting at the root
+	 */
+	public String getParentPath() {
+		return parent.getFullPath();
+	}
+	
+	/**
 	 * Return the IRemoteRoot that is the ancestor of the receiver
 	 */
 	public IRemoteRoot getRemoteRoot() {
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/response/custom/LogEntry.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/response/custom/LogEntry.java
index 8d8fc1d..a1d4741 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/response/custom/LogEntry.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/response/custom/LogEntry.java
@@ -5,15 +5,14 @@
  * All Rights Reserved.
  */
  
-import org.eclipse.team.internal.ccvs.core.resources.RemoteFile;
-import org.eclipse.team.internal.ccvs.core.resources.RemoteFileRevision;
 import org.eclipse.core.runtime.PlatformObject;
 import org.eclipse.team.ccvs.core.ILogEntry;
 import org.eclipse.team.ccvs.core.IRemoteFile;
+import org.eclipse.team.internal.ccvs.core.resources.RemoteFile;
 
 public class LogEntry extends PlatformObject implements ILogEntry {
 
-	private RemoteFileRevision file;
+	private RemoteFile file;
 	private String author;
 	private String date;
 	private String comment;