Index: mcs/class/corlib/System.Text/Encoding.cs
===================================================================
--- mcs/class/corlib/System.Text/Encoding.cs	(revision 59350)
+++ mcs/class/corlib/System.Text/Encoding.cs	(working copy)
@@ -227,58 +227,16 @@
 	{
 		if (s == null)
 			throw new ArgumentNullException ("s");
-#if NET_2_0
-		if (charIndex < 0 || charIndex > s.Length)
-			throw new ArgumentOutOfRangeException ("charIndex", _("ArgRange_Array"));
-		if (charCount < 0 || charIndex + charCount > s.Length)
-			throw new ArgumentOutOfRangeException ("charCount", _("ArgRange_Array"));
-		if (byteIndex < 0 || byteIndex > bytes.Length)
-			throw new ArgumentOutOfRangeException ("byteIndex", _("ArgRange_Array"));
 
-		if (charCount == 0 || bytes.Length == byteIndex)
-			return 0;
-		unsafe {
-			fixed (char* cptr = s) {
-				fixed (byte* bptr = bytes) {
-					return GetBytes (cptr + charIndex,
-						charCount,
-						bptr + byteIndex,
-						bytes.Length - byteIndex);
-				}
-			}
-		}
-#else
 		return GetBytes (s.ToCharArray(), charIndex, charCount, bytes, byteIndex);
-#endif
 	}
 	public virtual byte[] GetBytes (String s)
 	{
 		if (s == null)
 			throw new ArgumentNullException ("s");
 
-#if NET_2_0
-		if (s.Length == 0)
-			return new byte [0];
-		int byteCount = GetByteCount (s);
-		if (byteCount == 0)
-			return new byte [0];
-		unsafe {
-			fixed (char* cptr = s) {
-				byte [] bytes = new byte [byteCount];
-				fixed (byte* bptr = bytes) {
-					GetBytes (cptr, s.Length,
-						bptr, byteCount);
-					return bytes;
-				}
-			}
-		}
-#else
 		char[] chars = s.ToCharArray ();
-		int numBytes = GetByteCount (chars, 0, chars.Length);
-		byte[] bytes = new byte [numBytes];
-		GetBytes (chars, 0, chars.Length, bytes, 0);
-		return bytes;
-#endif
+		return GetBytes (chars, 0, chars.Length);
 	}
 	public virtual byte[] GetBytes (char[] chars, int index, int count)
 	{
@@ -289,10 +247,10 @@
 	}
 	public virtual byte[] GetBytes (char[] chars)
 	{
-		int numBytes = GetByteCount (chars, 0, chars.Length);
-		byte[] bytes = new byte [numBytes];
-		GetBytes (chars, 0, chars.Length, bytes, 0);
-		return bytes;
+		if (chars == null)
+			throw new ArgumentNullException ("chars");
+
+		return GetBytes (chars, 0, chars.Length);
 	}
 
 	// Get the number of characters needed to decode a byte buffer.
@@ -324,10 +282,7 @@
 		if (bytes == null) {
 			throw new ArgumentNullException ("bytes");
 		}
-		int numChars = GetCharCount (bytes, 0, bytes.Length);
-		char[] chars = new char [numChars];
-		GetChars (bytes, 0, bytes.Length, chars, 0);
-		return chars;
+		return GetChars (bytes, 0, bytes.Length);
 	}
 
 	// Get a decoder that forwards requests to this object.
@@ -663,7 +618,10 @@
 	}
 	public virtual String GetString (byte[] bytes)
 	{
-		return new String (GetChars(bytes));
+		if (bytes == null)
+			throw new ArgumentNullException ("bytes");
+
+		return GetString (bytes, 0, bytes.Length);
 	}
 
 #if !ECMA_COMPAT
@@ -1033,7 +991,7 @@
 		for (int p = 0; p < count; p++)
 			c [p] = chars [p];
 
-		return GetByteCount (c);
+		return GetByteCount (c, 0, count);
 	}
 
 	[CLSCompliantAttribute(false)]
@@ -1061,19 +1019,22 @@
 			throw new ArgumentOutOfRangeException ("charCount");
 		if (byteCount < 0)
 			throw new ArgumentOutOfRangeException ("byteCount");
-		
+
 		byte [] ba = new byte [byteCount];
 		for (int i = 0; i < byteCount; i++)
 			ba [i] = bytes [i];
-		char [] ret = GetChars (ba, 0, byteCount);
-		int top = ret.Length;
 
-		if (top > charCount)
-			throw new ArgumentException ("charCount is less than the number of characters produced", "charCount");
-		
-		for (int i = 0; i < top; i++)
-			chars [i] = ret [i];
-		return top;
+		char [] c = new char [charCount];		
+		int top = GetChars (ba, 0, byteCount, c, 0);
+
+		// Unusual but avoids IndexOutOfRangeException
+		if (top < charCount)
+			charCount = top;
+
+		for (int i = 0; i < charCount; i++)
+			chars [i] = c [i];
+
+		return charCount;
 	}
 
 	[CLSCompliantAttribute(false)]
@@ -1087,21 +1048,22 @@
 			throw new ArgumentOutOfRangeException ("charCount");
 		if (byteCount < 0)
 			throw new ArgumentOutOfRangeException ("byteCount");
-		
+
 		char [] c = new char [charCount];
-		
 		for (int i = 0; i < charCount; i++)
 			c [i] = chars [i];
 
-		byte [] b = GetBytes (c, 0, charCount);
-		int top = b.Length;
-		if (top > byteCount)
-			throw new ArgumentException ("byteCount is less that the number of bytes produced", "byteCount");
+		byte [] ba = new byte [byteCount];
+		int top = GetBytes (c, 0, charCount, ba, 0);
 
-		for (int i = 0; i < top; i++)
-			bytes [i] = b [i];
-		
-		return b.Length;
+		// Unusual but avoids IndexOutOfRangeException
+		if (top < byteCount)
+			byteCount = top;
+
+		for (int i = 0; i < byteCount; i++)
+			bytes [i] = ba [i];
+
+		return byteCount;
 	}
 #endif
 
Index: mcs/class/corlib/System.Text/UnicodeEncoding.cs
===================================================================
--- mcs/class/corlib/System.Text/UnicodeEncoding.cs	(revision 59350)
+++ mcs/class/corlib/System.Text/UnicodeEncoding.cs	(working copy)
@@ -147,7 +147,7 @@
 	}
 
 #if !NET_2_0
-	public unsafe override byte [] GetBytes (String s)
+	public override byte [] GetBytes (String s)
 	{
 		if (s == null)
 			throw new ArgumentNullException ("s");
@@ -155,10 +155,7 @@
 		int byteCount = GetByteCount (s);
 		byte [] bytes = new byte [byteCount];
 
-		if (byteCount != 0)
-			fixed (char* charPtr = s)
-				fixed (byte* bytePtr = bytes)
-					GetBytesInternal (charPtr, s.Length, bytePtr, byteCount);
+		GetBytes (s, 0, s.Length, bytes, 0);
 
 		return bytes;
 	}
@@ -183,6 +180,10 @@
 			throw new ArgumentOutOfRangeException ("byteIndex", _("ArgRange_Array"));
 		}
 
+		// For consistency
+		if (charCount == 0)
+			return 0;
+
 		int byteCount = bytes.Length - byteIndex;
 		if (bytes.Length == 0)
 			bytes = new byte [1];
@@ -298,6 +299,29 @@
 
 		return GetCharsInternal (bytes, byteCount, chars, charCount);
 	}
+
+	// Decode a buffer of bytes into a string.
+	public unsafe override String GetString (byte [] bytes, int index, int count)
+	{
+		if (bytes == null)
+			throw new ArgumentNullException ("bytes");
+		if (index < 0 || index > bytes.Length)
+			throw new ArgumentOutOfRangeException ("index", _("ArgRange_Array"));
+		if (count < 0 || count > (bytes.Length - index))
+			throw new ArgumentOutOfRangeException ("count", _("ArgRange_Array"));
+
+		if (count == 0)
+			return string.Empty;
+
+		int charCount = GetCharCount (bytes, index, count);
+		string s = string.InternalAllocateStr (charCount);
+
+		fixed (byte* bytePtr = bytes)
+			fixed (char* charPtr = s)
+				GetCharsInternal (bytePtr + index, count, charPtr, charCount);
+
+		return s;
+	}
 #endif
 
 	private unsafe int GetCharsInternal (byte* bytes, int byteCount,
Index: mcs/class/I18N/Common/MonoEncoding.cs
===================================================================
--- mcs/class/I18N/Common/MonoEncoding.cs	(revision 59350)
+++ mcs/class/I18N/Common/MonoEncoding.cs	(working copy)
@@ -82,6 +82,23 @@
 			}
 		}
 
+		public override int GetByteCount (string s)
+		{
+			if (s == null)
+				throw new ArgumentNullException ("s");
+
+			// For consistency
+			if (s.Length == 0)
+				return 0;
+
+			unsafe {
+				fixed (char* cptr = s) {
+					return GetByteCountImpl (
+						cptr, s.Length);
+				}
+			}
+		}
+
 		// Get the bytes that result from encoding a character buffer.
 		public override int GetBytes (
 			char [] chars, int charIndex, int charCount,
@@ -106,6 +123,10 @@
 			if (charCount == 0)
 				return 0;
 
+			int byteCount = bytes.Length - byteIndex;
+			if (bytes.Length == 0)
+				bytes = new byte [1];
+
 			unsafe {
 				fixed (char* cptr = chars) {
 					fixed (byte* bptr = bytes) {
@@ -113,7 +134,7 @@
 							cptr + charIndex,
 							charCount,
 							bptr + byteIndex,
-							bytes.Length - byteIndex);
+							byteCount);
 					}
 				}
 			}
@@ -144,8 +165,14 @@
 				throw new ArgumentException
 					(Strings.GetString("Arg_InsufficientSpace"), "bytes");
 
-			if (charCount == 0 || bytes.Length == byteIndex)
+			// For consistency
+			if (charCount == 0)
 				return 0;
+
+			int byteCount = bytes.Length - byteIndex;
+			if (bytes.Length == 0)
+				bytes = new byte [1];
+
 			unsafe {
 				fixed (char* cptr = s) {
 					fixed (byte* bptr = bytes) {
@@ -153,12 +180,25 @@
 							cptr + charIndex,
 							charCount,
 							bptr + byteIndex,
-							bytes.Length - byteIndex);
+							byteCount);
 					}
 				}
 			}
 		}
 
+		public override byte [] GetBytes (string s)
+		{
+			if (s == null)
+				throw new ArgumentNullException ("s");
+
+			int byteCount = GetByteCount (s);
+			byte [] bytes = new byte [byteCount];
+
+			GetBytes (s, 0, s.Length, bytes, 0);
+
+			return bytes;
+		}
+
 #if NET_2_0
 		public unsafe override int GetByteCount (char* chars, int count)
 
@@ -234,13 +274,18 @@
 
 				if (charCount == 0)
 					return 0;
+
+				int byteCount = bytes.Length - byteIndex;
+				if (bytes.Length == 0)
+					bytes = new byte [1];
+
 				unsafe {
 					fixed (char* cptr = chars) {
 						fixed (byte* bptr = bytes) {
 							return GetBytesImpl (cptr + charIndex, 
 								charCount,
 								bptr + byteIndex,
-								bytes.Length - byteIndex,
+								byteCount,
 								flush);
 						}
 					}
