32539: [CVS Core] Charset for CVS log is invalid
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/ICVSRepositoryLocation.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/ICVSRepositoryLocation.java
index 3a95b3b..c0f0e43 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/ICVSRepositoryLocation.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/ICVSRepositoryLocation.java
@@ -82,6 +82,11 @@
 	public ICVSRemoteFolder getRemoteFolder(String remotePath, CVSTag tag);
 	
 	/**
+	 * encoding for commit comments. 
+	 */
+	public String getEncoding();
+	
+	/**
 	 * Return the conection timeout value in milliseconds.
 	 * A value of 0 means there is no timeout value.
 	 */
@@ -122,4 +127,10 @@
 	 * @since 3.0
 	 */
 	public void setUserAuthenticator(IUserAuthenticator authenticator);	
+
+	/**
+	 * Sets encoding for commit messages.
+	 * @since 3.0
+	 */
+	public void setEncoding(String encoding);
 }
\ No newline at end of file
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/connection/CVSRepositoryLocation.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/connection/CVSRepositoryLocation.java
index 9df1a4c..11026cf 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/connection/CVSRepositoryLocation.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/connection/CVSRepositoryLocation.java
@@ -60,6 +60,7 @@
 	public static final String PREF_LOCATION = "location"; //$NON-NLS-1$
 	public static final String PREF_WRITE_LOCATION = "write"; //$NON-NLS-1$
 	public static final String PREF_READ_LOCATION = "read"; //$NON-NLS-1$
+	public static final String PREF_SERVER_ENCODING = "encoding"; //$NON-NLS-1$
 	
 	// server platform constants
 	public static final int UNDETERMINED_PLATFORM = 0;
@@ -148,6 +149,7 @@
 	 *   host The host where the repository resides
 	 *   port The port to connect to (optional)
 	 *   root The server directory where the repository is located
+	 *   encoding The file system encoding of the server
 	 */
 	public static CVSRepositoryLocation fromProperties(Properties configuration) throws CVSException {
 		// We build a string to allow validation of the components that are provided to us
@@ -177,7 +179,9 @@
 			throw new CVSException(new Status(IStatus.ERROR, CVSProviderPlugin.ID, TeamException.UNABLE, Policy.bind("CVSRepositoryLocation.rootRequired"), null));//$NON-NLS-1$ 
 		root = root.replace('\\', '/');
 
-		return new CVSRepositoryLocation(method, user, password, host, port, root, user != null, false);
+		String encoding = configuration.getProperty("encoding"); //$NON-NLS-1$
+		
+		return new CVSRepositoryLocation(method, user, password, host, port, root, encoding, user != null, false);
 	}
 	
 	/**
@@ -299,9 +303,8 @@
 			String root = location.substring(start).replace('\\', '/');
 			
 			if (validateOnly)
-				throw new CVSException(new CVSStatus(IStatus.OK, Policy.bind("ok")));//$NON-NLS-1$ 
-				
-			return new CVSRepositoryLocation(method, user, password, host, port, root, (user != null), (password != null));
+				throw new CVSException(new CVSStatus(IStatus.OK, Policy.bind("ok")));//$NON-NLS-1$ 		
+			return new CVSRepositoryLocation(method, user, password, host, port, root, null /* encoding */, (user != null), (password != null));
 		}
 		catch (IndexOutOfBoundsException e) {
 			// We'll get here if anything funny happened while extracting substrings
@@ -464,7 +467,7 @@
 	/*
 	 * Create a CVSRepositoryLocation from its composite parts.
 	 */
-	private CVSRepositoryLocation(IConnectionMethod method, String user, String password, String host, int port, String root, boolean userFixed, boolean passwordFixed) {
+	private CVSRepositoryLocation(IConnectionMethod method, String user, String password, String host, int port, String root, String encoding, boolean userFixed, boolean passwordFixed) {
 		this.method = method;
 		this.user = user;
 		this.password = password;
@@ -477,6 +480,7 @@
 		// The password can only be fixed if the username is and a password is provided
 		if (userFixed && passwordFixed && (password != null))
 			this.passwordFixed = true;
+		setEncoding(encoding);
 	}
 	
 	/*
@@ -572,6 +576,32 @@
 	}
 	
 	/*
+	 * @see ICVSRepositoryLocation#getEncoding()
+	 */
+	public String getEncoding() {
+		if (hasPreferences()) {
+			return getPreferences().get(PREF_SERVER_ENCODING, getDefaultEncoding());
+		} else {
+			return getDefaultEncoding();
+		}
+	}
+
+	/*
+	 * @see ICVSRepositoryLocation#setEncoding()
+	 */
+	public void setEncoding(String encoding) {
+		if (encoding == null || encoding == getDefaultEncoding()) {
+			if (hasPreferences()) {
+				getPreferences().remove(PREF_SERVER_ENCODING);
+			}
+		} else {
+			ensurePreferencesStored();
+			getPreferences().put(PREF_SERVER_ENCODING, encoding);
+			flushPreferences();
+		}
+	}	
+
+	/*
 	 * @see ICVSRepositoryLocation#members(CVSTag, boolean, IProgressMonitor)
 	 */
 	public ICVSRemoteResource[] members(CVSTag tag, boolean modules, IProgressMonitor progress) throws CVSException {
@@ -1142,4 +1172,8 @@
 			storePreferences();
 		}
 	}
+	
+	private String getDefaultEncoding() {
+		return System.getProperty("file.encoding"); //$NON-NLS-1$
+	}
 }
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/connection/Connection.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/connection/Connection.java
index e99e4f1..b25172b 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/connection/Connection.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/connection/Connection.java
@@ -11,16 +11,10 @@
 package org.eclipse.team.internal.ccvs.core.connection;
 
  
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
+import java.io.*;
 
 import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.team.internal.ccvs.core.CVSException;
-import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin;
-import org.eclipse.team.internal.ccvs.core.ICVSRepositoryLocation;
-import org.eclipse.team.internal.ccvs.core.IServerConnection;
-import org.eclipse.team.internal.ccvs.core.Policy;
+import org.eclipse.team.internal.ccvs.core.*;
 
 /**
  * A connection to talk to a cvs server. The life cycle of a connection is
@@ -44,7 +38,6 @@
 	
 	private IServerConnection serverConnection;
 	private ICVSRepositoryLocation fCVSRoot;
-	private String fCVSRootDirectory;
 	private boolean fIsEstablished;
 	private InputStream fResponseStream;
 	private byte[] readLineBuffer = new byte[256];
@@ -66,7 +59,7 @@
 	/**
 	 * Closes the connection.
 	 */
-	public void close() throws CVSException {
+	public void close() {
 		if (!isEstablished())
 			return;
 		try {
@@ -99,7 +92,7 @@
 	 * Returns the <code>OutputStream</code> used to send requests
 	 * to the server.
 	 */
-	public OutputStream getOutputStream() throws CVSException {
+	public OutputStream getOutputStream() {
 		if (!isEstablished())
 			return null;
 		return serverConnection.getOutputStream();
@@ -108,7 +101,7 @@
 	 * Returns the <code>InputStream</code> used to read responses from
 	 * the server.
 	 */
-	public InputStream getInputStream() throws CVSException {
+	public InputStream getInputStream() {
 		if (!isEstablished())
 			return null;
 		if (fResponseStream == null)
@@ -151,7 +144,8 @@
 				if (r == NEWLINE) break;
 				readLineBuffer = append(readLineBuffer, index++, (byte) r);
 			}
-			String result = new String(readLineBuffer, 0, index);
+
+			String result = new String(readLineBuffer, 0, index, getEncoding(fCVSRoot));
 			if (Policy.DEBUG_CVS_PROTOCOL) System.out.println(result);
 			return result;
 		} catch (IOException e) {
@@ -159,7 +153,7 @@
 		}
 	}
 	
-	static String readLine(InputStream in) throws IOException {
+	static String readLine(ICVSRepositoryLocation location, InputStream in) throws IOException {
 		byte[] buffer = new byte[256];
 		int index = 0;
 		int r;
@@ -168,7 +162,8 @@
 				break;
 			buffer = append(buffer, index++, (byte) r);
 		}
-		String result = new String(buffer, 0, index);
+
+		String result = new String(buffer, 0, index, getEncoding(location));
 		if (Policy.DEBUG_CVS_PROTOCOL)
 			System.out.println(result);
 		return result;
@@ -180,21 +175,39 @@
 	 * Sends the given string to the server.
 	 */
 	public void write(String s) throws CVSException {
-		write(s.getBytes(), false);
+        try {
+			write(s.getBytes(getEncoding(fCVSRoot)), false);
+		} catch (UnsupportedEncodingException e) {
+			throw new CVSException (e.getMessage());
+		}
 	}
 	
 	/**
+	 * Return the encoding for the given repository location
+	 * @return the encoding for the given repository location
+	 */
+	public static String getEncoding(ICVSRepositoryLocation location) {
+		return location.getEncoding();
+	}
+
+	/**
 	 * Sends the given bytes to the server.
 	 */
 	public void write(byte[] b, int off, int len) throws CVSException {
 		write(b, off, len, false);
 	}
+
 	/**
 	 * Sends the given string and a newline to the server. 
 	 */
 	public void writeLine(String s) throws CVSException {
-		write(s.getBytes(), true);
+		try {
+			write(s.getBytes(getEncoding(fCVSRoot)), true);
+		} catch (UnsupportedEncodingException e) {
+			throw new CVSException (e.getMessage());
 	}
+	}
+
 	/**
 	 * Sends the given bytes and a newline to the server.
 	 */
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/connection/PServerConnection.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/connection/PServerConnection.java
index 8d9faa0..e703140 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/connection/PServerConnection.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/connection/PServerConnection.java
@@ -162,7 +162,7 @@
 		request.append(NEWLINE);
 		out.write(request.toString().getBytes());
 		out.flush();
-		String line = Connection.readLine(getInputStream());
+		String line = Connection.readLine(cvsroot, getInputStream());
 		
 		// Return if we succeeded
 		if (LOGIN_OK.equals(line))
@@ -177,7 +177,7 @@
 		// Skip any E messages for now
 		while (line.charAt(0) == ERROR_CHAR) {
 			// message += line.substring(1) + " ";
-			line = Connection.readLine(getInputStream());
+			line = Connection.readLine(cvsroot, getInputStream());
 		}
 		// Remove leading "error 0"
 		if (line.startsWith(ERROR_MESSAGE))