Reader/Writer implementations changed to use static factories
diff --git a/src/ProtoBench/Program.cs b/src/ProtoBench/Program.cs
index ec05131..23af195 100644
--- a/src/ProtoBench/Program.cs
+++ b/src/ProtoBench/Program.cs
@@ -131,30 +131,40 @@
                 MemoryStream inputStream = new MemoryStream(inputData);

                 ByteString inputString = ByteString.CopyFrom(inputData);

                 IMessage sampleMessage = defaultMessage.WeakCreateBuilderForType().WeakMergeFrom(inputString, registry).WeakBuild();

-                

-                StringWriter temp = new StringWriter();

-                new XmlFormatWriter(temp).WriteMessage(sampleMessage);

-                string xmlMessageText = temp.ToString();

-                temp = new StringWriter();

-                new JsonFormatWriter(temp).WriteMessage(sampleMessage);

-                string jsonMessageText = temp.ToString();

-                byte[] jsonBytes /*no pun intended*/ = Encoding.UTF8.GetBytes(jsonMessageText);

 

+                byte[] jsonBytes, xmlBytes;/*no pun intended, well... maybe for xml*/

+                using (MemoryStream temp = new MemoryStream())

+                {

+                    XmlFormatWriter.CreateInstance(temp).WriteMessage(sampleMessage);

+                    xmlBytes = temp.ToArray();

+                }

+                using (MemoryStream temp = new MemoryStream())

+                {

+                    JsonFormatWriter.CreateInstance(temp).WriteMessage(sampleMessage);

+                    jsonBytes = temp.ToArray();

+                }

                 IDictionary<string, object> dictionary = new Dictionary<string, object>(StringComparer.Ordinal);

                 new DictionaryWriter(dictionary).WriteMessage(sampleMessage);

 

-

                 //Serializers

                 if(!FastTest) RunBenchmark("Serialize to byte string", inputData.Length, () => sampleMessage.ToByteString());

                 RunBenchmark("Serialize to byte array", inputData.Length, () => sampleMessage.ToByteArray());

                 if (!FastTest) RunBenchmark("Serialize to memory stream", inputData.Length,

                           () => sampleMessage.WriteTo(new MemoryStream()));

 

-                RunBenchmark("Serialize to xml", xmlMessageText.Length, () => new XmlFormatWriter(new StringWriter()).WriteMessage(sampleMessage));

-                RunBenchmark("Serialize to json", jsonMessageText.Length, () => new JsonFormatWriter(new StringWriter()).WriteMessage(sampleMessage));

-                RunBenchmark("Serialize to json via xml", jsonMessageText.Length,

-                    () => new XmlFormatWriter(JsonReaderWriterFactory.CreateJsonWriter(new MemoryStream(), Encoding.UTF8)) 

-                    { Options = XmlWriterOptions.OutputJsonTypes }.WriteMessage(sampleMessage)

+                RunBenchmark("Serialize to xml", xmlBytes.Length, () =>

+                {

+                    XmlFormatWriter.CreateInstance(new MemoryStream(), Encoding.UTF8).WriteMessage(sampleMessage);

+                } );

+                RunBenchmark("Serialize to json", jsonBytes.Length, () => 

+                {

+                    JsonFormatWriter.CreateInstance(new MemoryStream()).WriteMessage(sampleMessage); 

+                });

+                RunBenchmark("Serialize to json via xml", jsonBytes.Length,

+                    () =>

+                        XmlFormatWriter.CreateInstance(JsonReaderWriterFactory.CreateJsonWriter(new MemoryStream(), Encoding.UTF8))

+                            .SetOptions(XmlWriterOptions.OutputJsonTypes)

+                            .WriteMessage(sampleMessage)

                 );

 

                 RunBenchmark("Serialize to dictionary", sampleMessage.SerializedSize, () => new DictionaryWriter().WriteMessage(sampleMessage));

@@ -179,12 +189,11 @@
                           .WeakBuild();

                   });

 

-                RunBenchmark("Deserialize from xml", xmlMessageText.Length, () => new XmlFormatReader(xmlMessageText).Merge(defaultMessage.WeakCreateBuilderForType()).WeakBuild());

-                RunBenchmark("Deserialize from json", jsonMessageText.Length, () => new JsonFormatReader(jsonMessageText).Merge(defaultMessage.WeakCreateBuilderForType()).WeakBuild());

-                RunBenchmark("Deserialize from json via xml", jsonMessageText.Length,

-                    () => new XmlFormatReader(JsonReaderWriterFactory.CreateJsonReader(jsonBytes, System.Xml.XmlDictionaryReaderQuotas.Max)) 

-                    { Options = XmlReaderOptions.ReadNestedArrays }

-                    .Merge(defaultMessage.WeakCreateBuilderForType()).WeakBuild());

+                RunBenchmark("Deserialize from xml", xmlBytes.Length, () => XmlFormatReader.CreateInstance(xmlBytes).Merge(defaultMessage.WeakCreateBuilderForType()).WeakBuild());

+                RunBenchmark("Deserialize from json", jsonBytes.Length, () => JsonFormatReader.CreateInstance(jsonBytes).Merge(defaultMessage.WeakCreateBuilderForType()).WeakBuild());

+                RunBenchmark("Deserialize from json via xml", jsonBytes.Length,

+                    () => XmlFormatReader.CreateInstance(JsonReaderWriterFactory.CreateJsonReader(jsonBytes, System.Xml.XmlDictionaryReaderQuotas.Max))

+                        .SetOptions(XmlReaderOptions.ReadNestedArrays).Merge(defaultMessage.WeakCreateBuilderForType()).WeakBuild());

 

                 RunBenchmark("Deserialize from dictionary", sampleMessage.SerializedSize, () => new DictionaryReader(dictionary).Merge(defaultMessage.WeakCreateBuilderForType()).WeakBuild());

 

diff --git a/src/ProtoBench/ProtoBench.csproj b/src/ProtoBench/ProtoBench.csproj
index b1d676a..7722f8d 100644
--- a/src/ProtoBench/ProtoBench.csproj
+++ b/src/ProtoBench/ProtoBench.csproj
@@ -56,15 +56,9 @@
   <ItemGroup>

     <Reference Include="System" />

     <Reference Include="System.Data" />

-    <Reference Include="System.Runtime.Serialization, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">

-      <RequiredTargetFramework>3.0</RequiredTargetFramework>

-    </Reference>

-    <Reference Include="System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">

-      <RequiredTargetFramework>3.0</RequiredTargetFramework>

-    </Reference>

-    <Reference Include="System.ServiceModel.Web, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">

-      <RequiredTargetFramework>3.5</RequiredTargetFramework>

-    </Reference>

+    <Reference Include="System.Runtime.Serialization" />

+    <Reference Include="System.ServiceModel" />

+    <Reference Include="System.ServiceModel.Web" />

     <Reference Include="System.Xml" />

   </ItemGroup>

   <ItemGroup>

@@ -105,11 +99,11 @@
     </BootstrapperPackage>

   </ItemGroup>

   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-       Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 

+       Other similar extension points exist, see Microsoft.Common.targets.

+  <Target Name="BeforeBuild">

+  </Target>

+  <Target Name="AfterBuild">

+  </Target>

   -->

 </Project>
\ No newline at end of file
diff --git a/src/ProtocolBuffers.Test/CompatTests/CompatibilityTests.cs b/src/ProtocolBuffers.Test/CompatTests/CompatibilityTests.cs
index 0306c41..b54900b 100644
--- a/src/ProtocolBuffers.Test/CompatTests/CompatibilityTests.cs
+++ b/src/ProtocolBuffers.Test/CompatTests/CompatibilityTests.cs
@@ -71,5 +71,117 @@
             Assert.AreEqual(TestResources.google_message2, copy.ToByteArray());

         }

 

+        #region Test message builders

+

+        private static TestAllTypes.Builder AddAllTypes(TestAllTypes.Builder builder)

+        {

+            return builder.SetOptionalInt32(1001)

+                .SetOptionalInt64(1001)

+                .SetOptionalUint32(1001)

+                .SetOptionalUint64(1001)

+                .SetOptionalSint32(-1001)

+                .SetOptionalSint64(-1001)

+                .SetOptionalFixed32(1001)

+                .SetOptionalFixed64(1001)

+                .SetOptionalSfixed32(-1001)

+                .SetOptionalSfixed64(-1001)

+                .SetOptionalFloat(1001.1001f)

+                .SetOptionalDouble(1001.1001)

+                .SetOptionalBool(true)

+                .SetOptionalString("this is a string value")

+                .SetOptionalBytes(ByteString.CopyFromUtf8("this is an array of bytes"))

+                .SetOptionalGroup(new TestAllTypes.Types.OptionalGroup.Builder().SetA(1001))

+                .SetOptionalNestedMessage(new TestAllTypes.Types.NestedMessage.Builder().SetBb(1001))

+                .SetOptionalNestedEnum(TestAllTypes.Types.NestedEnum.FOO)

+            ;

+        }

+

+        private static TestAllTypes.Builder AddRepeatedTypes(TestAllTypes.Builder builder, int size)

+        {

+            //repeated values

+            for (int i = 0; i < size; i++)

+                builder.AddRepeatedInt32(1001 + i)

+                .AddRepeatedInt64(1001)

+                .AddRepeatedUint32(1001)

+                .AddRepeatedUint64(1001)

+                .AddRepeatedSint32(-1001)

+                .AddRepeatedSint64(-1001)

+                .AddRepeatedFixed32(1001)

+                .AddRepeatedFixed64(1001)

+                .AddRepeatedSfixed32(-1001)

+                .AddRepeatedSfixed64(-1001)

+                .AddRepeatedFloat(1001.1001f)

+                .AddRepeatedDouble(1001.1001)

+                .AddRepeatedBool(true)

+                .AddRepeatedString("this is a string value")

+                .AddRepeatedBytes(ByteString.CopyFromUtf8("this is an array of bytes"))

+                .AddRepeatedGroup(new TestAllTypes.Types.RepeatedGroup.Builder().SetA(1001))

+                .AddRepeatedNestedMessage(new TestAllTypes.Types.NestedMessage.Builder().SetBb(1001))

+                .AddRepeatedNestedEnum(TestAllTypes.Types.NestedEnum.FOO)

+            ;

+            return builder;

+        }

+

+        private static TestPackedTypes.Builder AddPackedTypes(TestPackedTypes.Builder builder, int size)

+        {

+            for(int i=0; i < size; i++ )

+                builder.AddPackedInt32(1001)

+                .AddPackedInt64(1001)

+                .AddPackedUint32(1001)

+                .AddPackedUint64(1001)

+                .AddPackedSint32(-1001)

+                .AddPackedSint64(-1001)

+                .AddPackedFixed32(1001)

+                .AddPackedFixed64(1001)

+                .AddPackedSfixed32(-1001)

+                .AddPackedSfixed64(-1001)

+                .AddPackedFloat(1001.1001f)

+                .AddPackedDouble(1001.1001)

+                .AddPackedBool(true)

+                .AddPackedEnum(ForeignEnum.FOREIGN_FOO)

+            ;

+            return builder;

+        }

+

+        #endregion

+

+        [Test]

+        public void TestRoundTripAllTypes()

+        {

+            TestAllTypes msg = AddAllTypes(new TestAllTypes.Builder()).Build();

+            object content = SerializeMessage<TestAllTypes, TestAllTypes.Builder>(msg);

+

+            TestAllTypes copy = DeerializeMessage<TestAllTypes, TestAllTypes.Builder>(content, TestAllTypes.CreateBuilder(), ExtensionRegistry.Empty).Build();

+

+            Assert.AreEqual(msg, copy);

+            AssertOutputEquals(content, SerializeMessage<TestAllTypes, TestAllTypes.Builder>(copy));

+            Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray());

+        }

+

+        [Test]

+        public void TestRoundTripRepeatedTypes()

+        {

+            TestAllTypes msg = AddRepeatedTypes(new TestAllTypes.Builder(), 5).Build();

+            object content = SerializeMessage<TestAllTypes, TestAllTypes.Builder>(msg);

+

+            TestAllTypes copy = DeerializeMessage<TestAllTypes, TestAllTypes.Builder>(content, TestAllTypes.CreateBuilder(), ExtensionRegistry.Empty).Build();

+

+            Assert.AreEqual(msg, copy);

+            AssertOutputEquals(content, SerializeMessage<TestAllTypes, TestAllTypes.Builder>(copy));

+            Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray());

+        }

+

+        [Test]

+        public void TestRoundTripPackedTypes()

+        {

+            TestPackedTypes msg = AddPackedTypes(new TestPackedTypes.Builder(), 5).Build();

+            object content = SerializeMessage<TestPackedTypes, TestPackedTypes.Builder>(msg);

+

+            TestPackedTypes copy = DeerializeMessage<TestPackedTypes, TestPackedTypes.Builder>(content, TestPackedTypes.CreateBuilder(), ExtensionRegistry.Empty).Build();

+

+            Assert.AreEqual(msg, copy);

+            AssertOutputEquals(content, SerializeMessage<TestPackedTypes, TestPackedTypes.Builder>(copy));

+            Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray());

+        }

     }

 }

diff --git a/src/ProtocolBuffers.Test/CompatTests/JsonCompatibilityTests.cs b/src/ProtocolBuffers.Test/CompatTests/JsonCompatibilityTests.cs
index 30a0839..23fa263 100644
--- a/src/ProtocolBuffers.Test/CompatTests/JsonCompatibilityTests.cs
+++ b/src/ProtocolBuffers.Test/CompatTests/JsonCompatibilityTests.cs
@@ -11,7 +11,7 @@
         protected override object SerializeMessage<TMessage, TBuilder>(TMessage message)

         {

             StringWriter sw = new StringWriter();

-            new JsonFormatWriter(sw)

+            JsonFormatWriter.CreateInstance(sw)

                 .Formatted()

                 .WriteMessage(message);

             return sw.ToString();

@@ -19,7 +19,7 @@
 

         protected override TBuilder DeerializeMessage<TMessage, TBuilder>(object message, TBuilder builder, ExtensionRegistry registry)

         {

-            new JsonFormatReader((string)message).Merge(builder);

+            JsonFormatReader.CreateInstance((string)message).Merge(builder);

             return builder;

         }

     }

diff --git a/src/ProtocolBuffers.Test/CompatTests/XmlCompatibilityTests.cs b/src/ProtocolBuffers.Test/CompatTests/XmlCompatibilityTests.cs
index e204200..14616b7 100644
--- a/src/ProtocolBuffers.Test/CompatTests/XmlCompatibilityTests.cs
+++ b/src/ProtocolBuffers.Test/CompatTests/XmlCompatibilityTests.cs
@@ -10,14 +10,14 @@
         protected override object SerializeMessage<TMessage, TBuilder>(TMessage message)

         {

             StringWriter text = new StringWriter();

-            XmlFormatWriter writer = new XmlFormatWriter(text);

+            XmlFormatWriter writer = XmlFormatWriter.CreateInstance(text);

             writer.WriteMessage("root", message);

             return text.ToString();

         }

 

         protected override TBuilder DeerializeMessage<TMessage, TBuilder>(object message, TBuilder builder, ExtensionRegistry registry)

         {

-            XmlFormatReader reader = new XmlFormatReader((string)message);

+            XmlFormatReader reader = XmlFormatReader.CreateInstance((string)message);

             return reader.Merge("root", builder, registry);

         }

     }

diff --git a/src/ProtocolBuffers.Test/TestWriterFormatJson.cs b/src/ProtocolBuffers.Test/TestWriterFormatJson.cs
index 1c95d84..88c059d 100644
--- a/src/ProtocolBuffers.Test/TestWriterFormatJson.cs
+++ b/src/ProtocolBuffers.Test/TestWriterFormatJson.cs
@@ -14,7 +14,7 @@
         protected void FormatterAssert<TMessage>(TMessage message, params string[] expecting) where TMessage : IMessageLite

         {

             StringWriter sw = new StringWriter();

-            new JsonFormatWriter(sw).WriteMessage(message);

+            JsonFormatWriter.CreateInstance(sw).WriteMessage(message);

             

             Content = sw.ToString();

 

@@ -22,7 +22,7 @@
             UnitTestXmlSerializerTestProtoFile.RegisterAllExtensions(registry);

 

             IMessageLite copy = 

-                new JsonFormatReader(Content)

+                JsonFormatReader.CreateInstance(Content)

                 .Merge(message.WeakCreateBuilderForType(), registry).WeakBuild();

 

             Assert.AreEqual(typeof(TMessage), copy.GetType());

@@ -44,12 +44,12 @@
                 .Build();

 

             StringWriter sw = new StringWriter();

-            new JsonFormatWriter(sw).Formatted()

+            JsonFormatWriter.CreateInstance(sw).Formatted()

                 .WriteMessage(message);

 

             string json = sw.ToString();

 

-            TestXmlMessage copy = new JsonFormatReader(json)

+            TestXmlMessage copy = JsonFormatReader.CreateInstance(json)

                 .Merge(TestXmlMessage.CreateBuilder()).Build();

             Assert.AreEqual(message, copy);

         }

@@ -240,11 +240,11 @@
                 .ClearExtension(UnitTestXmlSerializerTestProtoFile.ExtensionEnum)

                 .Build();

 

-            JsonFormatWriter writer = new JsonFormatWriter();

+            JsonFormatWriter writer = JsonFormatWriter.CreateInstance();

             writer.WriteMessage(original);

             Content = writer.ToString();

 

-            IMessageLite copy = new JsonFormatReader(Content)

+            IMessageLite copy = JsonFormatReader.CreateInstance(Content)

                 .Merge(message.CreateBuilderForType()).Build();

 

             Assert.AreNotEqual(original, message);

@@ -255,8 +255,8 @@
         public void TestMergeFields()

         {

             TestXmlMessage.Builder builder = TestXmlMessage.CreateBuilder();

-            builder.MergeFrom(new JsonFormatReader("\"valid\": true"));

-            builder.MergeFrom(new JsonFormatReader("\"text\": \"text\", \"number\": \"411\""));

+            builder.MergeFrom(JsonFormatReader.CreateInstance("\"valid\": true"));

+            builder.MergeFrom(JsonFormatReader.CreateInstance("\"text\": \"text\", \"number\": \"411\""));

             Assert.AreEqual(true, builder.Valid);

             Assert.AreEqual("text", builder.Text);

             Assert.AreEqual(411, builder.Number);

@@ -264,7 +264,7 @@
         [Test]

         public void TestMessageArray()

         {

-            JsonFormatWriter writer = new JsonFormatWriter().Formatted();

+            JsonFormatWriter writer = JsonFormatWriter.CreateInstance().Formatted();

             using (writer.StartArray())

             {

                 writer.WriteMessage(TestXmlMessage.CreateBuilder().SetNumber(1).AddTextlines("a").Build());

@@ -272,7 +272,7 @@
                 writer.WriteMessage(TestXmlMessage.CreateBuilder().SetNumber(3).AddTextlines("c").Build());

             }

             string json = writer.ToString();

-            JsonFormatReader reader = new JsonFormatReader(json);

+            JsonFormatReader reader = JsonFormatReader.CreateInstance(json);

             

             TestXmlMessage.Builder builder = TestXmlMessage.CreateBuilder();

             int ordinal = 0;

@@ -288,7 +288,7 @@
         [Test]

         public void TestNestedMessageArray()

         {

-            JsonFormatWriter writer = new JsonFormatWriter();

+            JsonFormatWriter writer = JsonFormatWriter.CreateInstance();

             using (writer.StartArray())

             {

                 using (writer.StartArray())

@@ -300,7 +300,7 @@
                     writer.WriteMessage(TestXmlMessage.CreateBuilder().SetNumber(3).AddTextlines("c").Build());

             }

             string json = writer.ToString();

-            JsonFormatReader reader = new JsonFormatReader(json);

+            JsonFormatReader reader = JsonFormatReader.CreateInstance(json);

 

             TestXmlMessage.Builder builder = TestXmlMessage.CreateBuilder();

             int ordinal = 0;

@@ -317,25 +317,25 @@
         [Test, ExpectedException(typeof(FormatException))]

         public void FailWithEmptyText()

         {

-            new JsonFormatReader("")

+            JsonFormatReader.CreateInstance("")

                 .Merge(TestXmlMessage.CreateBuilder());

         }

         [Test, ExpectedException(typeof(FormatException))]

         public void FailWithUnexpectedValue()

         {

-            new JsonFormatReader("{{}}")

+            JsonFormatReader.CreateInstance("{{}}")

                 .Merge(TestXmlMessage.CreateBuilder());

         }

         [Test, ExpectedException(typeof(FormatException))]

         public void FailWithUnQuotedName()

         {

-            new JsonFormatReader("{name:{}}")

+            JsonFormatReader.CreateInstance("{name:{}}")

                 .Merge(TestXmlMessage.CreateBuilder());

         }

         [Test, ExpectedException(typeof(FormatException))]

         public void FailWithUnexpectedType()

         {

-            new JsonFormatReader("{\"valid\":{}}")

+            JsonFormatReader.CreateInstance("{\"valid\":{}}")

                 .Merge(TestXmlMessage.CreateBuilder());

         }

     }

diff --git a/src/ProtocolBuffers.Test/TestWriterFormatXml.cs b/src/ProtocolBuffers.Test/TestWriterFormatXml.cs
index a2def5e..2ddf39e 100644
--- a/src/ProtocolBuffers.Test/TestWriterFormatXml.cs
+++ b/src/ProtocolBuffers.Test/TestWriterFormatXml.cs
@@ -23,12 +23,12 @@
 

             //When we call message.WriteTo, we are responsible for the root element

             xw.WriteStartElement("root");

-            message.WriteTo(new XmlFormatWriter(xw));

+            message.WriteTo(XmlFormatWriter.CreateInstance(xw));

             xw.WriteEndElement();

             xw.Flush();

 

             string xml = sw.ToString();

-            XmlFormatReader rdr = new XmlFormatReader(xml);

+            XmlFormatReader rdr = XmlFormatReader.CreateInstance(xml);

             TestXmlChild copy = rdr.Merge(TestXmlChild.CreateBuilder()).Build();

             Assert.AreEqual(message, copy);

         }

@@ -42,10 +42,10 @@
 

             //Allow the writer to write the root element

             StringWriter sw = new StringWriter();

-            new XmlFormatWriter(sw).WriteMessage("root", message);

+            XmlFormatWriter.CreateInstance(sw).WriteMessage("root", message);

 

             string xml = sw.ToString();

-            XmlFormatReader rdr = new XmlFormatReader(xml);

+            XmlFormatReader rdr = XmlFormatReader.CreateInstance(xml);

             TestXmlChild copy = rdr.Merge(TestXmlChild.CreateBuilder()).Build();

             Assert.AreEqual(message, copy);

         }

@@ -57,10 +57,10 @@
                 .Build();

 

             StringWriter sw = new StringWriter();

-            new XmlFormatWriter(sw).WriteMessage("root", message);

+            XmlFormatWriter.CreateInstance(sw).WriteMessage("root", message);

 

             string xml = sw.ToString();

-            XmlFormatReader rdr = new XmlFormatReader(xml);

+            XmlFormatReader rdr = XmlFormatReader.CreateInstance(xml);

             TestXmlMessage copy = rdr.Merge(TestXmlMessage.CreateBuilder()).Build();

             Assert.AreEqual(message, copy);

         }

@@ -72,10 +72,10 @@
                 .Build();

 

             StringWriter sw = new StringWriter();

-            new XmlFormatWriter(sw).WriteMessage("root", message);

+            XmlFormatWriter.CreateInstance(sw).WriteMessage("root", message);

 

             string xml = sw.ToString();

-            XmlFormatReader rdr = new XmlFormatReader(xml);

+            XmlFormatReader rdr = XmlFormatReader.CreateInstance(xml);

             TestXmlMessage copy = rdr.Merge(TestXmlMessage.CreateBuilder()).Build();

             Assert.AreEqual(message, copy);

         }

@@ -87,10 +87,10 @@
                 .Build();

 

             StringWriter sw = new StringWriter();

-            new XmlFormatWriter(sw).WriteMessage("root", message);

+            XmlFormatWriter.CreateInstance(sw).WriteMessage("root", message);

 

             string xml = sw.ToString();

-            XmlFormatReader rdr = new XmlFormatReader(xml);

+            XmlFormatReader rdr = XmlFormatReader.CreateInstance(xml);

             TestXmlMessage copy = rdr.Merge(TestXmlMessage.CreateBuilder()).Build();

             Assert.AreEqual(message, copy);

         }

@@ -113,11 +113,11 @@
                 .Build();

 

             StringWriter sw = new StringWriter();

-            new XmlFormatWriter(sw).WriteMessage("root", message);

+            XmlFormatWriter.CreateInstance(sw).WriteMessage("root", message);

 

             string xml = sw.ToString();

 

-            XmlFormatReader rdr = new XmlFormatReader(xml);

+            XmlFormatReader rdr = XmlFormatReader.CreateInstance(xml);

             TestXmlMessage copy = rdr.Merge(TestXmlMessage.CreateBuilder()).Build();

             Assert.AreEqual(message, copy);

         }

@@ -140,14 +140,13 @@
                 .Build();

 

             StringWriter sw = new StringWriter();

-            new XmlFormatWriter(sw) 

-            {

-                Options = XmlWriterOptions.OutputNestedArrays | XmlWriterOptions.OutputEnumValues

-            }.WriteMessage("root", message);

+            XmlFormatWriter.CreateInstance(sw)

+                .SetOptions(XmlWriterOptions.OutputNestedArrays | XmlWriterOptions.OutputEnumValues)

+                .WriteMessage("root", message);

 

             string xml = sw.ToString();

 

-            XmlFormatReader rdr = new XmlFormatReader(xml);

+            XmlFormatReader rdr = XmlFormatReader.CreateInstance(xml);

             rdr.Options = XmlReaderOptions.ReadNestedArrays;

             TestXmlMessage copy = rdr.Merge(TestXmlMessage.CreateBuilder()).Build();

             Assert.AreEqual(message, copy);

@@ -174,10 +173,9 @@
             Assert.AreEqual(0, message.AllFields.Count);

 

             StringWriter sw = new StringWriter();

-            new XmlFormatWriter(sw)

-            {

-                Options = XmlWriterOptions.OutputNestedArrays | XmlWriterOptions.OutputEnumValues

-            }.WriteMessage("root", message);

+            XmlFormatWriter.CreateInstance(sw)

+                .SetOptions(XmlWriterOptions.OutputNestedArrays | XmlWriterOptions.OutputEnumValues)

+                .WriteMessage("root", message);

 

             string xml = sw.ToString();

 

@@ -191,7 +189,7 @@
                     );

             }

 

-            XmlFormatReader rdr = new XmlFormatReader(xml);

+            XmlFormatReader rdr = XmlFormatReader.CreateInstance(xml);

             rdr.Options = XmlReaderOptions.ReadNestedArrays;

             TestXmlMessage copy = rdr.Merge(TestXmlMessage.CreateBuilder()).Build();

             Assert.AreEqual(TestXmlMessage.DefaultInstance, copy);

@@ -203,11 +201,11 @@
                 .SetText("<text>").Build();

 

             StringWriter sw = new StringWriter();

-            new XmlFormatWriter(sw).WriteMessage("root", message);

+            XmlFormatWriter.CreateInstance(sw).WriteMessage("root", message);

 

             string xml = sw.ToString();

 

-            XmlFormatReader rdr = new XmlFormatReader(xml);

+            XmlFormatReader rdr = XmlFormatReader.CreateInstance(xml);

             TestXmlMessage copy = rdr.Merge(TestXmlMessage.CreateBuilder()).Build();

             Assert.AreEqual(message, copy);

         }

@@ -218,11 +216,11 @@
                 .SetText(" \t <- leading space and trailing -> \r\n\t").Build();

 

             StringWriter sw = new StringWriter();

-            new XmlFormatWriter(sw).WriteMessage("root", message);

+            XmlFormatWriter.CreateInstance(sw).WriteMessage("root", message);

 

             string xml = sw.ToString();

 

-            XmlFormatReader rdr = new XmlFormatReader(xml);

+            XmlFormatReader rdr = XmlFormatReader.CreateInstance(xml);

             TestXmlMessage copy = rdr.Merge(TestXmlMessage.CreateBuilder()).Build();

             Assert.AreEqual(message, copy);

         }

@@ -234,14 +232,14 @@
                 .Build();

 

             StringWriter sw = new StringWriter();

-            new XmlFormatWriter(sw).WriteMessage("root", message);

+            XmlFormatWriter.CreateInstance(sw).WriteMessage("root", message);

 

             string xml = sw.ToString();

 

             ExtensionRegistry registry = ExtensionRegistry.CreateInstance();

             UnitTestXmlSerializerTestProtoFile.RegisterAllExtensions(registry);

 

-            XmlFormatReader rdr = new XmlFormatReader(xml);

+            XmlFormatReader rdr = XmlFormatReader.CreateInstance(xml);

             TestXmlMessage copy = rdr.Merge(TestXmlMessage.CreateBuilder(), registry).Build();

             Assert.AreEqual(message, copy);

         }

@@ -253,14 +251,14 @@
                 new TestXmlExtension.Builder().SetNumber(42).Build()).Build();

 

             StringWriter sw = new StringWriter();

-            new XmlFormatWriter(sw).WriteMessage("root", message);

+            XmlFormatWriter.CreateInstance(sw).WriteMessage("root", message);

 

             string xml = sw.ToString();

 

             ExtensionRegistry registry = ExtensionRegistry.CreateInstance();

             UnitTestXmlSerializerTestProtoFile.RegisterAllExtensions(registry);

 

-            XmlFormatReader rdr = new XmlFormatReader(xml);

+            XmlFormatReader rdr = XmlFormatReader.CreateInstance(xml);

             TestXmlMessage copy = rdr.Merge(TestXmlMessage.CreateBuilder(), registry).Build();

             Assert.AreEqual(message, copy);

         }

@@ -274,14 +272,14 @@
                 .Build();

 

             StringWriter sw = new StringWriter();

-            new XmlFormatWriter(sw).WriteMessage("root", message);

+            XmlFormatWriter.CreateInstance(sw).WriteMessage("root", message);

 

             string xml = sw.ToString();

 

             ExtensionRegistry registry = ExtensionRegistry.CreateInstance();

             UnitTestXmlSerializerTestProtoFile.RegisterAllExtensions(registry);

 

-            XmlFormatReader rdr = new XmlFormatReader(xml);

+            XmlFormatReader rdr = XmlFormatReader.CreateInstance(xml);

             TestXmlMessage copy = rdr.Merge(TestXmlMessage.CreateBuilder(), registry).Build();

             Assert.AreEqual(message, copy);

         }

@@ -293,14 +291,14 @@
                 .Build();

 

             StringWriter sw = new StringWriter();

-            new XmlFormatWriter(sw).WriteMessage("root", message);

+            XmlFormatWriter.CreateInstance(sw).WriteMessage("root", message);

 

             string xml = sw.ToString();

 

             ExtensionRegistry registry = ExtensionRegistry.CreateInstance();

             UnitTestXmlSerializerTestProtoFile.RegisterAllExtensions(registry);

 

-            XmlFormatReader rdr = new XmlFormatReader(xml);

+            XmlFormatReader rdr = XmlFormatReader.CreateInstance(xml);

             TestXmlMessage copy = rdr.Merge(TestXmlMessage.CreateBuilder(), registry).Build();

             Assert.AreEqual(message, copy);

         }

diff --git a/src/ProtocolBuffers/Serialization/DictionaryReader.cs b/src/ProtocolBuffers/Serialization/DictionaryReader.cs
index f8ef1ed..d6e5c18 100644
--- a/src/ProtocolBuffers/Serialization/DictionaryReader.cs
+++ b/src/ProtocolBuffers/Serialization/DictionaryReader.cs
@@ -64,7 +64,7 @@
                 try 

                 {

                     if (obj is IConvertible)

-                        value = (T)Convert.ChangeType(obj, typeof(T));

+                        value = (T)Convert.ChangeType(obj, typeof(T), System.Globalization.CultureInfo.InvariantCulture);

                     else

                         value = (T)obj;

                 }

@@ -186,8 +186,17 @@
             object[] array = null;

             if (GetValue(ref array))

             {

-                foreach (T item in array)

-                    items.Add(item);

+                if (typeof(T) == typeof(ByteString))

+                {

+                    ICollection<ByteString> output = (ICollection<ByteString>)items;

+                    foreach (byte[] item in array)

+                        output.Add(ByteString.CopyFrom(item));

+                }

+                else

+                {

+                    foreach (T item in array)

+                        items.Add(item);

+                }

                 return true;

             }

             return false;

diff --git a/src/ProtocolBuffers/Serialization/JsonFormatReader.cs b/src/ProtocolBuffers/Serialization/JsonFormatReader.cs
index e9df913..2808ff5 100644
--- a/src/ProtocolBuffers/Serialization/JsonFormatReader.cs
+++ b/src/ProtocolBuffers/Serialization/JsonFormatReader.cs
@@ -10,7 +10,7 @@
     /// </summary>

     public class JsonFormatReader : AbstractTextReader

     {

-        private readonly JsonTextCursor _input;

+        private readonly JsonCursor _input;

         private readonly Stack<int> _stopChar;

 

         enum ReaderState { Start, BeginValue, EndValue, BeginObject, BeginArray }

@@ -18,27 +18,43 @@
         ReaderState _state;

 

         /// <summary>

-        /// Constructs a JsonFormatReader to parse Json into a message

+        /// Constructs a JsonFormatReader to parse Json into a message, this method does not use text encoding, all bytes MUST

+        /// represent ASCII character values.

         /// </summary>

-        public JsonFormatReader(string jsonText)

-        {

-            _input = new JsonTextCursor(jsonText.ToCharArray());

-            _stopChar = new Stack<int>();

-            _stopChar.Push(-1);

-            _state = ReaderState.Start;

-        }

+        public static JsonFormatReader CreateInstance(Stream stream) { return new JsonFormatReader(JsonCursor.CreateInstance(stream)); }

+        /// <summary>

+        /// Constructs a JsonFormatReader to parse Json into a message, this method does not use text encoding, all bytes MUST

+        /// represent ASCII character values.

+        /// </summary>

+        public static JsonFormatReader CreateInstance(byte[] bytes) { return new JsonFormatReader(JsonCursor.CreateInstance(bytes)); }

         /// <summary>

         /// Constructs a JsonFormatReader to parse Json into a message

         /// </summary>

-        public JsonFormatReader(TextReader input)

+        public static JsonFormatReader CreateInstance(string jsonText) { return new JsonFormatReader(JsonCursor.CreateInstance(jsonText)); }

+        /// <summary>

+        /// Constructs a JsonFormatReader to parse Json into a message

+        /// </summary>

+        public static JsonFormatReader CreateInstance(TextReader input) { return new JsonFormatReader(JsonCursor.CreateInstance(input)); }

+

+        /// <summary>

+        /// Constructs a JsonFormatReader to parse Json into a message

+        /// </summary>

+        internal JsonFormatReader(JsonCursor input)

         {

-            _input = new JsonTextCursor(input);

+            _input = input;

             _stopChar = new Stack<int>();

             _stopChar.Push(-1);

             _state = ReaderState.Start;

         }

 

         /// <summary>

+        /// Constructs a JsonFormatReader to parse Json into a message

+        /// </summary>

+        protected JsonFormatReader(TextReader input)

+            : this(JsonCursor.CreateInstance(input))

+        { }

+

+        /// <summary>

         /// Returns true if the reader is currently on an array element

         /// </summary>

         public bool IsArrayMessage { get { return _input.NextChar == '['; } }

@@ -115,18 +131,18 @@
         protected override bool ReadAsText(ref string value, Type typeInfo)

         {

             object temp;

-            JsonTextCursor.JsType type = _input.ReadVariant(out temp);

+            JsonCursor.JsType type = _input.ReadVariant(out temp);

             _state = ReaderState.EndValue;

 

-            _input.Assert(type != JsonTextCursor.JsType.Array && type != JsonTextCursor.JsType.Object, "Encountered {0} while expecting {1}", type, typeInfo);

-            if (type == JsonTextCursor.JsType.Null)

+            _input.Assert(type != JsonCursor.JsType.Array && type != JsonCursor.JsType.Object, "Encountered {0} while expecting {1}", type, typeInfo);

+            if (type == JsonCursor.JsType.Null)

                 return false;

-            if (type == JsonTextCursor.JsType.True) value = "1";

-            else if (type == JsonTextCursor.JsType.False) value = "0";

+            if (type == JsonCursor.JsType.True) value = "1";

+            else if (type == JsonCursor.JsType.False) value = "0";

             else value = temp as string;

 

             //exponent representation of integer number:

-            if (value != null && type == JsonTextCursor.JsType.Number &&

+            if (value != null && type == JsonCursor.JsType.Number &&

                 (typeInfo != typeof(double) && typeInfo != typeof(float)) &&

                 value.IndexOf("e", StringComparison.OrdinalIgnoreCase) > 0)

             {

diff --git a/src/ProtocolBuffers/Serialization/JsonFormatWriter.cs b/src/ProtocolBuffers/Serialization/JsonFormatWriter.cs
index 0baf6ca..b205752 100644
--- a/src/ProtocolBuffers/Serialization/JsonFormatWriter.cs
+++ b/src/ProtocolBuffers/Serialization/JsonFormatWriter.cs
@@ -1,6 +1,7 @@
 using System;

 using System.Collections.Generic;

 using System.IO;

+using System.Text;

 using Google.ProtocolBuffers.Descriptors;

 

 namespace Google.ProtocolBuffers.Serialization

@@ -10,81 +11,178 @@
     /// you may also use the XmlFormatWriter with an XmlWriter created by the

     /// <see cref="System.Runtime.Serialization.Json.JsonReaderWriterFactory">JsonReaderWriterFactory</see>.

     /// </summary>

-    public class JsonFormatWriter : AbstractTextWriter

+    public abstract class JsonFormatWriter : AbstractTextWriter

     {

-        private readonly char[] _buffer;

-        private readonly TextWriter _output;

-        private readonly List<int> _counter;

-        private bool _isArray;

-        int _bufferPos;

-        /// <summary>

-        /// Constructs a JsonFormatWriter to output to a new instance of a StringWriter, use

-        /// the ToString() member to extract the final Json on completion.

-        /// </summary>

-        public JsonFormatWriter() : this(new StringWriter()) { }

-        /// <summary>

-        /// Constructs a JsonFormatWriter to output to the given text writer

-        /// </summary>

-        public JsonFormatWriter(TextWriter output)

+        #region buffering implementations

+        private class JsonTextWriter : JsonFormatWriter

         {

-            _buffer = new char[4096];

-            _bufferPos = 0;

-            _output = output;

-            _counter = new List<int>();

-            _counter.Add(0);

-        }

+            private readonly char[] _buffer;

+            private TextWriter _output;

+            int _bufferPos;

 

-

-        private void WriteToOutput(string format, params object[] args)

-        { WriteToOutput(String.Format(format, args)); }

-

-        private void WriteToOutput(string text)

-        { WriteToOutput(text.ToCharArray(), 0, text.Length); }

-

-        private void WriteToOutput(char[] chars, int offset, int len)

-        {

-            if (_bufferPos + len >= _buffer.Length)

-                Flush();

-            if (len < _buffer.Length)

+            public JsonTextWriter(TextWriter output)

             {

-                if (len <= 12)

+                _buffer = new char[4096];

+                _bufferPos = 0;

+                _output = output;

+                _counter.Add(0);

+            }

+

+            /// <summary>

+            /// Returns the output of TextWriter.ToString() where TextWriter is the ctor argument.

+            /// </summary>

+            public override string ToString()

+            {

+                Flush();

+

+                if (_output != null)

+                    return _output.ToString();

+

+                return new String(_buffer, 0, _bufferPos);

+            }

+

+            protected override void WriteToOutput(char[] chars, int offset, int len)

+            {

+                if (_bufferPos + len >= _buffer.Length)

                 {

-                    int stop = offset + len;

-                    for (int i = offset; i < stop; i++)

-                        _buffer[_bufferPos++] = chars[i];

+                    if (_output == null)

+                        _output = new StringWriter(new System.Text.StringBuilder(_buffer.Length * 2 + len));

+                    Flush();

+                }

+

+                if (len < _buffer.Length)

+                {

+                    if (len <= 12)

+                    {

+                        int stop = offset + len;

+                        for (int i = offset; i < stop; i++)

+                            _buffer[_bufferPos++] = chars[i];

+                    }

+                    else

+                    {

+                        Buffer.BlockCopy(chars, offset << 1, _buffer, _bufferPos << 1, len << 1);

+                        _bufferPos += len;

+                    }

+                }

+                else

+                    _output.Write(chars, offset, len);

+            }

+

+            protected override void WriteToOutput(char ch)

+            {

+                if (_bufferPos >= _buffer.Length)

+                    Flush();

+                _buffer[_bufferPos++] = ch;

+            }

+

+            public override void Flush()

+            {

+                if (_bufferPos > 0 && _output != null)

+                {

+                    _output.Write(_buffer, 0, _bufferPos);

+                    _bufferPos = 0;

+                }

+                base.Flush();

+            }

+        }

+        private class JsonStreamWriter : JsonFormatWriter

+        {

+#if SILVERLIGHT2 || COMPACT_FRAMEWORK_35

+            static readonly Encoding Encoding = Encoding.UTF8;

+#else

+            static readonly Encoding Encoding = Encoding.ASCII;

+#endif

+            private readonly byte[] _buffer;

+            private Stream _output;

+            int _bufferPos;

+

+            public JsonStreamWriter(Stream output)

+            {

+                _buffer = new byte[8192];

+                _bufferPos = 0;

+                _output = output;

+                _counter.Add(0);

+            }

+

+            protected override void WriteToOutput(char[] chars, int offset, int len)

+            {

+                if (_bufferPos + len >= _buffer.Length)

+                    Flush();

+

+                if (len < _buffer.Length)

+                {

+                    if (len <= 12)

+                    {

+                        int stop = offset + len;

+                        for (int i = offset; i < stop; i++)

+                            _buffer[_bufferPos++] = (byte)chars[i];

+                    }

+                    else

+                    {

+                        _bufferPos += Encoding.GetBytes(chars, offset, len, _buffer, _bufferPos);

+                    }

                 }

                 else

                 {

-                    Buffer.BlockCopy(chars, offset << 1, _buffer, _bufferPos << 1, len << 1);

-                    _bufferPos += len;

+                    byte[] temp = Encoding.GetBytes(chars, offset, len);

+                    _output.Write(temp, 0, temp.Length);

                 }

             }

-            else

-                _output.Write(chars, offset, len);

-        }

 

-        private void WriteToOutput(char ch)

-        {

-            if (_bufferPos >= _buffer.Length)

-                Flush();

-            _buffer[_bufferPos++] = ch;

-        }

-

-        public override void Flush()

-        {

-            if (_bufferPos > 0)

+            protected override void WriteToOutput(char ch)

             {

-                _output.Write(_buffer, 0, _bufferPos);

-                _bufferPos = 0;

+                if (_bufferPos >= _buffer.Length)

+                    Flush();

+                _buffer[_bufferPos++] = (byte)ch;

             }

-            base.Flush();

+

+            public override void Flush()

+            {

+                if (_bufferPos > 0 && _output != null)

+                {

+                    _output.Write(_buffer, 0, _bufferPos);

+                    _bufferPos = 0;

+                }

+                base.Flush();

+            }

+        }

+        #endregion

+

+        private readonly List<int> _counter;

+        private bool _isArray;

+        /// <summary>

+        /// Constructs a JsonFormatWriter, use the ToString() member to extract the final Json on completion.

+        /// </summary>

+        protected JsonFormatWriter()

+        {

+            _counter = new List<int>();

         }

 

         /// <summary>

-        /// Returns the output of TextWriter.ToString() where TextWriter is the ctor argument.

+        /// Constructs a JsonFormatWriter, use ToString() to extract the final output

         /// </summary>

-        public override string ToString()

-        { Flush(); return _output.ToString(); }

+        public static JsonFormatWriter CreateInstance() { return new JsonTextWriter(null); }

+            

+        /// <summary>

+        /// Constructs a JsonFormatWriter to output to the given text writer

+        /// </summary>

+        public static JsonFormatWriter CreateInstance(TextWriter output) { return new JsonTextWriter(output); }

+

+        /// <summary>

+        /// Constructs a JsonFormatWriter to output to the given stream

+        /// </summary>

+        public static JsonFormatWriter CreateInstance(Stream output) { return new JsonStreamWriter(output); }

+

+        /// <summary> Write to the output stream </summary>

+        protected void WriteToOutput(string format, params object[] args)

+        { WriteToOutput(String.Format(format, args)); }

+        /// <summary> Write to the output stream </summary>

+        protected void WriteToOutput(string text)

+        { WriteToOutput(text.ToCharArray(), 0, text.Length); }

+        /// <summary> Write to the output stream </summary>

+        protected abstract void WriteToOutput(char ch);

+        /// <summary> Write to the output stream </summary>

+        protected abstract void WriteToOutput(char[] chars, int offset, int len);

 

         /// <summary> Sets the output formatting to use Environment.NewLine with 4-character indentions </summary>

         public JsonFormatWriter Formatted()

diff --git a/src/ProtocolBuffers/Serialization/JsonTextCursor.cs b/src/ProtocolBuffers/Serialization/JsonTextCursor.cs
index 6a8652c..a0b468f 100644
--- a/src/ProtocolBuffers/Serialization/JsonTextCursor.cs
+++ b/src/ProtocolBuffers/Serialization/JsonTextCursor.cs
@@ -9,52 +9,115 @@
     /// <summary>

     /// JSon Tokenizer used by JsonFormatReader

     /// </summary>

-    class JsonTextCursor

+    abstract class JsonCursor

     {

         public enum JsType { String, Number, Object, Array, True, False, Null }

 

-        private readonly char[] _buffer;

-        private int _bufferPos;

-        private readonly TextReader _input;

+        #region Buffering implementations

+        class JsonStreamCursor : JsonCursor

+        {

+            private readonly byte[] _buffer;

+            private int _bufferPos;

+            private readonly Stream _input;

+

+            public JsonStreamCursor(Stream input)

+            {

+                _input = input;

+                _next = _input.ReadByte();

+            }

+            public JsonStreamCursor(byte[] input)

+            {

+                _input = null;

+                _buffer = input;

+                _next = _buffer[_bufferPos];

+            }

+

+            protected override int Peek()

+            {

+                if (_input != null)

+                    return _next;

+                else if (_bufferPos < _buffer.Length)

+                    return _buffer[_bufferPos];

+                else

+                    return -1;

+            }

+

+            protected override int Read()

+            {

+                if (_input != null)

+                {

+                    int result = _next;

+                    _next = _input.ReadByte();

+                    return result;

+                }

+                else if (_bufferPos < _buffer.Length)

+                    return _buffer[_bufferPos++];

+                else

+                    return -1;

+            }

+        }

+

+        class JsonTextCursor : JsonCursor

+        {

+            private readonly char[] _buffer;

+            private int _bufferPos;

+            private readonly TextReader _input;

+

+            public JsonTextCursor(char[] input)

+            {

+                _input = null;

+                _buffer = input;

+                _bufferPos = 0;

+                _next = Peek();

+            }

+

+            public JsonTextCursor(TextReader input)

+            {

+                _input = input;

+                _next = Peek();

+            }

+

+            protected override int Peek()

+            {

+                if (_input != null)

+                    return _input.Peek();

+                else if (_bufferPos < _buffer.Length)

+                    return _buffer[_bufferPos];

+                else

+                    return -1;

+            }

+

+            protected override int Read()

+            {

+                if (_input != null)

+                    return _input.Read();

+                else if (_bufferPos < _buffer.Length)

+                    return _buffer[_bufferPos++];

+                else

+                    return -1;

+            }

+        }

+        #endregion

+

+        protected int _next;

         private int _lineNo, _linePos;

 

-        public JsonTextCursor(char[] input)

+        public static JsonCursor CreateInstance(byte[] input) { return new JsonStreamCursor(input); }

+        public static JsonCursor CreateInstance(Stream input) { return new JsonStreamCursor(input); }

+        public static JsonCursor CreateInstance(string input) { return new JsonTextCursor(input.ToCharArray()); }

+        public static JsonCursor CreateInstance(TextReader input) { return new JsonTextCursor(input); }

+

+        protected JsonCursor()

         {

-            _input = null;

-            _buffer = input;

-            _bufferPos = 0;

-            _next = Peek();

             _lineNo = 1;

+            _linePos = 0;

         }

+        

+        /// <summary>Returns the next character without actually 'reading' it</summary>

+        protected abstract int Peek();

+        /// <summary>Reads the next character in the input</summary>

+        protected abstract int Read();

 

-        public JsonTextCursor(TextReader input)

-        {

-            _input = input;

-            _next = Peek();

-            _lineNo = 1;

-        }

-

-        private int Peek()

-        {

-            if (_input != null)

-                return _input.Peek();

-            else if (_bufferPos < _buffer.Length)

-                return _buffer[_bufferPos];

-            else

-                return -1;

-        }

-

-        private int Read()

-        {

-            if (_input != null)

-                return _input.Read();

-            else if (_bufferPos < _buffer.Length)

-                return _buffer[_bufferPos++];

-            else

-                return -1;

-        }

-

-        int _next;

         public Char NextChar { get { SkipWhitespace(); return (char)_next; } }

 

         #region Assert(...)

@@ -62,8 +125,8 @@
         private string CharDisplay(int ch)

         {

             return ch == -1 ? "EOF" :

-                                        (ch > 32 && ch < 127) ? String.Format("'{0}'", (char)ch) :

-                                                                                                     String.Format("'\\u{0:x4}'", ch);

+                (ch > 32 && ch < 127) ? String.Format("'{0}'", (char)ch) :

+                String.Format("'\\u{0:x4}'", ch);

         }

         [System.Diagnostics.DebuggerNonUserCode]

         private void Assert(bool cond, char expected)

diff --git a/src/ProtocolBuffers/Serialization/XmlFormatReader.cs b/src/ProtocolBuffers/Serialization/XmlFormatReader.cs
index 671490e..241c554 100644
--- a/src/ProtocolBuffers/Serialization/XmlFormatReader.cs
+++ b/src/ProtocolBuffers/Serialization/XmlFormatReader.cs
@@ -25,33 +25,41 @@
         /// <summary>

         /// Constructs the XmlFormatReader using the stream provided as the xml

         /// </summary>

-        public XmlFormatReader(Stream input) : this(XmlReader.Create(input, DefaultSettings)) { }

+        public static XmlFormatReader CreateInstance(byte[] input) { return new XmlFormatReader(XmlReader.Create(new MemoryStream(input, false), DefaultSettings)); }

+        /// <summary>

+        /// Constructs the XmlFormatReader using the stream provided as the xml

+        /// </summary>

+        public static XmlFormatReader CreateInstance(Stream input) { return new XmlFormatReader(XmlReader.Create(input, DefaultSettings)); }

         /// <summary>

         /// Constructs the XmlFormatReader using the string provided as the xml to be read

         /// </summary>

-        public XmlFormatReader(String input) : this(XmlReader.Create(new StringReader(input))) { }

+        public static XmlFormatReader CreateInstance(String input) { return new XmlFormatReader(XmlReader.Create(new StringReader(input), DefaultSettings)); }

         /// <summary>

         /// Constructs the XmlFormatReader using the xml in the TextReader

         /// </summary>

-        public XmlFormatReader(TextReader input) : this(XmlReader.Create(input)) { }

+        public static XmlFormatReader CreateInstance(TextReader input) { return new XmlFormatReader(XmlReader.Create(input, DefaultSettings)); }

         /// <summary>

         /// Constructs the XmlFormatReader with the XmlReader

         /// </summary>

-        public XmlFormatReader(XmlReader input) : this(input, XmlReaderOptions.None) { }

+        public static XmlFormatReader CreateInstance(XmlReader input) { return new XmlFormatReader(input); }

         /// <summary>

         /// Constructs the XmlFormatReader with the XmlReader and options

         /// </summary>

-        public XmlFormatReader(XmlReader input, XmlReaderOptions options)

+        protected XmlFormatReader(XmlReader input)

         {

             _input = input;

             _rootElementName = DefaultRootElementName;

-            Options = options;

+            Options = XmlReaderOptions.None;

         }

         

         /// <summary>

         /// Gets or sets the options to use when reading the xml

         /// </summary>

         public XmlReaderOptions Options { get; set; }

+        /// <summary>

+        /// Sets the options to use while generating the XML

+        /// </summary>

+        public XmlFormatReader SetOptions(XmlReaderOptions options) { Options = options; return this; }

 

         /// <summary>

         /// Gets or sets the default element name to use when using the Merge&lt;TBuilder>()

@@ -64,7 +72,7 @@
 

         private XmlFormatReader CloneWith(XmlReader rdr)

         {

-            return new XmlFormatReader(rdr, Options);

+            return new XmlFormatReader(rdr).SetOptions(Options);

         }

         private void NextElement()

         {

diff --git a/src/ProtocolBuffers/Serialization/XmlFormatWriter.cs b/src/ProtocolBuffers/Serialization/XmlFormatWriter.cs
index b5dbf5f..2bb4f15 100644
--- a/src/ProtocolBuffers/Serialization/XmlFormatWriter.cs
+++ b/src/ProtocolBuffers/Serialization/XmlFormatWriter.cs
@@ -1,5 +1,6 @@
 using System;

 using System.IO;

+using System.Text;

 using System.Xml;

 using Google.ProtocolBuffers.Descriptors;

 

@@ -17,23 +18,29 @@
         private readonly XmlWriter _output;

         private string _rootElementName;

 

-        static XmlWriterSettings DefaultSettings

+        static XmlWriterSettings DefaultSettings(Encoding encoding)

         {

-            get { return new XmlWriterSettings() {CheckCharacters = false, NewLineHandling = NewLineHandling.Entitize}; }

+            return new XmlWriterSettings() { CheckCharacters = false, NewLineHandling = NewLineHandling.Entitize, Encoding = encoding };

         }

 

         /// <summary>

         /// Constructs the XmlFormatWriter to write to the given TextWriter

         /// </summary>

-        public XmlFormatWriter(TextWriter output) : this(XmlWriter.Create(output, DefaultSettings)) { }

+        public static XmlFormatWriter CreateInstance(TextWriter output) { return new XmlFormatWriter(XmlWriter.Create(output, DefaultSettings(output.Encoding))); }

         /// <summary>

         /// Constructs the XmlFormatWriter to write to the given stream

         /// </summary>

-        public XmlFormatWriter(Stream output) : this(XmlWriter.Create(output, DefaultSettings)) { }

+        public static XmlFormatWriter CreateInstance(Stream output) { return new XmlFormatWriter(XmlWriter.Create(output, DefaultSettings(Encoding.UTF8))); }

+        /// <summary>

+        /// Constructs the XmlFormatWriter to write to the given stream

+        /// </summary>

+        public static XmlFormatWriter CreateInstance(Stream output, Encoding encoding) { return new XmlFormatWriter(XmlWriter.Create(output, DefaultSettings(encoding))); }

         /// <summary>

         /// Constructs the XmlFormatWriter to write to the given XmlWriter

         /// </summary>

-        public XmlFormatWriter(XmlWriter output)

+        public static XmlFormatWriter CreateInstance(XmlWriter output) { return new XmlFormatWriter(output); }

+

+        protected XmlFormatWriter(XmlWriter output)

         {

             _output = output;

             _rootElementName = DefaultRootElementName;

@@ -61,6 +68,10 @@
         /// Gets or sets the options to use while generating the XML

         /// </summary>

         public XmlWriterOptions Options { get; set; }

+        /// <summary>

+        /// Sets the options to use while generating the XML

+        /// </summary>

+        public XmlFormatWriter SetOptions(XmlWriterOptions options) { Options = options; return this; }

 

         private bool TestOption(XmlWriterOptions option) { return (Options & option) != 0; }