Portability Changes -
Removing uses of Enum to IConvertible from CodedIOStreams,
Removed MessageStreamIterator.FromFile on non-client profiles,
Removed use of Path.GetFileName,
Removed uses of Converter<T1, T2> delegate,
Removed Guid/DispId options from test protos
diff --git a/src/ProtocolBuffers.Serialization/Http/MessageFormatFactory.cs b/src/ProtocolBuffers.Serialization/Http/MessageFormatFactory.cs
index b3679ba..270af64 100644
--- a/src/ProtocolBuffers.Serialization/Http/MessageFormatFactory.cs
+++ b/src/ProtocolBuffers.Serialization/Http/MessageFormatFactory.cs
@@ -78,7 +78,7 @@
         {

             contentType = (contentType ?? String.Empty).Split(';')[0].Trim();

 

-            Converter<Stream, ICodedInputStream> factory;

+            CodedInputBuilder factory;

             if(!options.MimeInputTypesReadOnly.TryGetValue(contentType, out factory) || factory == null)

             {

                 if(String.IsNullOrEmpty(options.DefaultContentType) ||

@@ -95,7 +95,7 @@
         {

             contentType = (contentType ?? String.Empty).Split(';')[0].Trim();

 

-            Converter<Stream, ICodedOutputStream> factory;

+            CodedOutputBuilder factory;

             if (!options.MimeOutputTypesReadOnly.TryGetValue(contentType, out factory) || factory == null)

             {

                 if (String.IsNullOrEmpty(options.DefaultContentType) ||

diff --git a/src/ProtocolBuffers.Serialization/Http/MessageFormatOptions.cs b/src/ProtocolBuffers.Serialization/Http/MessageFormatOptions.cs
index 72d7371..1480e50 100644
--- a/src/ProtocolBuffers.Serialization/Http/MessageFormatOptions.cs
+++ b/src/ProtocolBuffers.Serialization/Http/MessageFormatOptions.cs
@@ -6,6 +6,15 @@
 namespace Google.ProtocolBuffers.Serialization.Http

 {

     /// <summary>

+    /// A delegate used to specify a method that constructs an ICodedInputStream from a .NET Stream.

+    /// </summary>

+    public delegate ICodedInputStream CodedInputBuilder(Stream stream);

+    /// <summary>

+    /// A delegate used to specify a method that constructs an ICodedOutputStream from a .NET Stream.

+    /// </summary>

+    public delegate ICodedOutputStream CodedOutputBuilder(Stream stream);

+

+    /// <summary>

     /// Defines control information for the various formatting used with HTTP services

     /// </summary>

     public class MessageFormatOptions

@@ -32,9 +41,9 @@
         /// <summary>

         /// Default mime-type handling for input

         /// </summary>

-        private static readonly IDictionary<string, Converter<Stream, ICodedInputStream>> MimeInputDefaults =

-            new ReadOnlyDictionary<string, Converter<Stream, ICodedInputStream>>(

-            new Dictionary<string, Converter<Stream, ICodedInputStream>>(StringComparer.OrdinalIgnoreCase)

+        private static readonly IDictionary<string, CodedInputBuilder> MimeInputDefaults =

+            new ReadOnlyDictionary<string, CodedInputBuilder>(

+            new Dictionary<string, CodedInputBuilder>(StringComparer.OrdinalIgnoreCase)

                 {

                     {"application/json", JsonFormatReader.CreateInstance},

                     {"application/x-json", JsonFormatReader.CreateInstance},

@@ -55,9 +64,9 @@
         /// <summary>

         /// Default mime-type handling for output

         /// </summary>

-        private static readonly IDictionary<string, Converter<Stream, ICodedOutputStream>> MimeOutputDefaults =

-            new ReadOnlyDictionary<string, Converter<Stream, ICodedOutputStream>>(

-            new Dictionary<string, Converter<Stream, ICodedOutputStream>>(StringComparer.OrdinalIgnoreCase)

+        private static readonly IDictionary<string, CodedOutputBuilder> MimeOutputDefaults =

+            new ReadOnlyDictionary<string, CodedOutputBuilder>(

+            new Dictionary<string, CodedOutputBuilder>(StringComparer.OrdinalIgnoreCase)

                 {

                     {"application/json", JsonFormatWriter.CreateInstance},

                     {"application/x-json", JsonFormatWriter.CreateInstance},

@@ -81,35 +90,35 @@
         private string _xmlReaderRootElementName;

         private string _xmlWriterRootElementName;

         private ExtensionRegistry _extensionRegistry;

-        private Dictionary<string, Converter<Stream, ICodedInputStream>> _mimeInputTypes;

-        private Dictionary<string, Converter<Stream, ICodedOutputStream>> _mimeOutputTypes;

+        private Dictionary<string, CodedInputBuilder> _mimeInputTypes;

+        private Dictionary<string, CodedOutputBuilder> _mimeOutputTypes;

 

         /// <summary> Provides access to modify the mime-type input stream construction </summary>

-        public IDictionary<string, Converter<Stream, ICodedInputStream>> MimeInputTypes

+        public IDictionary<string, CodedInputBuilder> MimeInputTypes

         {

             get

             {

                 return _mimeInputTypes ??

-                    (_mimeInputTypes = new Dictionary<string, Converter<Stream, ICodedInputStream>>(

+                    (_mimeInputTypes = new Dictionary<string, CodedInputBuilder>(

                                            MimeInputDefaults, StringComparer.OrdinalIgnoreCase));

             }

         }

 

         /// <summary> Provides access to modify the mime-type input stream construction </summary>

-        public IDictionary<string, Converter<Stream, ICodedOutputStream>> MimeOutputTypes

+        public IDictionary<string, CodedOutputBuilder> MimeOutputTypes

         {

             get

             {

                 return _mimeOutputTypes ??

-                    (_mimeOutputTypes = new Dictionary<string, Converter<Stream, ICodedOutputStream>>(

+                    (_mimeOutputTypes = new Dictionary<string, CodedOutputBuilder>(

                                            MimeOutputDefaults, StringComparer.OrdinalIgnoreCase));

             }

         }

 

-        internal IDictionary<string, Converter<Stream, ICodedInputStream>> MimeInputTypesReadOnly

+        internal IDictionary<string, CodedInputBuilder> MimeInputTypesReadOnly

         { get { return _mimeInputTypes ?? MimeInputDefaults; } }

 

-        internal IDictionary<string, Converter<Stream, ICodedOutputStream>> MimeOutputTypesReadOnly

+        internal IDictionary<string, CodedOutputBuilder> MimeOutputTypesReadOnly

         { get { return _mimeOutputTypes ?? MimeOutputDefaults; } }

 

         /// <summary>

diff --git a/src/ProtocolBuffers.Test/DeprecatedMemberTest.cs b/src/ProtocolBuffers.Test/DeprecatedMemberTest.cs
index 6035c40..0901f04 100644
--- a/src/ProtocolBuffers.Test/DeprecatedMemberTest.cs
+++ b/src/ProtocolBuffers.Test/DeprecatedMemberTest.cs
@@ -10,7 +10,7 @@
     [TestClass]

     public class DeprecatedMemberTest

     {

-        private static void AssertIsDeprecated(ICustomAttributeProvider member)

+        private static void AssertIsDeprecated(MemberInfo member)

         {

             Assert.IsNotNull(member);

             Assert.IsTrue(member.IsDefined(typeof(ObsoleteAttribute), false), "Member not obsolete: " + member);

diff --git a/src/ProtocolBuffers.Test/GeneratedBuilderTest.cs b/src/ProtocolBuffers.Test/GeneratedBuilderTest.cs
index cd87005..1dcb1c2 100644
--- a/src/ProtocolBuffers.Test/GeneratedBuilderTest.cs
+++ b/src/ProtocolBuffers.Test/GeneratedBuilderTest.cs
@@ -54,7 +54,9 @@
             b.AddRangeRepeatedForeignEnum(new OneTimeEnumerator<ForeignEnum>(ForeignEnum.FOREIGN_BAR));

         }

 

-        private static void AssertThrows<T>(System.Threading.ThreadStart method) where T : Exception

+        private delegate void TestMethod();

+

+        private static void AssertThrows<T>(TestMethod method) where T : Exception

         {

             try

             {

diff --git a/src/ProtocolBuffers.Test/TestProtos/UnitTestRpcInterop.cs b/src/ProtocolBuffers.Test/TestProtos/UnitTestRpcInterop.cs
index 8830b82..ecffc6f 100644
--- a/src/ProtocolBuffers.Test/TestProtos/UnitTestRpcInterop.cs
+++ b/src/ProtocolBuffers.Test/TestProtos/UnitTestRpcInterop.cs
@@ -39,12 +39,11 @@
           "dHMYASADKAsyGi5TZWFyY2hSZXNwb25zZS5SZXN1bHRJdGVtGicKClJlc3Vs" + 

           "dEl0ZW0SCwoDdXJsGAEgAigJEgwKBG5hbWUYAiABKAkiUgoTUmVmaW5lU2Vh" + 

           "cmNoUmVxdWVzdBIQCghDcml0ZXJpYRgBIAMoCRIpChBwcmV2aW91c19yZXN1" + 

-          "bHRzGAIgAigLMg8uU2VhcmNoUmVzcG9uc2UypQEKDVNlYXJjaFNlcnZpY2US" + 

-          "MAoGU2VhcmNoEg4uU2VhcmNoUmVxdWVzdBoPLlNlYXJjaFJlc3BvbnNlIgXC" + 

-          "PgIIBRI1CgxSZWZpbmVTZWFyY2gSFC5SZWZpbmVTZWFyY2hSZXF1ZXN0Gg8u" + 

-          "U2VhcmNoUmVzcG9uc2UaK8I+KAome0E2NUYwOTI1LUZEMTEtNGY5NC1CMTY2" + 

-          "LTg5QUM0RjAyNzIwNX1CP0gBwj46CiFHb29nbGUuUHJvdG9jb2xCdWZmZXJz" + 

-          "LlRlc3RQcm90b3MSElVuaXRUZXN0UnBjSW50ZXJvcIgOAw==");

+          "bHRzGAIgAigLMg8uU2VhcmNoUmVzcG9uc2UycQoNU2VhcmNoU2VydmljZRIp" + 

+          "CgZTZWFyY2gSDi5TZWFyY2hSZXF1ZXN0Gg8uU2VhcmNoUmVzcG9uc2USNQoM" + 

+          "UmVmaW5lU2VhcmNoEhQuUmVmaW5lU2VhcmNoUmVxdWVzdBoPLlNlYXJjaFJl" + 

+          "c3BvbnNlQj9IAcI+OgohR29vZ2xlLlByb3RvY29sQnVmZmVycy5UZXN0UHJv" + 

+          "dG9zEhJVbml0VGVzdFJwY0ludGVyb3CIDgM=");

       pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) {

         descriptor = root;

         internal__static_SearchRequest__Descriptor = Descriptor.MessageTypes[0];

@@ -1352,9 +1351,7 @@
   #endregion

   

   #region Services

-  [global::System.Runtime.InteropServices.GuidAttribute("a65f0925-fd11-4f94-b166-89ac4f027205")]

   public partial interface ISearchService {

-    [global::System.Runtime.InteropServices.DispId(5)]

     global::Google.ProtocolBuffers.TestProtos.SearchResponse Search(global::Google.ProtocolBuffers.TestProtos.SearchRequest searchRequest);

     global::Google.ProtocolBuffers.TestProtos.SearchResponse RefineSearch(global::Google.ProtocolBuffers.TestProtos.RefineSearchRequest refineSearchRequest);

   }

diff --git a/src/ProtocolBuffers/CodedInputStream.cs b/src/ProtocolBuffers/CodedInputStream.cs
index e4d690b..ab18f9d 100644
--- a/src/ProtocolBuffers/CodedInputStream.cs
+++ b/src/ProtocolBuffers/CodedInputStream.cs
@@ -449,7 +449,7 @@
         /// </summary>   

         [CLSCompliant(false)]

         public bool ReadEnum<T>(ref T value, out object unknown)

-            where T : struct, IComparable, IFormattable, IConvertible

+            where T : struct, IComparable, IFormattable

         {

             int number = (int) ReadRawVarint32();

             if (Enum.IsDefined(typeof(T), number))

@@ -882,7 +882,7 @@
         [CLSCompliant(false)]

         public void ReadEnumArray<T>(uint fieldTag, string fieldName, ICollection<T> list,

                                      out ICollection<object> unknown)

-            where T : struct, IComparable, IFormattable, IConvertible

+            where T : struct, IComparable, IFormattable

         {

             unknown = null;

             object unkval;

diff --git a/src/ProtocolBuffers/CodedOutputStream.ComputeSize.cs b/src/ProtocolBuffers/CodedOutputStream.ComputeSize.cs
index 4f4e13d..ca6662a 100644
--- a/src/ProtocolBuffers/CodedOutputStream.ComputeSize.cs
+++ b/src/ProtocolBuffers/CodedOutputStream.ComputeSize.cs
@@ -575,7 +575,7 @@
                 case FieldType.Enum:

                     if (value is Enum)

                     {

-                        return ComputeEnumSize(fieldNumber, ((IConvertible)value).ToInt32(FrameworkPortability.InvariantCulture));

+                        return ComputeEnumSize(fieldNumber, Convert.ToInt32(value));

                     }

                     else

                     {

@@ -631,7 +631,7 @@
                 case FieldType.Enum:

                     if (value is Enum)

                     {

-                        return ComputeEnumSizeNoTag(((IConvertible)value).ToInt32(FrameworkPortability.InvariantCulture));

+                        return ComputeEnumSizeNoTag(Convert.ToInt32(value));

                     }

                     else

                     {

diff --git a/src/ProtocolBuffers/CodedOutputStream.cs b/src/ProtocolBuffers/CodedOutputStream.cs
index b6a501c..b767f70 100644
--- a/src/ProtocolBuffers/CodedOutputStream.cs
+++ b/src/ProtocolBuffers/CodedOutputStream.cs
@@ -806,7 +806,7 @@
 

         [CLSCompliant(false)]

         public void WriteEnumArray<T>(int fieldNumber, string fieldName, IEnumerable<T> list)

-            where T : struct, IComparable, IFormattable, IConvertible

+            where T : struct, IComparable, IFormattable

         {

             if (list is ICastArray)

             {

@@ -1028,7 +1028,7 @@
 

         [CLSCompliant(false)]

         public void WritePackedEnumArray<T>(int fieldNumber, string fieldName, int calculatedSize, IEnumerable<T> list)

-            where T : struct, IComparable, IFormattable, IConvertible

+            where T : struct, IComparable, IFormattable

         {

             WriteTag(fieldNumber, WireFormat.WireType.LengthDelimited);

             WriteRawVarint32((uint) calculatedSize);

diff --git a/src/ProtocolBuffers/Descriptors/FileDescriptor.cs b/src/ProtocolBuffers/Descriptors/FileDescriptor.cs
index 392db9a..d7075e3 100644
--- a/src/ProtocolBuffers/Descriptors/FileDescriptor.cs
+++ b/src/ProtocolBuffers/Descriptors/FileDescriptor.cs
@@ -90,12 +90,14 @@
             csharpFileOptions = BuildOrFakeWithDefaultOptions(options);

         }

 

+        static readonly char[] PathSeperators = new char[] { '/', '\\' };

         private CSharpFileOptions BuildOrFakeWithDefaultOptions(CSharpFileOptions defaultOptions)

         {

             // Fix for being able to relocate these files to any directory structure

             if (proto.Package == "google.protobuf")

             {

-                string filename = Path.GetFileName(proto.Name);

+                int ixslash = proto.Name.LastIndexOfAny(PathSeperators);

+                string filename = ixslash < 0 ? proto.Name : proto.Name.Substring(ixslash + 1);

                 // TODO(jonskeet): Check if we could use FileDescriptorProto.Descriptor.Name - interesting bootstrap issues)

                 if (filename == "descriptor.proto")

                 {

diff --git a/src/ProtocolBuffers/ICodedInputStream.cs b/src/ProtocolBuffers/ICodedInputStream.cs
index a3c0f30..b39b602 100644
--- a/src/ProtocolBuffers/ICodedInputStream.cs
+++ b/src/ProtocolBuffers/ICodedInputStream.cs
@@ -171,7 +171,7 @@
         /// </summary>   

         [CLSCompliant(false)]

         bool ReadEnum<T>(ref T value, out object unknown)

-            where T : struct, IComparable, IFormattable, IConvertible;

+            where T : struct, IComparable, IFormattable;

 

         /// <summary>

         /// Reads an sfixed32 field value from the stream.

@@ -214,7 +214,7 @@
         /// </summary>

         [CLSCompliant(false)]

         void ReadEnumArray<T>(uint fieldTag, string fieldName, ICollection<T> list, out ICollection<object> unknown)

-            where T : struct, IComparable, IFormattable, IConvertible;

+            where T : struct, IComparable, IFormattable;

 

         /// <summary>

         /// Reads a set of messages using the <paramref name="messageType"/> as a template.  T is not guaranteed to be 

diff --git a/src/ProtocolBuffers/ICodedOutputStream.cs b/src/ProtocolBuffers/ICodedOutputStream.cs
index 8619508..64c8065 100644
--- a/src/ProtocolBuffers/ICodedOutputStream.cs
+++ b/src/ProtocolBuffers/ICodedOutputStream.cs
@@ -292,7 +292,7 @@
         /// </summary>

         [CLSCompliant(false)]

         void WriteEnumArray<T>(int fieldNumber, string fieldName, IEnumerable<T> list)

-            where T : struct, IComparable, IFormattable, IConvertible;

+            where T : struct, IComparable, IFormattable;

 

         /// <summary>

         /// Writes a packed repeated primitive, including tag and length, to the stream.

@@ -369,6 +369,6 @@
         /// </summary>

         [CLSCompliant(false)]

         void WritePackedEnumArray<T>(int fieldNumber, string fieldName, int calculatedSize, IEnumerable<T> list)

-            where T : struct, IComparable, IFormattable, IConvertible;

+            where T : struct, IComparable, IFormattable;

     }

 }
\ No newline at end of file
diff --git a/src/ProtocolBuffers/MessageStreamIterator.cs b/src/ProtocolBuffers/MessageStreamIterator.cs
index 89fda91..32d697c 100644
--- a/src/ProtocolBuffers/MessageStreamIterator.cs
+++ b/src/ProtocolBuffers/MessageStreamIterator.cs
@@ -124,10 +124,12 @@
             return new MessageStreamIterator<TMessage>(streamProvider, extensionRegistry, newSizeLimit);

         }

 

+#if CLIENTPROFILE

         public static MessageStreamIterator<TMessage> FromFile(string file)

         {

             return new MessageStreamIterator<TMessage>(() => File.OpenRead(file), ExtensionRegistry.Empty);

         }

+#endif

 

         public static MessageStreamIterator<TMessage> FromStreamProvider(StreamProvider streamProvider)

         {

diff --git a/src/ProtocolBuffers/TextFormat.cs b/src/ProtocolBuffers/TextFormat.cs
index c0f4a5f..7e2eff0 100644
--- a/src/ProtocolBuffers/TextFormat.cs
+++ b/src/ProtocolBuffers/TextFormat.cs
@@ -708,7 +708,7 @@
                 {

                     // Explicitly specify the invariant culture so that this code does not break when

                     // executing in Turkey.

-                    String lowerName = name.ToLower(FrameworkPortability.InvariantCulture);

+                    String lowerName = name.ToLowerInvariant();

                     field = type.FindDescriptor<FieldDescriptor>(lowerName);

                     // If the case-insensitive match worked but the field is NOT a group,

                     // TODO(jonskeet): What? Java comment ends here!

diff --git a/src/ProtocolBuffers/TextTokenizer.cs b/src/ProtocolBuffers/TextTokenizer.cs
index 90774bc..5bb27fd 100644
--- a/src/ProtocolBuffers/TextTokenizer.cs
+++ b/src/ProtocolBuffers/TextTokenizer.cs
@@ -338,7 +338,7 @@
                 NextToken();

                 return negative ? double.NegativeInfinity : double.PositiveInfinity;

             }

-            if (currentToken.Equals("nan", StringComparison.InvariantCultureIgnoreCase))

+            if (currentToken.Equals("nan", StringComparison.OrdinalIgnoreCase))

             {

                 NextToken();

                 return Double.NaN;

diff --git a/src/ProtocolBuffersLite.Test/TestProtos/UnitTestRpcInteropLite.cs b/src/ProtocolBuffersLite.Test/TestProtos/UnitTestRpcInteropLite.cs
index 85f562b..1a54e8e 100644
--- a/src/ProtocolBuffersLite.Test/TestProtos/UnitTestRpcInteropLite.cs
+++ b/src/ProtocolBuffersLite.Test/TestProtos/UnitTestRpcInteropLite.cs
@@ -1280,9 +1280,7 @@
   #endregion

   

   #region Services

-  [global::System.Runtime.InteropServices.GuidAttribute("a65f0925-fd11-4f94-b166-89ac4f027205")]

   public partial interface ISearchService {

-    [global::System.Runtime.InteropServices.DispId(5)]

     global::Google.ProtocolBuffers.TestProtos.SearchResponse Search(global::Google.ProtocolBuffers.TestProtos.SearchRequest searchRequest);

     global::Google.ProtocolBuffers.TestProtos.SearchResponse RefineSearch(global::Google.ProtocolBuffers.TestProtos.RefineSearchRequest refineSearchRequest);

   }